[PATCH 2/4] core: Add API to handle "content-changed" signal



Add notify_changed_start() and notify_changed_stop() functions so sources know
when they can emit the signal and when not.

Sources that are able to emit "content-changed" signal must re-implement
notify_changed_start() and notify_changed_stop() functions.

Added a notify_changed() function too that sources can use to send the signal.

Signed-off-by: Juan A. Suarez Romero <jasuarez igalia com>
---
 src/grl-error.h           |    4 ++-
 src/grl-media-source.c    |   83 +++++++++++++++++++++++++++++++++++++++++++++
 src/grl-media-source.h    |   21 +++++++++++-
 src/grl-metadata-source.h |    2 +
 4 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/src/grl-error.h b/src/grl-error.h
index 4f654ab..d76a5fb 100644
--- a/src/grl-error.h
+++ b/src/grl-error.h
@@ -54,6 +54,7 @@
  * @GRL_CORE_ERROR_LOAD_PLUGIN_FAILED: Failed to load plugin
  * @GRL_CORE_ERROR_UNLOAD_PLUGIN_FAILED: Failed to unload plugin
  * @GRL_CORE_ERROR_REGISTER_METADATA_KEY_FAILED: Failed to register metadata key
+ * @GRL_CORE_ERROR_NOTIFY_CHANGED_FAILED: Failed to start changed notifications
  *
  * These constants identify all the available core errors
  */
@@ -73,7 +74,8 @@ typedef enum {
   GRL_CORE_ERROR_UNREGISTER_SOURCE_FAILED,
   GRL_CORE_ERROR_LOAD_PLUGIN_FAILED,
   GRL_CORE_ERROR_UNLOAD_PLUGIN_FAILED,
-  GRL_CORE_ERROR_REGISTER_METADATA_KEY_FAILED
+  GRL_CORE_ERROR_REGISTER_METADATA_KEY_FAILED,
+  GRL_CORE_ERROR_NOTIFY_CHANGED_FAILED
 } GrlCoreError;
 
 #endif /* _GRL_ERROR_H_ */
diff --git a/src/grl-media-source.c b/src/grl-media-source.c
index a334370..ea9ef0a 100644
--- a/src/grl-media-source.c
+++ b/src/grl-media-source.c
@@ -2043,6 +2043,9 @@ grl_media_source_supported_operations (GrlMetadataSource *metadata_source)
   if (media_source_class->test_media_from_uri &&
       media_source_class->media_from_uri)
     caps |= GRL_OP_MEDIA_FROM_URI;
+  if (media_source_class->notify_changed_start &&
+      media_source_class->notify_changed_stop)
+    caps |= GRL_OP_NOTIFY_CHANGED;
 
   return caps;
 }
@@ -2532,3 +2535,83 @@ grl_media_source_get_media_from_uri_sync (GrlMediaSource *source,
 
   return result;
 }
+
+/**
+ * grl_media_source_notify_changed_start:
+ * @source: a media source
+ * @error: a #GError, or @NULL
+ *
+ * Starts emitting ::content-changed signals when @source discovers changes in
+ * the content. This instructs @source to setup the machinery needed to be aware
+ * of changes in the content.
+ *
+ * Returns: @TRUE if initialization has succeed.
+ */
+gboolean
+grl_media_source_notify_changed_start (GrlMediaSource *source,
+                                       GError **error)
+{
+  g_return_val_if_fail (GRL_IS_MEDIA_SOURCE (source), FALSE);
+  g_return_val_if_fail (grl_media_source_supported_operations (GRL_METADATA_SOURCE (source)) &
+                        GRL_OP_NOTIFY_CHANGED, FALSE);
+
+  return GRL_MEDIA_SOURCE_GET_CLASS (source)->notify_changed_start (source,
+                                                                    error);
+}
+
+/**
+ * grl_media_source_notify_changed_stop:
+ * @source: a media source
+ * @error: a #GError, or @NULL
+ *
+ * This will drop emission of ::content-changed signals from @source. When this
+ * is done @source should stop the machinery required for it to track changes in
+ * the content.
+ *
+ * Returns: @TRUE if stop has succeed.
+ */
+gboolean
+grl_media_source_notify_changed_stop (GrlMediaSource *source,
+                                      GError **error)
+{
+  g_return_val_if_fail (GRL_IS_MEDIA_SOURCE (source), FALSE);
+  g_return_val_if_fail (grl_media_source_supported_operations (GRL_METADATA_SOURCE (source)) &
+                        GRL_OP_NOTIFY_CHANGED, FALSE);
+
+  return GRL_MEDIA_SOURCE_GET_CLASS (source)->notify_changed_stop (source,
+                                                                   error);
+}
+
+/**
+ * grl_media_source_notify_changed:
+ * @source: a media source
+ * @media: (allow-none): the media which has changed
+ * @change_type: the type of change
+ * @location_unknown: if change has happpened in @media or any descendant
+ *
+ * Emits "content-changed" signal to notify subscribers that a change ocurred
+ * in @source.
+ *
+ * See GrlMediaSource::content-changed signal.
+ *
+ * <note>
+ *  <para>
+ *    This function is intended to be used only by plugins.
+ *  </para>
+ * </note>
+ */
+void grl_media_source_notify_changed (GrlMediaSource *source,
+                                      GrlMedia *media,
+                                      GrlMediaSourceChangeType change_type,
+                                      gboolean location_unknown)
+{
+  g_return_if_fail (GRL_IS_MEDIA_SOURCE (source));
+  g_return_if_fail (!media || GRL_IS_MEDIA (media));
+
+  g_signal_emit (source,
+                 registry_signals[SIG_CONTENT_CHANGED],
+                 0,
+                 media,
+                 change_type,
+                 location_unknown);
+}
diff --git a/src/grl-media-source.h b/src/grl-media-source.h
index 3df5af5..055d713 100644
--- a/src/grl-media-source.h
+++ b/src/grl-media-source.h
@@ -365,6 +365,8 @@ typedef struct _GrlMediaSourceClass GrlMediaSourceClass;
  * instances from a given URI.
  * @media_from_uri: Creates a #GrlMedia instance representing the media
  * exposed by a certain URI.
+ * @notify_changed_start: start emitting signals about changes in content
+ * @notify_changed_stop: stop emitting signals about changes in content
  *
  * Grilo MediaSource class. Override the vmethods to implement the
  * source functionality.
@@ -395,8 +397,14 @@ struct _GrlMediaSourceClass {
   void (*media_from_uri) (GrlMediaSource *source,
 			  GrlMediaSourceMediaFromUriSpec *mfss);
 
+  gboolean (*notify_changed_start) (GrlMediaSource *source,
+                                    GError **error);
+
+  gboolean (*notify_changed_stop) (GrlMediaSource *source,
+                                   GError **error);
+
   /*< private >*/
-  gpointer _grl_reserved[GRL_PADDING - 1];
+  gpointer _grl_reserved[GRL_PADDING - 3];
 
   /* signals */
   void (*content_changed) (GrlMediaSource *source,
@@ -524,6 +532,17 @@ GrlMedia *grl_media_source_get_media_from_uri_sync (GrlMediaSource *source,
                                                     GrlMetadataResolutionFlags flags,
                                                     GError **error);
 
+gboolean grl_media_source_notify_changed_start (GrlMediaSource *source,
+                                                GError **error);
+
+gboolean grl_media_source_notify_changed_stop (GrlMediaSource *source,
+                                               GError **error);
+
+void grl_media_source_notify_changed (GrlMediaSource *source,
+                                      GrlMedia *media,
+                                      GrlMediaSourceChangeType change_type,
+                                      gboolean location_unknown);
+
 G_END_DECLS
 
 #endif /* _GRL_MEDIA_SOURCE_H_ */
diff --git a/src/grl-metadata-source.h b/src/grl-metadata-source.h
index de80c8b..3da29e9 100644
--- a/src/grl-metadata-source.h
+++ b/src/grl-metadata-source.h
@@ -205,6 +205,7 @@ typedef struct {
  * @GRL_OP_SET_METADATA: Update metadata of a #GrlMedia in a service.
  * @GRL_OP_MEDIA_FROM_URI: Create a #GrlMedia instance from an URI
  * representing a media resource.
+ * @GRL_OP_NOTIFY_CHANGED: Notify about changes in the #GrlMediaSource.
  *
  * Bitwise flags which reflect the kind of operations that a
  * #GrlMediaPlugin supports.
@@ -221,6 +222,7 @@ typedef enum {
   GRL_OP_REMOVE          = 1 << 7,
   GRL_OP_SET_METADATA    = 1 << 8,
   GRL_OP_MEDIA_FROM_URI  = 1 << 9,
+  GRL_OP_NOTIFY_CHANGED  = 1 << 10,
 } GrlSupportedOps;
 
 /* GrlMetadataSource class */
-- 
1.7.3.5



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]