Add registration hooks for extension points. Register the gio extension
authorAlexander Larsson <alexl@redhat.com>
Mon, 28 Jan 2008 19:43:10 +0000 (19:43 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Mon, 28 Jan 2008 19:43:10 +0000 (19:43 +0000)
2008-01-28  Alexander Larsson  <alexl@redhat.com>

        * giomodule.[ch]:
        * gio.symbols:
Add registration hooks for extension points.
Register the gio extension points.

        * fam/gfamdirectorymonitor.c:
        * fam/gfamfilemonitor.c:
        * glocaldirectorymonitor.[ch]:
        * glocalfilemonitor.[ch]:
        * gnativevolumemonitor.h:
        * gunionvolumemonitor.c:
        * gunixvolumemonitor.c:
        * gvfs.[ch]:
        * gvolumemonitor.h:
        * inotify/ginotifydirectorymonitor.c:
        * inotify/ginotifyfilemonitor.c:
Use the extension points registration instead
of g_type_children().

svn path=/trunk/; revision=6399

18 files changed:
gio/ChangeLog
gio/fam/gfamdirectorymonitor.c
gio/fam/gfamfilemonitor.c
gio/gio.symbols
gio/giomodule.c
gio/giomodule.h
gio/glocaldirectorymonitor.c
gio/glocaldirectorymonitor.h
gio/glocalfilemonitor.c
gio/glocalfilemonitor.h
gio/gnativevolumemonitor.h
gio/gunionvolumemonitor.c
gio/gunixvolumemonitor.c
gio/gvfs.c
gio/gvfs.h
gio/gvolumemonitor.h
gio/inotify/ginotifydirectorymonitor.c
gio/inotify/ginotifyfilemonitor.c

index e29375f..029c088 100644 (file)
@@ -1,3 +1,24 @@
+2008-01-28  Alexander Larsson  <alexl@redhat.com>
+
+        * giomodule.[ch]:
+        * gio.symbols:
+       Add registration hooks for extension points.
+       Register the gio extension points.
+       
+        * fam/gfamdirectorymonitor.c:
+        * fam/gfamfilemonitor.c:
+        * glocaldirectorymonitor.[ch]:
+        * glocalfilemonitor.[ch]:
+        * gnativevolumemonitor.h:
+        * gunionvolumemonitor.c:
+        * gunixvolumemonitor.c:
+        * gvfs.[ch]:
+        * gvolumemonitor.h:
+        * inotify/ginotifydirectorymonitor.c:
+        * inotify/ginotifyfilemonitor.c:
+       Use the extension points registration instead
+       of g_type_children().
+
 2008-01-28  Matthias Clasen  <mclasen@redhat.com>
        
        * gdrive.[hc]: 
index b947de7..2bf1a71 100644 (file)
@@ -112,7 +112,6 @@ g_fam_directory_monitor_class_init (GFamDirectoryMonitorClass* klass)
   gobject_class->constructor = g_fam_directory_monitor_constructor;
   file_monitor_class->cancel = g_fam_directory_monitor_cancel;
 
-  local_directory_monitor_class->prio = 10;
   local_directory_monitor_class->mount_notify = FALSE;
   local_directory_monitor_class->is_supported = g_fam_directory_monitor_is_supported;
 }
@@ -146,5 +145,9 @@ void
 g_fam_directory_monitor_register (GIOModule *module)
 {
   g_fam_directory_monitor_register_type (G_TYPE_MODULE (module));
+  g_io_extension_point_implement (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME,
+                                 G_TYPE_FAM_DIRECTORY_MONITOR,
+                                 "fam",
+                                 10);
 }
 
index 78d3df9..56dafa3 100644 (file)
@@ -112,7 +112,6 @@ g_fam_file_monitor_class_init (GFamFileMonitorClass* klass)
   gobject_class->constructor = g_fam_file_monitor_constructor;
   file_monitor_class->cancel = g_fam_file_monitor_cancel;
 
-  local_file_monitor_class->prio = 10;
   local_file_monitor_class->is_supported = g_fam_file_monitor_is_supported;
 }
 
@@ -144,5 +143,9 @@ void
 g_fam_file_monitor_register (GIOModule *module)
 {
   g_fam_file_monitor_register_type (G_TYPE_MODULE (module));
+  g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
+                                 G_TYPE_FAM_FILE_MONITOR,
+                                 "fam",
+                                 10);
 }
 
index 058b510..b2fdae7 100644 (file)
@@ -486,6 +486,17 @@ g_io_error_from_errno
 g_io_module_get_type  G_GNUC_CONST
 g_io_module_new 
 g_io_modules_load_all_in_directory
+g_io_extension_point_register
+g_io_extension_point_lookup
+g_io_extension_point_set_required_type
+g_io_extension_point_get_required_type
+g_io_extension_point_get_extensions
+g_io_extension_point_get_extension_by_name
+g_io_extension_point_implement
+g_io_extension_get_type
+g_io_extension_get_name
+g_io_extension_get_priority
+g_io_extension_ref_class
 #endif
 #endif
 
index 1b0b388..cee23d6 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <config.h>
 
+#include <string.h>
+
 #include "giomodule.h"
 #include "giomodule-priv.h"
 #include "glocalfilemonitor.h"
@@ -247,20 +249,30 @@ _g_io_modules_ensure_loaded (void)
 {
   GList *modules, *l;
   static gboolean loaded_dirs = FALSE;
-  int i;
-  GType *types;
-  guint n_types;
-  GQuark private_q, name_q;
+  GIOExtensionPoint *ep;
 
   G_LOCK (loaded_dirs);
 
   if (!loaded_dirs)
     {
       loaded_dirs = TRUE;
-      modules = g_io_modules_load_all_in_directory (GIO_MODULE_DIR);
 
-      private_q = g_quark_from_static_string ("gio-prio");
-      name_q = g_quark_from_static_string ("gio-name");
+      ep = g_io_extension_point_register (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
+      g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_DIRECTORY_MONITOR);
+      
+      ep = g_io_extension_point_register (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
+      g_io_extension_point_set_required_type (ep, G_TYPE_LOCAL_FILE_MONITOR);
+
+      ep = g_io_extension_point_register (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
+      g_io_extension_point_set_required_type (ep, G_TYPE_VOLUME_MONITOR);
+      
+      ep = g_io_extension_point_register (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
+      g_io_extension_point_set_required_type (ep, G_TYPE_NATIVE_VOLUME_MONITOR);
+      
+      ep = g_io_extension_point_register (G_VFS_EXTENSION_POINT_NAME);
+      g_io_extension_point_set_required_type (ep, G_TYPE_VFS);
+      
+      modules = g_io_modules_load_all_in_directory (GIO_MODULE_DIR);
 
       /* Initialize types from built-in "modules" */
 #if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
@@ -271,49 +283,7 @@ _g_io_modules_ensure_loaded (void)
       _g_unix_volume_monitor_get_type ();
 #endif
       _g_local_vfs_get_type ();
-
-      /* Copy over all prios to static gtype data so
-       * we can avoid loading the module again
-       */
-
-      types = g_type_children (G_TYPE_LOCAL_FILE_MONITOR, &n_types);
-      for (i = 0; i < n_types; i++)
-       {
-         GLocalFileMonitorClass *klass = g_type_class_ref (types[i]);
-         g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->prio));
-         g_type_class_unref (klass);
-       }
-      g_free (types);
-
-      types = g_type_children (G_TYPE_LOCAL_DIRECTORY_MONITOR, &n_types);
-      for (i = 0; i < n_types; i++)
-       {
-         GLocalDirectoryMonitorClass *klass = g_type_class_ref (types[i]);
-         g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->prio));
-         g_type_class_unref (klass);
-       }
-      g_free (types);
-
-      types = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_types);
-      for (i = 0; i < n_types; i++)
-       {
-         GNativeVolumeMonitorClass *klass = g_type_class_ref (types[i]);
-         g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->priority));
-         g_type_set_qdata (types[i], name_q, g_strdup (klass->name));
-         g_type_class_unref (klass);
-       }
-      g_free (types);
-      
-      types = g_type_children (G_TYPE_VFS, &n_types);
-      for (i = 0; i < n_types; i++)
-       {
-         GVfsClass *klass = g_type_class_ref (types[i]);
-         g_type_set_qdata (types[i], private_q, GINT_TO_POINTER (klass->priority));
-         g_type_set_qdata (types[i], name_q, g_strdup (klass->name));
-         g_type_class_unref (klass);
-       }
-      g_free (types);
-      
+    
       for (l = modules; l != NULL; l = l->next)
        g_type_module_unuse (G_TYPE_MODULE (l->data));
       
@@ -323,5 +293,193 @@ _g_io_modules_ensure_loaded (void)
   G_UNLOCK (loaded_dirs);
 }
 
+struct _GIOExtension {
+  char *name;
+  GType type;
+  gint priority;
+};
+
+struct _GIOExtensionPoint {
+  GType required_type;
+  char *name;
+  GList *extensions;
+};
+
+static GHashTable *extension_points = NULL;
+G_LOCK_DEFINE_STATIC(extension_points);
+
+
+static void
+g_io_extension_point_free (GIOExtensionPoint *ep)
+{
+  g_free (ep->name);
+  g_free (ep);
+}
+
+GIOExtensionPoint *
+g_io_extension_point_register (const char *name)
+{
+  GIOExtensionPoint *ep;
+  
+  G_LOCK (extension_points);
+  if (extension_points == NULL)
+    extension_points = g_hash_table_new_full (g_str_hash,
+                                             g_str_equal,
+                                             NULL,
+                                             (GDestroyNotify)g_io_extension_point_free);
+
+  if (g_hash_table_lookup (extension_points, name) != NULL)
+    {
+      g_warning ("Extension point %s registered multiple times", name);
+      G_UNLOCK (extension_points);
+      return NULL;
+    }
+
+  ep = g_new0 (GIOExtensionPoint, 1);
+  ep->name = g_strdup (name);
+  
+  g_hash_table_insert (extension_points, ep->name, ep);
+  
+  G_UNLOCK (extension_points);
+
+  return ep;
+}
+
+GIOExtensionPoint *
+g_io_extension_point_lookup (const char *name)
+{
+  GIOExtensionPoint *ep;
+
+  G_LOCK (extension_points);
+  ep = NULL;
+  if (extension_points != NULL)
+    ep = g_hash_table_lookup (extension_points, name);
+  
+  G_UNLOCK (extension_points);
+
+  return ep;
+  
+}
+
+void
+g_io_extension_point_set_required_type (GIOExtensionPoint *extension_point,
+                                       GType              type)
+{
+  extension_point->required_type = type;
+}
+
+GType
+g_io_extension_point_get_required_type (GIOExtensionPoint *extension_point)
+{
+  return extension_point->required_type;
+}
+
+GList *
+g_io_extension_point_get_extensions (GIOExtensionPoint *extension_point)
+{
+  return extension_point->extensions;
+}
+
+GIOExtension *
+g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
+                                           const char        *name)
+{
+  GList *l;
+
+  for (l = extension_point->extensions; l != NULL; l = l->next)
+    {
+      GIOExtension *e = l->data;
+
+      if (e->name != NULL &&
+         strcmp (e->name, name) == 0)
+       return e;
+    }
+  
+  return NULL;
+}
+
+static gint
+extension_prio_compare (gconstpointer  a,
+                       gconstpointer  b)
+{
+  const GIOExtension *extension_a = a, *extension_b = b;
+
+  return extension_b->priority - extension_a->priority;
+}
+
+GIOExtension *
+g_io_extension_point_implement (const char *extension_point_name,
+                               GType type,
+                               const char *extension_name,
+                               gint priority)
+{
+  GIOExtensionPoint *extension_point;
+  GIOExtension *extension;
+  GList *l;
+
+  g_return_val_if_fail (extension_point_name != NULL, NULL);
+
+  extension_point = g_io_extension_point_lookup (extension_point_name);
+  if (extension_point == NULL)
+    {
+      g_warning ("Tried to implement non-registered extension point %s", extension_point_name);
+      return NULL;
+    }
+  
+  if (extension_point->required_type != 0 &&
+      !g_type_is_a (type, extension_point->required_type))
+    {
+      g_warning ("Tried to register an extension of the type %s to extension point %s. "
+                "Expected type is %s.",
+                g_type_name (type),
+                extension_point_name, 
+                g_type_name (extension_point->required_type));
+      return NULL;
+    }      
+
+  /* Its safe to register the same type multiple times */
+  for (l = extension_point->extensions; l != NULL; l = l->next)
+    {
+      extension = l->data;
+      if (extension->type == type)
+       return extension;
+    }
+  
+  extension = g_slice_new0 (GIOExtension);
+  extension->type = type;
+  extension->name = g_strdup (extension_name);
+  extension->priority = priority;
+  
+  extension_point->extensions = g_list_insert_sorted (extension_point->extensions,
+                                                     extension, extension_prio_compare);
+  
+  return extension;
+}
+
+GTypeClass *
+g_io_extension_ref_class (GIOExtension *extension)
+{
+  return g_type_class_ref (extension->type);
+}
+
+
+GType
+g_io_extension_get_type (GIOExtension *extension)
+{
+  return extension->type;
+}
+
+const char *
+g_io_extension_get_name (GIOExtension *extension)
+{
+  return extension->name;
+}
+
+gint
+g_io_extension_get_priority (GIOExtension *extension)
+{
+  return extension->priority;
+}
+
 #define __G_IO_MODULE_C__
 #include "gioaliasdef.c"
index bc2bb67..76c27ce 100644 (file)
@@ -47,10 +47,31 @@ G_BEGIN_DECLS
 typedef struct _GIOModule GIOModule;
 typedef struct _GIOModuleClass GIOModuleClass;
 
+typedef struct _GIOExtensionPoint GIOExtensionPoint;
+typedef struct _GIOExtension GIOExtension;
+
 GType      g_io_module_get_type (void) G_GNUC_CONST;
 GIOModule *g_io_module_new      (const gchar *filename);
 
-GList *    g_io_modules_load_all_in_directory (const char *dirname);
+GList *g_io_modules_load_all_in_directory            (const char *dirname);
+
+GIOExtensionPoint *g_io_extension_point_register              (const char        *extension_point);
+GIOExtensionPoint *g_io_extension_point_lookup                (const char        *extension_point);
+void               g_io_extension_point_set_required_type     (GIOExtensionPoint *extension_point,
+                                                              GType              type);
+GType              g_io_extension_point_get_required_type     (GIOExtensionPoint *extension_point);
+GList             *g_io_extension_point_get_extensions        (GIOExtensionPoint *extension_point);
+GIOExtension *     g_io_extension_point_get_extension_by_name (GIOExtensionPoint *extension_point,
+                                                              const char        *name);
+GIOExtension *     g_io_extension_point_implement             (const char        *extension_point_name,
+                                                              GType              type,
+                                                              const char        *extension_name,
+                                                              gint               priority);
+
+GType                   g_io_extension_get_type     (GIOExtension *extension);
+const char *            g_io_extension_get_name     (GIOExtension *extension);
+gint                    g_io_extension_get_priority (GIOExtension *extension);
+GTypeClass*             g_io_extension_ref_class    (GIOExtension *extension);
 
 /* API for the modules to implement */
 /**
index af2bc61..bd59af5 100644 (file)
@@ -202,52 +202,27 @@ mounts_changed (GUnixMountMonitor *mount_monitor,
     }
 }
 
-static gint
-_compare_monitor_type_by_prio (gconstpointer _a,
-                              gconstpointer _b,
-                              gpointer      user_data)
-{
-  const GType *a = _a, *b = _b;
-  int prio_a, prio_b;
-  gint ret;
-  GQuark private_q;
-
-  private_q = g_quark_from_static_string ("gio-prio");
-
-  prio_a = GPOINTER_TO_INT (g_type_get_qdata (*a, private_q));
-  prio_b = GPOINTER_TO_INT (g_type_get_qdata (*b, private_q));
-
-  ret = prio_b - prio_a;
-
-  return ret;
-}
-
 static gpointer
 get_default_local_directory_monitor (gpointer data)
 {
-  GType *monitor_impls;
-  guint n_monitor_impls;
-  gint i;
   GLocalDirectoryMonitorClass *chosen_class;
   GLocalDirectoryMonitorClass **ret = data;
+  GIOExtensionPoint *ep;
+  GList *extensions, *l;
 
   _g_io_modules_ensure_loaded ();
-  
-  monitor_impls = g_type_children (G_TYPE_LOCAL_DIRECTORY_MONITOR,
-                                   &n_monitor_impls);
 
-  g_qsort_with_data (monitor_impls,
-                     n_monitor_impls,
-                     sizeof (GType),
-                     _compare_monitor_type_by_prio,
-                     NULL);
+  ep = g_io_extension_point_lookup (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME);
 
+  extensions = g_io_extension_point_get_extensions (ep);
+  
   chosen_class = NULL;
-  for (i = 0; i < n_monitor_impls; i++)
-    {    
+  for (l = extensions; l != NULL; l = l->next)
+    {
+      GIOExtension *extension = l->data;
       GLocalDirectoryMonitorClass *klass;
       
-      klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
+      klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_io_extension_ref_class (extension));
       
       if (klass->is_supported ())
        {
@@ -257,8 +232,6 @@ get_default_local_directory_monitor (gpointer data)
       else
        g_type_class_unref (klass);
     }
-
-  g_free (monitor_impls);
   
   if (chosen_class)
     {
index 40923e6..c40e5ef 100644 (file)
@@ -36,6 +36,8 @@ G_BEGIN_DECLS
 #define G_IS_LOCAL_DIRECTORY_MONITOR(o)                (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_DIRECTORY_MONITOR))
 #define G_IS_LOCAL_DIRECTORY_MONITOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_DIRECTORY_MONITOR))
 
+#define G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME "gio-local-directory-monitor"
+
 typedef struct _GLocalDirectoryMonitor      GLocalDirectoryMonitor;
 typedef struct _GLocalDirectoryMonitorClass GLocalDirectoryMonitorClass;
 
@@ -50,8 +52,6 @@ struct _GLocalDirectoryMonitor
 
 struct _GLocalDirectoryMonitorClass {
   GFileMonitorClass parent_class;
-  gint prio;
-  char *name; /* Not used atm */
   gboolean mount_notify;
   gboolean (*is_supported) (void);
 };
index 252b9d0..d9517bc 100644 (file)
@@ -129,52 +129,27 @@ static void g_local_file_monitor_class_init (GLocalFileMonitorClass *klass)
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
 }
 
-static gint
-_compare_monitor_type_by_prio (gconstpointer _a,
-                              gconstpointer _b,
-                              gpointer      user_data)
-{
-  const GType *a = _a, *b = _b;
-  int prio_a, prio_b;
-  gint ret;
-  GQuark private_q;
-
-  private_q = g_quark_from_static_string ("gio-prio");
-
-  prio_a = GPOINTER_TO_INT (g_type_get_qdata (*a, private_q));
-  prio_b = GPOINTER_TO_INT (g_type_get_qdata (*b, private_q));
-
-  ret = prio_b - prio_a;
-
-  return ret;
-}
-
 static gpointer
 get_default_local_file_monitor (gpointer data)
 {
-  GType *monitor_impls;
-  guint n_monitor_impls;
-  gint i;
   GLocalFileMonitorClass *chosen_class;
   GLocalFileMonitorClass **ret = data;
+  GIOExtensionPoint *ep;
+  GList *extensions, *l;
 
   _g_io_modules_ensure_loaded ();
-  
-  monitor_impls = g_type_children (G_TYPE_LOCAL_FILE_MONITOR,
-                                   &n_monitor_impls);
 
-  g_qsort_with_data (monitor_impls,
-                     n_monitor_impls,
-                     sizeof (GType),
-                     _compare_monitor_type_by_prio,
-                     NULL);
+  ep = g_io_extension_point_lookup (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME);
 
+  extensions = g_io_extension_point_get_extensions (ep);
+  
   chosen_class = NULL;
-  for (i = 0; i < n_monitor_impls; i++)
-    {    
+  for (l = extensions; l != NULL; l = l->next)
+    {
+      GIOExtension *extension = l->data;
       GLocalFileMonitorClass *klass;
       
-      klass = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
+      klass = G_LOCAL_FILE_MONITOR_CLASS (g_io_extension_ref_class (extension));
       
       if (klass->is_supported ())
        {
@@ -184,8 +159,6 @@ get_default_local_file_monitor (gpointer data)
       else
        g_type_class_unref (klass);
     }
-
-  g_free (monitor_impls);
   
   if (chosen_class)
     {
index 658310d..81a38a3 100644 (file)
@@ -34,6 +34,8 @@ G_BEGIN_DECLS
 #define G_IS_LOCAL_FILE_MONITOR(o)             (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_MONITOR))
 #define G_IS_LOCAL_FILE_MONITOR_CLASS(k)       (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_MONITOR))
 
+#define G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME "gio-local-file-monitor"
+
 typedef struct _GLocalFileMonitor      GLocalFileMonitor;
 typedef struct _GLocalFileMonitorClass GLocalFileMonitorClass;
 
@@ -45,8 +47,6 @@ struct _GLocalFileMonitor
 
 struct _GLocalFileMonitorClass {
   GFileMonitorClass parent_class;
-  gint prio;
-  char *name; /* Not used atm */
   gboolean (*is_supported) (void);
 };
 
index f679e74..c4407b8 100644 (file)
@@ -12,6 +12,8 @@ G_BEGIN_DECLS
 #define G_IS_NATIVE_VOLUME_MONITOR(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_NATIVE_VOLUME_MONITOR))
 #define G_IS_NATIVE_VOLUME_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_NATIVE_VOLUME_MONITOR))
 
+#define G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME "gio-native-volume-monitor"
+
 typedef struct _GNativeVolumeMonitor GNativeVolumeMonitor;
 typedef struct _GNativeVolumeMonitorClass GNativeVolumeMonitorClass;
 
index d6cecee..73acc83 100644 (file)
@@ -390,54 +390,14 @@ g_union_volume_monitor_remove_monitor (GUnionVolumeMonitor *union_monitor,
   g_signal_handlers_disconnect_by_func (child_monitor, child_drive_changed, union_monitor);
 }
 
-/* Note: This compares in reverse order.
-   Higher prio -> sort first
- */
-static gint
-compare_monitor_type (gconstpointer  a,
-                     gconstpointer  b,
-                     gpointer       user_data)
-{
-  GType a_type, b_type;
-  char *a_name, *b_name;
-  int a_prio, b_prio;
-  gint res;
-  const char *use_this_monitor;
-  GQuark private_q, name_q;
-
-  private_q = g_quark_from_static_string ("gio-prio");
-  name_q = g_quark_from_static_string ("gio-name");
-  
-  use_this_monitor = user_data;
-  a_type = *(GType *)a;
-  b_type = *(GType *)b;
-  a_prio = GPOINTER_TO_INT (g_type_get_qdata (a_type, private_q));
-  a_name = g_type_get_qdata (a_type, name_q);
-  b_prio = GPOINTER_TO_INT (g_type_get_qdata (b_type, private_q));
-  b_name = g_type_get_qdata (b_type, name_q);
-
-  if (a_type == b_type)
-    res = 0;
-  else if (use_this_monitor != NULL &&
-          strcmp (a_name, use_this_monitor) == 0)
-    res = -1;
-  else if (use_this_monitor != NULL &&
-          strcmp (b_name, use_this_monitor) == 0)
-    res = 1;
-  else 
-    res = b_prio - a_prio;
-  
-  return res;
-}
-
 static GType
 get_default_native_class (gpointer data)
 {
   GNativeVolumeMonitorClass *klass, *native_class, **native_class_out;
-  GType *monitors;
-  guint n_monitors;
   const char *use_this;
-  int i;
+  GIOExtensionPoint *ep;
+  GIOExtension *extension;
+  GList *l;
 
   native_class_out = data;
   
@@ -446,28 +406,37 @@ get_default_native_class (gpointer data)
   /* Ensure vfs in modules loaded */
   _g_io_modules_ensure_loaded ();
 
-  monitors = g_type_children (G_TYPE_NATIVE_VOLUME_MONITOR, &n_monitors);
-
-  g_qsort_with_data (monitors,
-                     n_monitors,
-                     sizeof (GType),
-                     compare_monitor_type,
-                     (gpointer)use_this);
+  ep = g_io_extension_point_lookup (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME);
 
   native_class = NULL;
-  for (i = 0; i < n_monitors; i++)
-    {    
-      klass = g_type_class_ref (monitors[i]);
-      if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
+  if (use_this)
+    {
+      extension = g_io_extension_point_get_extension_by_name (ep, use_this);
+      if (extension)
        {
-         native_class = klass;
-         break;
+         klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
+         if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
+           native_class = klass;
+         else
+           g_type_class_unref (klass);
        }
-      else
-       g_type_class_unref (klass);
     }
 
-  g_free (monitors);
+  if (native_class == NULL)
+    {
+      for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
+       {
+         extension = l->data;
+         klass = G_NATIVE_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
+         if (G_VOLUME_MONITOR_CLASS (klass)->is_supported())
+           {
+             native_class = klass;
+             break;
+           }
+         else
+           g_type_class_unref (klass);
+       }
+    }
  
   if (native_class)
     {
@@ -502,11 +471,11 @@ static void
 g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
 {
   GVolumeMonitor *monitor;
-  GType *monitors;
-  guint n_monitors;
   GNativeVolumeMonitorClass *native_class;
   GVolumeMonitorClass *klass;
-  int i;
+  GIOExtensionPoint *ep;
+  GIOExtension *extension;
+  GList *l;
 
   native_class = get_native_class ();
 
@@ -517,26 +486,21 @@ g_union_volume_monitor_init (GUnionVolumeMonitor *union_monitor)
       g_object_unref (monitor);
       g_type_class_unref (native_class);
     }
-  
-  monitors = g_type_children (G_TYPE_VOLUME_MONITOR, &n_monitors);
-  
-  for (i = 0; i < n_monitors; i++)
-    {
-      if (monitors[i] == G_TYPE_UNION_VOLUME_MONITOR ||
-         g_type_is_a (monitors[i], G_TYPE_NATIVE_VOLUME_MONITOR))
-       continue;
 
-      klass = g_type_class_ref (monitors[i]);
+  ep = g_io_extension_point_lookup (G_VOLUME_MONITOR_EXTENSION_POINT_NAME);
+  for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
+    {
+      extension = l->data;
+      
+      klass = G_VOLUME_MONITOR_CLASS (g_io_extension_ref_class (extension));
       if (klass->is_supported == NULL || klass->is_supported())
        {
-         monitor = g_object_new (monitors[i], NULL);
+         monitor = g_object_new (g_io_extension_get_type (extension), NULL);
          g_union_volume_monitor_add_monitor (union_monitor, monitor);
          g_object_unref (monitor);
        }
       g_type_class_unref (klass);
     }
-      
-  g_free (monitors);
 }
 
 static GUnionVolumeMonitor *
index 69b8e36..fcd90fb 100644 (file)
@@ -57,7 +57,11 @@ static void update_volumes           (GUnixVolumeMonitor *monitor);
 static void update_mounts            (GUnixVolumeMonitor *monitor);
 
 #define g_unix_volume_monitor_get_type _g_unix_volume_monitor_get_type
-G_DEFINE_TYPE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR);
+G_DEFINE_TYPE_WITH_CODE (GUnixVolumeMonitor, g_unix_volume_monitor, G_TYPE_NATIVE_VOLUME_MONITOR,
+                         g_io_extension_point_implement (G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME,
+                                                        g_define_type_id,
+                                                        "unix",
+                                                        0));
 
 static void
 g_unix_volume_monitor_finalize (GObject *object)
@@ -168,8 +172,6 @@ g_unix_volume_monitor_class_init (GUnixVolumeMonitorClass *klass)
   monitor_class->get_mount_for_uuid = get_mount_for_uuid;
   monitor_class->is_supported = is_supported;
 
-  native_class->priority = 0;
-  native_class->name = "unix";
   native_class->get_mount_for_mount_path = get_mount_for_mount_path;
 }
 
index f61c619..67f0d38 100644 (file)
@@ -210,36 +210,48 @@ compare_vfs_type (gconstpointer  a,
 static gpointer
 get_default_vfs (gpointer arg)
 {
-  GType *vfs_impls;
-  int i;
-  guint n_vfs_impls;
   const char *use_this;
   GVfs *vfs;
+  GList *l;
+  GIOExtensionPoint *ep;
+  GIOExtension *extension;
+  
 
   use_this = g_getenv ("GIO_USE_VFS");
   
   /* Ensure vfs in modules loaded */
   _g_io_modules_ensure_loaded ();
 
-  vfs_impls = g_type_children (G_TYPE_VFS, &n_vfs_impls);
+  ep = g_io_extension_point_lookup (G_VFS_EXTENSION_POINT_NAME);
 
-  g_qsort_with_data (vfs_impls, n_vfs_impls, sizeof (GType),
-                    compare_vfs_type, (gpointer)use_this);
-  
-  for (i = 0; i < n_vfs_impls; i++)
+  if (use_this)
+    {
+      extension = g_io_extension_point_get_extension_by_name (ep, use_this);
+      if (extension)
+       {
+         vfs = g_object_new (g_io_extension_get_type (extension), NULL);
+         
+         if (g_vfs_is_active (vfs))
+           return vfs;
+         
+         g_object_unref (vfs);
+       }
+    }
+
+  for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
     {
-      vfs = g_object_new (vfs_impls[i], NULL);
+      extension = l->data;
+
+      vfs = g_object_new (g_io_extension_get_type (extension), NULL);
 
       if (g_vfs_is_active (vfs))
-       break;
+       return vfs;
 
       g_object_unref (vfs);
-      vfs = NULL;
     }
   
-  g_free (vfs_impls);
 
-  return vfs;
+  return NULL;
 }
 
 /**
index 9400c6f..484b386 100644 (file)
@@ -39,6 +39,8 @@ G_BEGIN_DECLS
 #define G_IS_VFS(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VFS))
 #define G_IS_VFS_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VFS))
 
+#define G_VFS_EXTENSION_POINT_NAME "gio-vfs"
+
 /**
  * GVfs:
  * 
index 45fb6b7..bfc21b8 100644 (file)
@@ -42,6 +42,8 @@ G_BEGIN_DECLS
 #define G_IS_VOLUME_MONITOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VOLUME_MONITOR))
 #define G_IS_VOLUME_MONITOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VOLUME_MONITOR))
 
+#define G_VOLUME_MONITOR_EXTENSION_POINT_NAME "gio-volume-monitor"
+
 /**
  * GVolumeMonitor:
  * @parent_instance: The parent instance.
index eb90534..945db29 100644 (file)
@@ -42,7 +42,11 @@ struct _GInotifyDirectoryMonitor
 static gboolean g_inotify_directory_monitor_cancel (GFileMonitor* monitor);
 
 #define g_inotify_directory_monitor_get_type _g_inotify_directory_monitor_get_type
-G_DEFINE_TYPE (GInotifyDirectoryMonitor, g_inotify_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR)
+G_DEFINE_TYPE_WITH_CODE (GInotifyDirectoryMonitor, g_inotify_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR,
+                        g_io_extension_point_implement (G_LOCAL_DIRECTORY_MONITOR_EXTENSION_POINT_NAME,
+                                                        g_define_type_id,
+                                                        "inotify",
+                                                        20))
 
 static void
 g_inotify_directory_monitor_finalize (GObject *object)
@@ -63,8 +67,8 @@ g_inotify_directory_monitor_finalize (GObject *object)
 
 static GObject *
 g_inotify_directory_monitor_constructor (GType type,
-                                    guint n_construct_properties,
-                                    GObjectConstructParam *construct_properties)
+                                        guint n_construct_properties,
+                                        GObjectConstructParam *construct_properties)
 {
   GObject *obj;
   GInotifyDirectoryMonitorClass *klass;
@@ -116,7 +120,6 @@ g_inotify_directory_monitor_class_init (GInotifyDirectoryMonitorClass* klass)
   gobject_class->constructor = g_inotify_directory_monitor_constructor;
   directory_monitor_class->cancel = g_inotify_directory_monitor_cancel;
 
-  local_directory_monitor_class->prio = 20;
   local_directory_monitor_class->mount_notify = TRUE;
   local_directory_monitor_class->is_supported = g_inotify_directory_monitor_is_supported;
 }
index 7e460f2..eee3eb3 100644 (file)
@@ -44,7 +44,11 @@ struct _GInotifyFileMonitor
 static gboolean g_inotify_file_monitor_cancel (GFileMonitor* monitor);
 
 #define g_inotify_file_monitor_get_type _g_inotify_file_monitor_get_type
-G_DEFINE_TYPE (GInotifyFileMonitor, g_inotify_file_monitor, G_TYPE_LOCAL_FILE_MONITOR)
+G_DEFINE_TYPE_WITH_CODE (GInotifyFileMonitor, g_inotify_file_monitor, G_TYPE_LOCAL_FILE_MONITOR,
+                        g_io_extension_point_implement (G_LOCAL_FILE_MONITOR_EXTENSION_POINT_NAME,
+                                                        g_define_type_id,
+                                                        "inotify",
+                                                        20))
 
 static void
 g_inotify_file_monitor_finalize (GObject *object)
@@ -135,7 +139,6 @@ g_inotify_file_monitor_class_init (GInotifyFileMonitorClass* klass)
   gobject_class->constructor = g_inotify_file_monitor_constructor;
   file_monitor_class->cancel = g_inotify_file_monitor_cancel;
 
-  local_file_monitor_class->prio = 20;
   local_file_monitor_class->is_supported = g_inotify_file_monitor_is_supported;
 }