[grilo] core: Add register_keys plugin function



commit a4fac2b310750e42435fc527e9bbe936d7be8f23
Author: Bastien Nocera <hadess hadess net>
Date:   Mon Dec 1 01:02:18 2014 +0100

    core: Add register_keys plugin function
    
    This allows for custom metadata keys to be registered before the
    plugins, or even the sources, are loaded.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=740943

 src/grl-plugin-priv.h |    5 ++
 src/grl-plugin.c      |   38 ++++++++++++++++++
 src/grl-registry.c    |  104 +++++++++++++++++++++++++++++++++----------------
 src/grl-registry.h    |   33 +++++++++++++---
 4 files changed, 140 insertions(+), 40 deletions(-)
---
diff --git a/src/grl-plugin-priv.h b/src/grl-plugin-priv.h
index 550e2ba..7538f05 100644
--- a/src/grl-plugin-priv.h
+++ b/src/grl-plugin-priv.h
@@ -48,10 +48,15 @@ void grl_plugin_set_load_func (GrlPlugin *plugin,
 void grl_plugin_set_unload_func (GrlPlugin *plugin,
                                  gpointer unload_function);
 
+void grl_plugin_set_register_keys_func (GrlPlugin *plugin,
+                                        gpointer   register_keys_function);
+
 gboolean grl_plugin_load (GrlPlugin *plugin, GList *configurations);
 
 void grl_plugin_unload (GrlPlugin *plugin);
 
+void grl_plugin_register_keys (GrlPlugin *plugin);
+
 void grl_plugin_set_id (GrlPlugin *plugin,
                         const gchar *id);
 
diff --git a/src/grl-plugin.c b/src/grl-plugin.c
index 7e92c93..cfadd38 100644
--- a/src/grl-plugin.c
+++ b/src/grl-plugin.c
@@ -64,6 +64,7 @@ struct _GrlPluginPrivate {
   gboolean loaded;
   gboolean (*load_func) (GrlRegistry *, GrlPlugin *, GList *);
   void (*unload_func) (GrlPlugin *);
+  void (*register_keys_func) (GrlRegistry *, GrlPlugin *);
 };
 
 static void grl_plugin_finalize (GObject *object);
@@ -199,6 +200,23 @@ grl_plugin_set_unload_func (GrlPlugin *plugin,
   plugin->priv->unload_func = unload_function;
 }
 
+/*
+ * grl_plugin_set_register_keys_func:
+ * @plugin: a plugin
+ * @register_keys_function: a function
+ *
+ * Sets the function to be executed to register new
+ * metadata keys.
+ */
+void
+grl_plugin_set_register_keys_func (GrlPlugin *plugin,
+                                   gpointer   register_keys_function)
+{
+  g_return_if_fail (GRL_IS_PLUGIN (plugin));
+
+  plugin->priv->register_keys_func = register_keys_function;
+}
+
 /**
  * grl_plugin_load:
  * @plugin: a plugin
@@ -252,6 +270,26 @@ grl_plugin_unload (GrlPlugin *plugin)
 }
 
 /*
+ * grl_plugin_register_keys:
+ * @plugin: a plugin
+ *
+ * Register custom metadata keys for the plugin
+ */
+void
+grl_plugin_register_keys (GrlPlugin *plugin)
+{
+  GrlRegistry *registry;
+
+  g_return_if_fail (GRL_IS_PLUGIN (plugin));
+
+  registry = grl_registry_get_default ();
+
+  if (plugin->priv->register_keys_func) {
+    plugin->priv->register_keys_func (registry, plugin);
+  }
+}
+
+/*
  * grl_plugin_set_id:
  * @plugin: a plugin
  * @id: plugin identifier
diff --git a/src/grl-registry.c b/src/grl-registry.c
index c1dd0b1..fcb3931 100644
--- a/src/grl-registry.c
+++ b/src/grl-registry.c
@@ -130,6 +130,10 @@ static void configs_free (GList *configs);
 static gboolean strv_contains (const char **strv, const char  *str);
 #endif
 
+static GrlPlugin *grl_registry_prepare_plugin (GrlRegistry *registry,
+                                               const gchar *library_filename,
+                                               GError **error);
+
 /* ================ GrlRegistry GObject ================ */
 
 enum {
@@ -516,12 +520,11 @@ get_info_from_plugin_xml (const gchar *xml_path)
 }
 
 static gboolean
-activate_plugin (GrlRegistry *registry,
-                 GrlPlugin *plugin,
-                 GError **error)
+register_keys_plugin (GrlRegistry *registry,
+                      GrlPlugin *plugin,
+                      GError **error)
 {
   gboolean is_loaded;
-  GList *plugin_configs;
 
   /* Check if plugin is already loaded */
   g_object_get (plugin, "loaded", &is_loaded, NULL);
@@ -534,6 +537,18 @@ activate_plugin (GrlRegistry *registry,
     return FALSE;
   }
 
+  grl_plugin_register_keys (plugin);
+
+  return TRUE;
+}
+
+static gboolean
+activate_plugin (GrlRegistry *registry,
+                 GrlPlugin *plugin,
+                 GError **error)
+{
+  GList *plugin_configs;
+
   plugin_configs = g_hash_table_lookup (registry->priv->configs,
                                         grl_plugin_get_id (plugin));
 
@@ -685,19 +700,24 @@ static gboolean
 grl_registry_load_plugin_list (GrlRegistry *registry,
                                GList *plugin_list)
 {
-  GrlPlugin *plugin;
+  GList *l;
   gboolean loaded_one = FALSE;
 
-  while (plugin_list) {
-    plugin = (GrlPlugin *) plugin_list->data;
+  for (l = plugin_list; l ; l = l->next) {
+    GrlPlugin *plugin = l->data;
     if (grl_plugin_get_module (plugin)) {
-      loaded_one |= activate_plugin (registry, plugin, NULL);
+      loaded_one |= register_keys_plugin (registry, plugin, NULL);
     } else {
-      loaded_one |= grl_registry_load_plugin (registry,
-                                              grl_plugin_get_filename (plugin),
-                                              NULL);
+      loaded_one |= (grl_registry_prepare_plugin (registry,
+                                                  grl_plugin_get_filename (plugin),
+                                                  NULL) != NULL);
+      loaded_one |= register_keys_plugin (registry, plugin, NULL);
     }
-    plugin_list = g_list_next (plugin_list);
+  }
+
+  for (l = plugin_list; l ; l = l->next) {
+    GrlPlugin *plugin = l->data;
+    loaded_one |= activate_plugin (registry, plugin, NULL);
   }
 
   return loaded_one;
@@ -1092,22 +1112,10 @@ grl_registry_add_directory (GrlRegistry *registry,
   registry->priv->all_plugins_preloaded = FALSE;
 }
 
-/**
- * grl_registry_load_plugin:
- * @registry: the registry instance
- * @library_filename: the path to the so file
- * @error: error return location or @NULL to ignore
- *
- * Loads a module from shared object file stored in @path
- *
- * Returns: %TRUE if the module is loaded correctly
- *
- * Since: 0.2.0
- */
-gboolean
-grl_registry_load_plugin (GrlRegistry *registry,
-                          const gchar *library_filename,
-                          GError **error)
+static GrlPlugin *
+grl_registry_prepare_plugin (GrlRegistry *registry,
+                             const gchar *library_filename,
+                             GError **error)
 {
   GModule *module;
   GrlPluginDescriptor *plugin_desc;
@@ -1125,7 +1133,7 @@ grl_registry_load_plugin (GrlRegistry *registry,
                  GRL_CORE_ERROR,
                  GRL_CORE_ERROR_LOAD_PLUGIN_FAILED,
                  _("Failed to load plugin from %s"), library_filename);
-    return FALSE;
+    return NULL;
   }
 
   if (!g_module_symbol (module, "GRL_PLUGIN_DESCRIPTOR", (gpointer) &plugin_desc)) {
@@ -1135,7 +1143,7 @@ grl_registry_load_plugin (GrlRegistry *registry,
                  GRL_CORE_ERROR_LOAD_PLUGIN_FAILED,
                  _("Invalid plugin file %s"), library_filename);
     g_module_close (module);
-    return FALSE;
+    return NULL;
   }
 
   if (!plugin_desc->plugin_init ||
@@ -1146,7 +1154,7 @@ grl_registry_load_plugin (GrlRegistry *registry,
                  GRL_CORE_ERROR_LOAD_PLUGIN_FAILED,
                  _("'%s' is not a valid plugin file"), library_filename);
     g_module_close (module);
-    return FALSE;
+    return NULL;
   }
 
   /* Check if plugin is preloaded; if not, then create one */
@@ -1165,7 +1173,7 @@ grl_registry_load_plugin (GrlRegistry *registry,
                    GRL_CORE_ERROR_LOAD_PLUGIN_FAILED,
                    _("Unable to load plugin '%s'"), plugin_desc->plugin_id);
       g_module_close (module);
-      return FALSE;
+      return NULL;
     }
   } else {
     /* Check if the existent plugin is for a different module */
@@ -1175,13 +1183,14 @@ grl_registry_load_plugin (GrlRegistry *registry,
                    GRL_CORE_ERROR,
                    GRL_CORE_ERROR_LOAD_PLUGIN_FAILED,
                    _("Plugin '%s' already exists"), library_filename);
-      return FALSE;
+      return NULL;
     }
   }
 
   if (!grl_plugin_get_module (plugin)) {
     grl_plugin_set_load_func (plugin, plugin_desc->plugin_init);
     grl_plugin_set_unload_func (plugin, plugin_desc->plugin_deinit);
+    grl_plugin_set_register_keys_func (plugin, plugin_desc->plugin_register_keys);
 
     /* Insert module name as part of plugin information */
     module_name = g_path_get_basename (library_filename);
@@ -1194,7 +1203,34 @@ grl_registry_load_plugin (GrlRegistry *registry,
     g_module_make_resident (module);
   }
 
-  return activate_plugin (registry, plugin, error);
+  return plugin;
+}
+
+/**
+ * grl_registry_load_plugin:
+ * @registry: the registry instance
+ * @library_filename: the path to the so file
+ * @error: error return location or @NULL to ignore
+ *
+ * Loads a module from shared object file stored in @path
+ *
+ * Returns: %TRUE if the module is loaded correctly
+ *
+ * Since: 0.2.0
+ */
+gboolean
+grl_registry_load_plugin (GrlRegistry *registry,
+                          const gchar *library_filename,
+                          GError **error)
+{
+  GrlPlugin *plugin;
+
+  plugin = grl_registry_prepare_plugin (registry, library_filename, error);
+  if (!plugin)
+    return FALSE;
+
+  return register_keys_plugin (registry, plugin, error) &&
+         activate_plugin (registry, plugin, error);
 }
 
 /**
diff --git a/src/grl-registry.h b/src/grl-registry.h
index 5a12335..f20a19f 100644
--- a/src/grl-registry.h
+++ b/src/grl-registry.h
@@ -72,25 +72,44 @@
 /* Plugin registration */
 
 /**
- * GRL_PLUGIN_REGISTER:
+ * GRL_PLUGIN_REGISTER_FULL:
  * @init: the module initialization. It shall instantiate
  * the #GrlPlugins provided
  * @deinit: (allow-none): function to execute when the registry needs to dispose the module
+ * @register_keys: (allow-none): function to execute before plugin initialisation to register
+ * new metadata keys
  * @id: the module identifier
  *
  * Define the boilerplate for loadable modules. Defines a new module
  * descriptor which provides a set of #GrlPlugins
  */
-#define GRL_PLUGIN_REGISTER(init,                                    \
-                            deinit,                                  \
-                            id)                                      \
-  G_MODULE_EXPORT GrlPluginDescriptor GRL_PLUGIN_DESCRIPTOR = {                \
+#define GRL_PLUGIN_REGISTER_FULL(init,                               \
+                                 deinit,                             \
+                                 register_keys,                      \
+                                 id)                                 \
+  G_MODULE_EXPORT GrlPluginDescriptor GRL_PLUGIN_DESCRIPTOR = {      \
     .plugin_id = id,                                                 \
     .plugin_init = init,                                             \
     .plugin_deinit = deinit,                                         \
+    .plugin_register_keys = register_keys,                           \
     .module = NULL                                                   \
   }
 
+/**
+ * GRL_PLUGIN_REGISTER:
+ * @init: the module initialization. It shall instantiate
+ * the #GrlPlugins provided
+ * @deinit: (allow-none): function to execute when the registry needs to dispose the module
+ * @id: the module identifier
+ *
+ * Define the boilerplate for loadable modules. Defines a new module
+ * descriptor which provides a set of #GrlPlugins
+ */
+#define GRL_PLUGIN_REGISTER(init,                                    \
+                            deinit,                                  \
+                            id)                                      \
+  GRL_PLUGIN_REGISTER_FULL(init, deinit, NULL, id)
+
 /* Plugin descriptor */
 
 typedef struct _GrlRegistry GrlRegistry;
@@ -115,9 +134,11 @@ struct _GrlPluginDescriptor {
                            GList *configs);
   void (*plugin_deinit) (GrlPlugin *plugin);
   GModule *module;
+  void (*plugin_register_keys) (GrlRegistry *registry,
+                                GrlPlugin   *plugin);
 
   /*< private >*/
-  gpointer _grl_reserved[GRL_PADDING];
+  gpointer _grl_reserved[GRL_PADDING - 1];
 };
 
 /* Plugin ranks */


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