[glibmm/glibmm-2-20] Allow dynamic GType registration, using g_type_module_register_type().



commit 2714f9f8aa1a920a5410804d5d2f1c08e632a8ff
Author: Murray Cumming <murrayc murrayc com>
Date:   Mon Jun 22 10:57:07 2009 +0200

    Allow dynamic GType registration, using g_type_module_register_type().
    
    * glib/glibmm/class.[h|cc]: Added a  register_derived_type() overload that
    takes an extra GTypeModule* parameter, and which calls
    g_type_module_register_type() instead of g_type_register_static().
    * tools/m4/class_gobject.m4:
    * tools/m4/class_gtkobject.m4:
    * tools/m4/class_shared.m4: Added a _DYNAMIC_GTYPE_REGISTRATION macro to
    be used in the class in the hg file, to add a *_Class::init(GTypeModule)
    method, and a get_type(GTypeModule*) method that calls it.

 ChangeLog                   |   13 ++++++++++
 glib/glibmm/class.cc        |   12 +++++++++-
 glib/glibmm/class.h         |    7 +++++
 tools/m4/class_gobject.m4   |    5 ++++
 tools/m4/class_gtkobject.m4 |    5 ++++
 tools/m4/class_shared.m4    |   53 +++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 94 insertions(+), 1 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d8ca365..a661c87 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-06-19  Murray Cumming  <murrayc murrayc com>
+
+	Allow dynamic GType registration, using g_type_module_register_type().
+	
+	* glib/glibmm/class.[h|cc]: Added a  register_derived_type() overload that 
+	takes an extra GTypeModule* parameter, and which calls 
+	g_type_module_register_type() instead of g_type_register_static().
+	* tools/m4/class_gobject.m4:
+	* tools/m4/class_gtkobject.m4:
+	* tools/m4/class_shared.m4: Added a _DYNAMIC_GTYPE_REGISTRATION macro to 
+	be used in the class in the hg file, to add a *_Class::init(GTypeModule) 
+	method, and a get_type(GTypeModule*) method that calls it.
+
 2009-06-16 José Alburquerque <jaalburqu svn gnome org>
 
 	* tools/extra_defs_gen/generate_extra_defs.cc:
diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc
index 3127c69..af28517 100644
--- a/glib/glibmm/class.cc
+++ b/glib/glibmm/class.cc
@@ -29,6 +29,11 @@ namespace Glib
 
 void Class::register_derived_type(GType base_type)
 {
+  return register_derived_type(base_type, 0);
+}
+
+void Class::register_derived_type(GType base_type, GTypeModule* module)
+{
   if(gtype_)
     return; // already initialized
 
@@ -62,7 +67,12 @@ void Class::register_derived_type(GType base_type)
   }
 
   gchar* derived_name = g_strconcat("gtkmm__", base_query.type_name, NULL);
-  gtype_ = g_type_register_static(base_type, derived_name, &derived_info, GTypeFlags(0));
+  
+  if(module)
+    gtype_ = g_type_module_register_type(module, base_type, derived_name, &derived_info, GTypeFlags(0));
+  else
+    gtype_ = g_type_register_static(base_type, derived_name, &derived_info, GTypeFlags(0));
+
   g_free(derived_name);
 }
 
diff --git a/glib/glibmm/class.h b/glib/glibmm/class.h
index c961a76..2e7345d 100644
--- a/glib/glibmm/class.h
+++ b/glib/glibmm/class.h
@@ -57,8 +57,15 @@ protected:
   GType           gtype_;
   GClassInitFunc  class_init_func_;
 
+  /** Register a GType, derived from the @a base_type.
+   */
   void register_derived_type(GType base_type);
 
+  /** Register a GType, derived from the @a base_type.
+   * @param module If this is not 0 then g_type_module_register_type() will be used. Otherwise g_type_register_static() will be used.
+   */
+  void register_derived_type(GType base_type, GTypeModule* module);
+
 private:
   static void custom_class_init_function(void* g_class, void* class_data);
 };
diff --git a/tools/m4/class_gobject.m4 b/tools/m4/class_gobject.m4
index 50743d9..12cbec6 100644
--- a/tools/m4/class_gobject.m4
+++ b/tools/m4/class_gobject.m4
@@ -247,6 +247,11 @@ public:
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
   static GType get_type()      G_GNUC_CONST;
+
+ifdef(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',`
+  static GType get_type(GTypeModule* module)      G_GNUC_CONST;
+',`')
+
   static GType get_base_type() G_GNUC_CONST;
 #endif
 
diff --git a/tools/m4/class_gtkobject.m4 b/tools/m4/class_gtkobject.m4
index cbe9529..9c6e3e1 100644
--- a/tools/m4/class_gtkobject.m4
+++ b/tools/m4/class_gtkobject.m4
@@ -210,6 +210,11 @@ protected:
 public:
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
   static GType get_type()      G_GNUC_CONST;
+
+ifdef(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',`
+  static GType get_type(GTypeModule* module)      G_GNUC_CONST;
+',`')
+
   static GType get_base_type() G_GNUC_CONST;
 #endif
 
diff --git a/tools/m4/class_shared.m4 b/tools/m4/class_shared.m4
index 13f718c..a57ff7d 100644
--- a/tools/m4/class_shared.m4
+++ b/tools/m4/class_shared.m4
@@ -50,6 +50,17 @@ define(`__BOOL_DO_NOT_DERIVE_GTYPE__',`$1')
 _POP()
 ')
 
+dnl GVolumeMonitor can be broken/impeded by defining a sub-type.
+define(`_DYNAMIC_GTYPE_REGISTRATION',`dnl
+_PUSH()
+dnl Define this macro to be tested for later.
+define(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',`$1')
+_POP()
+')
+
+
+
+
 dnl
 dnl
 dnl
@@ -73,6 +84,10 @@ ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl
 
   const Glib::Class& init();
 
+ifdef(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',`
+  const Glib::Class& init(GTypeModule* module);
+',`')
+
 ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl
 ',`dnl
   static void class_init_function(void* g_class, void* class_data);
@@ -126,6 +141,35 @@ _IMPORT(SECTION_CC_IMPLEMENTS_INTERFACES)
 
   return *this;
 }
+
+ifdef(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',`
+const Glib::Class& __CPPNAME__`'_Class::init(GTypeModule* module)
+{
+  if(!gtype_) // create the GType if necessary
+  {
+ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl
+    // Do not derive a GType, or use a derived klass:
+    gtype_ = CppClassParent::CppObjectType::get_type();
+',`dnl
+    // Glib::Class has to know the class init function to clone custom types.
+    class_init_func_ = &__CPPNAME__`'_Class::class_init_function;
+
+    // This is actually just optimized away, apparently with no harm.
+    // Make sure that the parent type has been created.
+    //CppClassParent::CppObjectType::get_type();
+
+    // Create the wrapper type, with the same class/instance size as the base type.
+    register_derived_type(_LOWER(__CCAST__)_get_type(), module);
+
+    // Add derived versions of interfaces, if the C type implements any interfaces:
+_IMPORT(SECTION_CC_IMPLEMENTS_INTERFACES)
+')
+  }
+
+  return *this;
+}
+',`')
+
 ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl
 ',`dnl
 
@@ -166,6 +210,15 @@ GType __CPPNAME__::get_type()
   return __BASE__`'_class_.init().get_type();
 }
 
+ifdef(`__BOOL_DYNAMIC_GTYPE_REGISTRATION__',`
+GType __CPPNAME__::get_type(GTypeModule* module)
+{
+  return __BASE__`'_class_.init(module).get_type();
+}
+'dnl
+,`'dnl
+)
+
 GType __CPPNAME__::get_base_type()
 {
   return _LOWER(__CCAST__)_get_type();



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