[telepathy-gabble/master] Turn the plugin loader into a fully-fledged object

Will Thompson will.thompson at collabora.co.uk
Sat Nov 14 05:15:50 PST 2009


GabblePluginLoader is a singleton, because it doesn't make sense to have
more than one plugin loader. It keeps a reference to itself once it's
instantiated, because it doesn't make sense to destroy it (our modules
can't be unloaded).

If Gabble is built without plugin support, GabblePluginLoader is still
an immortal singleton, it just doesn't do anything.
---
 src/gabble.c        |    2 +-
 src/plugin-loader.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++----
 src/plugin-loader.h |   37 +++++++++++++++++++++++-
 3 files changed, 108 insertions(+), 9 deletions(-)

diff --git a/src/gabble.c b/src/gabble.c
index b8c5c2a..4dc7b8a 100644
--- a/src/gabble.c
+++ b/src/gabble.c
@@ -141,7 +141,7 @@ gabble_main (int argc,
     tp_debug_set_persistent (TRUE);
 #endif
 
-  gabble_plugin_loader_load ();
+  gabble_plugin_loader_dup ();
 
   out = tp_run_connection_manager ("telepathy-gabble", VERSION,
       construct_cm, argc, argv);
diff --git a/src/plugin-loader.c b/src/plugin-loader.c
index 9117230..63bf2e5 100644
--- a/src/plugin-loader.c
+++ b/src/plugin-loader.c
@@ -21,15 +21,26 @@
 #include "plugin-loader.h"
 
 #include <glib.h>
-#include <gmodule.h>
+
+#ifdef ENABLE_PLUGINS
+# include <gmodule.h>
+#endif
 
 #define DEBUG_FLAG GABBLE_DEBUG_PLUGINS
 #include "debug.h"
 #include "plugin.h"
 
+G_DEFINE_TYPE(GabblePluginLoader,
+    gabble_plugin_loader,
+    G_TYPE_OBJECT)
+
+struct _GabblePluginLoaderPrivate {
+    guint unused;
+};
+
 #ifdef ENABLE_PLUGINS
-void
-gabble_plugin_loader_load (void)
+static void
+gabble_plugin_loader_probe (GabblePluginLoader *self)
 {
   GError *error = NULL;
   GDir *d;
@@ -118,13 +129,66 @@ gabble_plugin_loader_load (void)
 
   g_dir_close (d);
 }
+#endif
 
-#else /* ! ENABLE_PLUGINS */
+static void
+gabble_plugin_loader_init (GabblePluginLoader *self)
+{
+  GabblePluginLoaderPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+      GABBLE_TYPE_PLUGIN_LOADER, GabblePluginLoaderPrivate);
 
-void
-gabble_plugin_loader_load (void)
+  self->priv = priv;
+}
+
+static GObject *
+gabble_plugin_loader_constructor (
+    GType type,
+    guint n_props,
+    GObjectConstructParam *props)
 {
-  DEBUG ("built without plugin support");
+  static GObject *singleton = NULL;
+
+  if (singleton == NULL)
+    {
+      /* We keep a ref in here to ensure the loader never dies. */
+      singleton = G_OBJECT_CLASS (gabble_plugin_loader_parent_class)->
+          constructor (type, n_props, props);
+    }
+
+  return g_object_ref (singleton);
 }
 
+static void
+gabble_plugin_loader_constructed (GObject *object)
+{
+  GabblePluginLoader *self = GABBLE_PLUGIN_LOADER (object);
+  void (*chain_up) (GObject *) =
+      G_OBJECT_CLASS (gabble_plugin_loader_parent_class)->constructed;
+
+  if (chain_up != NULL)
+    chain_up (object);
+
+#ifdef ENABLE_PLUGINS
+  gabble_plugin_loader_probe (self);
+#else
+  DEBUG ("built without plugin support, not actually loading anything");
+  (void) self; /* silence unused variable warning. */
 #endif
+}
+
+static void
+gabble_plugin_loader_class_init (GabblePluginLoaderClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (GabblePluginLoaderPrivate));
+
+  object_class->constructor = gabble_plugin_loader_constructor;
+  object_class->constructed = gabble_plugin_loader_constructed;
+}
+
+GabblePluginLoader *
+gabble_plugin_loader_dup ()
+{
+  return g_object_new (GABBLE_TYPE_PLUGIN_LOADER, NULL);
+}
diff --git a/src/plugin-loader.h b/src/plugin-loader.h
index 990e6c5..84b57b8 100644
--- a/src/plugin-loader.h
+++ b/src/plugin-loader.h
@@ -20,6 +20,41 @@
 #ifndef __PLUGIN_LOADER_H__
 #define __PLUGIN_LOADER_H__
 
-void gabble_plugin_loader_load (void);
+#include <glib-object.h>
+
+typedef struct _GabblePluginLoader GabblePluginLoader;
+typedef struct _GabblePluginLoaderClass GabblePluginLoaderClass;
+typedef struct _GabblePluginLoaderPrivate GabblePluginLoaderPrivate;
+
+struct _GabblePluginLoaderClass {
+    GObjectClass parent_class;
+};
+
+struct _GabblePluginLoader {
+    GObject parent;
+
+    GabblePluginLoaderPrivate *priv;
+};
+
+GType gabble_plugin_loader_get_type (void);
+
+/* TYPE MACROS */
+#define GABBLE_TYPE_PLUGIN_LOADER \
+  (gabble_plugin_loader_get_type ())
+#define GABBLE_PLUGIN_LOADER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj), GABBLE_TYPE_PLUGIN_LOADER, \
+                              GabblePluginLoader))
+#define GABBLE_PLUGIN_LOADER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass), GABBLE_TYPE_PLUGIN_LOADER, \
+                           GabblePluginLoaderClass))
+#define GABBLE_IS_PLUGIN_LOADER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj), GABBLE_TYPE_PLUGIN_LOADER))
+#define GABBLE_IS_PLUGIN_LOADER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass), GABBLE_TYPE_PLUGIN_LOADER))
+#define GABBLE_PLUGIN_LOADER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_PLUGIN_LOADER, \
+                              GabblePluginLoaderClass))
+
+GabblePluginLoader *gabble_plugin_loader_dup (void);
 
 #endif /* #ifndef __PLUGIN_LOADER_H__ */
-- 
1.5.6.5




More information about the telepathy-commits mailing list