GObjectClass->constructor revised, g_object_newv_with_data



  I'd like to propose an API enhancement to GObject, in order to solve
pygtk bugs 161177 and 123891 in a way that doesn't involve some "hack".

  As people may or may not know, in PyGTK there is, for each GObject, a
corresponding "python wrapper" PyObject.  Normally, the PyObject is
create first, then __init__ is called, and this in turn calls the parent
__init__ which takes care of creating the GObject with g_object_newv.

  Now, in bug 123891 we'd like to solve the "construction properties"
problem.  The only place where we may set construction properties is, as
you may know, in the GObjectClass->constructor method.  Fine, let's
override GObject->constructor for PyGTK GObjects then.  But there's a
problem, here.  In the case described above, we already have a PyObject
for this GObject, and we need to "attach" the PyObject to the GObject
inside the construction, before setting any construction properties.
However, there is currently no way to pass the PyObject into the
constructor.  The idea of creating a special property to pass the data
into the constructor was mentioned, but this is an ugly hack we'd like
to avoid at all costs.

  Related to this is bug 161177, which aims to fix the problem of
creating custom python GObjects from a C g_object_new call.  For this to
work, we need to create the PyObject inside the GObject constructor.
And of course the constructor needs to "know" whether a PyObject already
exists or not.

  Another problem is that GObject->constructor currently does not allow
chaining to parent class in some situations.  For objects implemented in
C, we normally have something like:

static GtkBinClass *parent_class = NULL;

  This is fine in one-source-file-per-gobject case, since you can you
the global variable which is local to the type.  In case of pygtk, the
same C function has to be used for all types, and there is no way to
obtain the "parent class" from the constructor.

  The proposed solution involves possibly deprecating
GObjectClass->constructor, and adding a new
GObjectClass->constructor_full with more parameters, and adding a new
API g_object_newv_with_data to create GObjects while passing some data
to the constructor.

  Comments welcome.

PS: patch is in bug 305560

-- 
Gustavo J. A. M. Carneiro
<gjc inescporto pt> <gustavo users sourceforge net>
The universe is always one step beyond logic
? gobject/actual-abi
? gobject/expected-abi
Index: gobject/gobject.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.c,v
retrieving revision 1.67
diff -u -p -d -r1.67 gobject.c
--- gobject/gobject.c	5 May 2005 14:57:29 -0000	1.67
+++ gobject/gobject.c	28 May 2005 22:20:36 -0000
@@ -844,9 +844,10 @@ object_in_construction (GObject *object)
 }
 
 gpointer
-g_object_newv (GType       object_type,
-	       guint       n_parameters,
-	       GParameter *parameters)
+g_object_newv_with_data (GType        object_type,
+                         guint        n_parameters,
+                         GParameter  *parameters,
+                         GData      **datalist)
 {
   GObjectConstructParam *cparams, *oparams;
   GObjectNotifyQueue *nqueue;
@@ -946,7 +947,10 @@ g_object_newv (GType       object_type,
     }
 
   /* construct object from construction parameters */
-  object = class->constructor (object_type, n_total_cparams, cparams);
+  if (class->constructor_full)
+    object = class->constructor_full (object_type, object_type, n_total_cparams, cparams, datalist);
+  else
+    object = class->constructor (object_type, n_total_cparams, cparams);
   G_LOCK (construct_objects_lock);
   construct_objects = g_slist_remove (construct_objects, object);
   G_UNLOCK (construct_objects_lock);
@@ -973,6 +977,14 @@ g_object_newv (GType       object_type,
   g_object_notify_queue_thaw (object, nqueue);
   
   return object;
+}
+
+gpointer
+g_object_newv (GType       object_type,
+	       guint       n_parameters,
+	       GParameter *parameters)
+{
+  return g_object_newv_with_data (object_type, n_parameters, parameters, NULL);
 }
 
 GObject*
Index: gobject/gobject.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gobject.h,v
retrieving revision 1.31
diff -u -p -d -r1.31 gobject.h
--- gobject/gobject.h	5 May 2005 14:57:29 -0000	1.31
+++ gobject/gobject.h	28 May 2005 22:20:36 -0000
@@ -99,9 +99,16 @@ struct  _GObjectClass
   /* signals */
   void	     (*notify)			(GObject	*object,
 					 GParamSpec	*pspec);
+
+  GObject*   (*constructor_full) (GType                   this_type,
+                                  GType                   leaf_type,
+                                  guint                   n_construct_properties,
+                                  GObjectConstructParam  *construct_properties,
+                                  GData                 **datalist);
+
   /*< private >*/
   /* padding */
-  gpointer	pdummy[8];
+  gpointer	pdummy[7];
 };
 struct _GObjectConstructParam
 {
@@ -135,6 +142,10 @@ gpointer    g_object_new                
 gpointer    g_object_newv		      (GType           object_type,
 					       guint	       n_parameters,
 					       GParameter     *parameters);
+gpointer    g_object_newv_with_data           (GType           object_type,
+					       guint	       n_parameters,
+					       GParameter     *parameters,
+                                               GData         **datalist);
 GObject*    g_object_new_valist               (GType           object_type,
 					       const gchar    *first_property_name,
 					       va_list         var_args);


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