[libpeas/proxys: 16/25] [PeasObjectModule] Introduce peas_object_module_register_extension.



commit 8dcea1a08897fff34e725d687139fd1ab8b70710
Author: Steve Frécinaux <code istique net>
Date:   Wed May 19 19:54:45 2010 +0200

    [PeasObjectModule] Introduce peas_object_module_register_extension.
    
    This function allows a plugin to register an extension and a callback
    to create the related object. This function is meant to be called from
    peas_register_types().

 libpeas/peas-engine.c                              |    3 +-
 libpeas/peas-object-module.c                       |   76 ++++++++++++++++++--
 libpeas/peas-object-module.h                       |   13 +++-
 loaders/c/peas-plugin-loader-c.c                   |   70 +++++++-----------
 loaders/c/peas-plugin-loader-c.h                   |    3 +-
 .../helloworld/peasdemo-hello-world-plugin.c       |   30 ++++----
 .../helloworld/peasdemo-hello-world-plugin.h       |    5 +-
 7 files changed, 130 insertions(+), 70 deletions(-)
---
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index d88b2ab..12a8735 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -527,7 +527,8 @@ load_plugin_loader (PeasEngine  *engine,
   /* make sure to load the type definition */
   if (g_type_module_use (G_TYPE_MODULE (module)))
     {
-      loader = (PeasPluginLoader *) peas_object_module_new_object (module);
+      peas_object_module_register_types (module);
+      loader = (PeasPluginLoader *) peas_object_module_create_object (module, PEAS_TYPE_PLUGIN_LOADER);
 
       if (loader == NULL || !PEAS_IS_PLUGIN_LOADER (loader))
         {
diff --git a/libpeas/peas-object-module.c b/libpeas/peas-object-module.c
index 7ebaf09..42b9755 100644
--- a/libpeas/peas-object-module.c
+++ b/libpeas/peas-object-module.c
@@ -30,7 +30,7 @@
 
 G_DEFINE_TYPE (PeasObjectModule, peas_object_module, G_TYPE_TYPE_MODULE);
 
-typedef GObject *(*PeasObjectModuleRegisterFunc) (GTypeModule *);
+typedef void     (*PeasObjectModuleRegisterFunc) (PeasObjectModule *);
 
 enum {
   PROP_0,
@@ -39,15 +39,23 @@ enum {
   PROP_RESIDENT
 };
 
+typedef struct {
+  GType iface_type;
+  PeasCreateFunc func;
+  gconstpointer user_data;
+} InterfaceImplementation;
+
 struct _PeasObjectModulePrivate {
   GModule *library;
 
   PeasObjectModuleRegisterFunc register_func;
+  GArray *implementations;
 
   gchar *path;
   gchar *module_name;
 
-  gboolean resident;
+  gboolean types_registered : 1;
+  gboolean resident : 1;
 };
 
 static gboolean
@@ -121,6 +129,8 @@ peas_object_module_init (PeasObjectModule *module)
   module->priv = G_TYPE_INSTANCE_GET_PRIVATE (module,
                                               PEAS_TYPE_OBJECT_MODULE,
                                               PeasObjectModulePrivate);
+
+  module->priv->implementations = g_array_new (FALSE, FALSE, sizeof (InterfaceImplementation));
 }
 
 static void
@@ -130,6 +140,7 @@ peas_object_module_finalize (GObject *object)
 
   g_free (module->priv->path);
   g_free (module->priv->module_name);
+  g_array_free (module->priv->implementations, TRUE);
 
   G_OBJECT_CLASS (peas_object_module_parent_class)->finalize (object);
 }
@@ -239,12 +250,55 @@ peas_object_module_new (const gchar *module_name,
                                             NULL);
 }
 
+void
+peas_object_module_register_types (PeasObjectModule *module)
+{
+  g_return_if_fail (PEAS_IS_OBJECT_MODULE (module));
+  g_return_if_fail (module->priv->register_func != NULL);
+  g_return_if_fail (module->priv->types_registered == FALSE);
+
+  module->priv->register_func (module);
+  module->priv->types_registered = TRUE;
+}
+
 GObject *
-peas_object_module_new_object (PeasObjectModule *module)
+peas_object_module_create_object (PeasObjectModule *module,
+                                  GType             interface)
 {
-  g_return_val_if_fail (module->priv->register_func != NULL, NULL);
+  guint i;
+  InterfaceImplementation *impls;
 
-  return module->priv->register_func (G_TYPE_MODULE (module));
+  g_return_val_if_fail (PEAS_IS_OBJECT_MODULE (module), NULL);
+
+  if (!module->priv->types_registered)
+    peas_object_module_register_types (module);
+
+  impls = (InterfaceImplementation *) module->priv->implementations->data;
+  for (i = 0; i < module->priv->implementations->len; ++i)
+    if (impls[i].iface_type == interface)
+      return impls[i].func (impls[i].user_data);
+
+  return NULL;
+}
+
+gboolean
+peas_object_module_provides_object (PeasObjectModule *module,
+                                    GType             interface)
+{
+  guint i;
+  InterfaceImplementation *impls;
+
+  g_return_val_if_fail (PEAS_IS_OBJECT_MODULE (module), FALSE);
+
+  if (!module->priv->types_registered)
+    peas_object_module_register_types (module);
+
+  impls = (InterfaceImplementation *) module->priv->implementations->data;
+  for (i = 0; i < module->priv->implementations->len; ++i)
+    if (impls[i].iface_type == interface)
+      return TRUE;
+
+  return FALSE;
 }
 
 const gchar *
@@ -270,3 +324,15 @@ peas_object_module_get_library (PeasObjectModule *module)
 
   return module->priv->library;
 }
+
+void
+peas_object_module_register_extension (PeasObjectModule *module,
+                                       GType iface_type,
+                                       PeasCreateFunc func,
+                                       gconstpointer user_data)
+{
+  InterfaceImplementation impl = { iface_type, func, user_data };
+  g_array_append_val (module->priv->implementations, impl);
+
+  g_debug ("Registered extension for type '%s'", g_type_name (iface_type));
+}
diff --git a/libpeas/peas-object-module.h b/libpeas/peas-object-module.h
index a68d6ab..7a14deb 100644
--- a/libpeas/peas-object-module.h
+++ b/libpeas/peas-object-module.h
@@ -41,6 +41,8 @@ typedef struct _PeasObjectModule        PeasObjectModule;
 typedef struct _PeasObjectModuleClass   PeasObjectModuleClass;
 typedef struct _PeasObjectModulePrivate PeasObjectModulePrivate;
 
+typedef GObject *(*PeasCreateFunc)   (gconstpointer user_data);
+
 struct _PeasObjectModule {
   GTypeModule parent;
 
@@ -59,13 +61,22 @@ PeasObjectModule   *peas_object_module_new                    (const gchar
                                                                const gchar      *path,
                                                                gboolean          resident);
 
-GObject            *peas_object_module_new_object             (PeasObjectModule *module);
+void                peas_object_module_register_types         (PeasObjectModule *module);
+GObject            *peas_object_module_create_object          (PeasObjectModule *module,
+                                                               GType             interface);
+gboolean            peas_object_module_provides_object        (PeasObjectModule *module,
+                                                               GType             interface);
 
 const gchar        *peas_object_module_get_path               (PeasObjectModule *module);
 const gchar        *peas_object_module_get_module_name        (PeasObjectModule *module);
 
 GModule            *peas_object_module_get_library            (PeasObjectModule *module);
 
+void                peas_object_module_register_extension     (PeasObjectModule *module,
+                                                               GType iface_type,
+                                                               PeasCreateFunc func,
+                                                               gconstpointer user_data);
+
 G_END_DECLS
 
 #endif /* __PEAS_OBJECT_MODULE_H__ */
diff --git a/loaders/c/peas-plugin-loader-c.c b/loaders/c/peas-plugin-loader-c.c
index ad4a75a..51b5889 100644
--- a/loaders/c/peas-plugin-loader-c.c
+++ b/loaders/c/peas-plugin-loader-c.c
@@ -24,8 +24,6 @@
 #include <libpeas/peas-object-module.h>
 #include <gmodule.h>
 
-typedef gpointer (* CreateFunc) (void);
-
 struct _PeasPluginLoaderCPrivate
 {
   GHashTable *loaded_plugins;
@@ -33,12 +31,22 @@ struct _PeasPluginLoaderCPrivate
 
 G_DEFINE_DYNAMIC_TYPE (PeasPluginLoaderC, peas_plugin_loader_c, PEAS_TYPE_PLUGIN_LOADER);
 
-G_MODULE_EXPORT GObject *
-peas_register_types (GTypeModule *type_module)
+static GObject *
+create_object (GType the_type)
+{
+  return g_object_new (the_type, NULL);
+}
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-        peas_plugin_loader_c_register_type (type_module);
-        peas_extension_c_register (type_module);
-        return g_object_new (PEAS_TYPE_PLUGIN_LOADER_C, NULL);
+  peas_plugin_loader_c_register_type (G_TYPE_MODULE (module));
+  peas_extension_c_register (G_TYPE_MODULE (module));
+
+  peas_object_module_register_extension (module,
+                                         PEAS_TYPE_PLUGIN_LOADER,
+                                         (PeasCreateFunc) create_object,
+                                         GSIZE_TO_POINTER (PEAS_TYPE_PLUGIN_LOADER_C));
 }
 
 static void
@@ -82,48 +90,24 @@ peas_plugin_loader_c_load (PeasPluginLoader * loader,
       return FALSE;
     }
 
-  {
-    /* FIXME: This weird hack is currently necessary but ought to be removed. */
-    PeasPlugin *result = (PeasPlugin *) peas_object_module_new_object (module);
-    g_object_unref (result);
-  }
+  peas_object_module_register_types (module);
 
   return TRUE;
 }
 
-static CreateFunc
-get_create_function (PeasPluginLoaderC *cloader,
-                     PeasPluginInfo    *info,
-                     GType              exten_type)
-{
-  PeasObjectModule *module;
-  gchar *symbol_name;
-  gpointer symbol;
-  gboolean ret;
-
-  module = (PeasObjectModule *) g_hash_table_lookup (cloader->priv->loaded_plugins,
-                                                     info);
-
-  g_return_val_if_fail (module != NULL, NULL);
-
-  symbol_name = g_strdup_printf ("create_%s", g_type_name (exten_type));
-  g_debug ("Resolving symbol %s", symbol_name);
-  ret = g_module_symbol (peas_object_module_get_library (module), symbol_name, &symbol);
-  g_free (symbol_name);
-
-  if (!ret)
-    return NULL;
-  return (CreateFunc) symbol;
-}
-
 static gboolean
 peas_plugin_loader_c_provides_extension  (PeasPluginLoader *loader,
                                           PeasPluginInfo   *info,
                                           GType             exten_type)
 {
   PeasPluginLoaderC *cloader = PEAS_PLUGIN_LOADER_C (loader);
+  PeasObjectModule *module;
+
+  module = (PeasObjectModule *) g_hash_table_lookup (cloader->priv->loaded_plugins,
+                                                     info);
+  g_return_val_if_fail (module != NULL, FALSE);
 
-  return get_create_function (cloader, info, exten_type) != NULL;
+  return peas_object_module_provides_object (module, exten_type);
 }
 
 static PeasExtension *
@@ -132,14 +116,14 @@ peas_plugin_loader_c_get_extension (PeasPluginLoader *loader,
                                     GType             exten_type)
 {
   PeasPluginLoaderC *cloader = PEAS_PLUGIN_LOADER_C (loader);
-  CreateFunc create_func;
+  PeasObjectModule *module;
   gpointer instance;
 
-  create_func = get_create_function (cloader, info, exten_type);
-  if (!create_func)
-    return NULL;
+  module = (PeasObjectModule *) g_hash_table_lookup (cloader->priv->loaded_plugins,
+                                                     info);
+  g_return_val_if_fail (module != NULL, NULL);
 
-  instance = create_func ();
+  instance = peas_object_module_create_object (module, exten_type);
 
   g_return_val_if_fail (instance != NULL, NULL);
   g_return_val_if_fail (G_IS_OBJECT (instance), NULL);
diff --git a/loaders/c/peas-plugin-loader-c.h b/loaders/c/peas-plugin-loader-c.h
index 4c22500..ae188f0 100644
--- a/loaders/c/peas-plugin-loader-c.h
+++ b/loaders/c/peas-plugin-loader-c.h
@@ -23,6 +23,7 @@
 #define __PEAS_PLUGIN_LOADER_C_H__
 
 #include <libpeas/peas-plugin-loader.h>
+#include <libpeas/peas-object-module.h>
 
 G_BEGIN_DECLS
 
@@ -50,7 +51,7 @@ struct _PeasPluginLoaderCClass {
 GType                    peas_plugin_loader_c_get_type (void) G_GNUC_CONST;
 
 /* All the loaders must implement this function */
-G_MODULE_EXPORT GObject *peas_register_types           (GTypeModule *module);
+G_MODULE_EXPORT void     peas_register_types           (PeasObjectModule *module);
 
 G_END_DECLS
 
diff --git a/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.c b/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.c
index eca2f91..940daf8 100644
--- a/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.c
+++ b/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.c
@@ -157,25 +157,23 @@ peasdemo_hello_world_plugin_class_finalize (PeasDemoHelloWorldPluginClass *klass
 {
 }
 
-G_MODULE_EXPORT GObject *
-peas_register_types (GTypeModule *type_module)
+GObject *
+create_plugin (void)
 {
-        peasdemo_hello_world_plugin_register_type (type_module);
-
-        return g_object_new (PEASDEMO_TYPE_HELLO_WORLD_PLUGIN,
-                             NULL);
-}
-
-G_MODULE_EXPORT GObject *
-create_PeasActivatable ()
-{
-  g_debug ("%s called", G_STRFUNC);
   return g_object_new (PEASDEMO_TYPE_HELLO_WORLD_PLUGIN, NULL);
 }
 
-G_MODULE_EXPORT GObject *
-create_PeasUIConfigurable ()
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
 {
-  g_debug ("%s called", G_STRFUNC);
-  return g_object_new (PEASDEMO_TYPE_HELLO_WORLD_PLUGIN, NULL);
+  peasdemo_hello_world_plugin_register_type (G_TYPE_MODULE (module));
+
+  peas_object_module_register_extension (module,
+                                         PEAS_TYPE_ACTIVATABLE,
+                                         (PeasCreateFunc) create_plugin,
+                                         NULL);
+  peas_object_module_register_extension (module,
+                                         PEAS_UI_TYPE_CONFIGURABLE,
+                                         (PeasCreateFunc) create_plugin,
+                                         NULL);
 }
diff --git a/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.h b/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.h
index 534dcf9..551664e 100644
--- a/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.h
+++ b/peas-demo/plugins/helloworld/peasdemo-hello-world-plugin.h
@@ -5,6 +5,7 @@
 #include <glib-object.h>
 #include <libpeas/peas-plugin.h>
 #include <libpeas/peas-plugin-info.h>
+#include <libpeas/peas-object-module.h>
 
 G_BEGIN_DECLS
 
@@ -27,9 +28,7 @@ struct _PeasDemoHelloWorldPluginClass {
 };
 
 GType                       peasdemo_hello_world_plugin_get_type  (void) G_GNUC_CONST;
-G_MODULE_EXPORT GObject    *peas_register_types                   (GTypeModule *module);
-G_MODULE_EXPORT GObject    *create_PeasUIConfigurable ();
-G_MODULE_EXPORT GObject    *create_PeasActivatable ();
+G_MODULE_EXPORT void        peas_register_types                   (PeasObjectModule *module);
 
 G_END_DECLS
 



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