[pygobject] Simplify registration of custom types



commit e54c2d1df3812a1789ee240b0ba71ddf77c2f90a
Author: Daniel Drake <dsd laptop org>
Date:   Mon Mar 18 14:13:37 2013 -0600

    Simplify registration of custom types
    
    Use custom quark data to track Python created GTypes.
    
    Remove previous mechanism to track registration of python-implemented
    GTypes as it was unused (no custom registration was ever tracked).
    
    Leave vtable pointer and set to NULL to avoid an ABI break.
    
    Signed-off-by: Simon Feltman <sfeltman src gnome org>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=696143

 gi/_gobject/gobjectmodule.c     | 11 +++++--
 gi/_gobject/pygobject-private.h |  8 ++---
 gi/_gobject/pygobject.c         |  8 ++---
 gi/_gobject/pygobject.h         |  9 +++---
 gi/_gobject/pygtype.c           | 69 +++--------------------------------------
 5 files changed, 22 insertions(+), 83 deletions(-)
---
diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c
index ec91072..93d5abc 100644
--- a/gi/_gobject/gobjectmodule.c
+++ b/gi/_gobject/gobjectmodule.c
@@ -128,7 +128,7 @@ pyg_type_from_name (PyObject *self, PyObject *args)
 #endif
     if (!PyArg_ParseTuple(args, "s:gobject.type_from_name", &name))
        return NULL;
-    type = _pyg_type_from_name(name);
+    type = g_type_from_name(name);
     if (type != 0)
        return pyg_type_wrapper_new(type);
     repr = PyObject_Repr((PyObject*)self);
@@ -958,7 +958,7 @@ get_type_name_for_class(PyTypeObject *class)
        for (i = 0; type_name[i] != '\0'; i++)
            if (type_name[i] == '.')
                type_name[i] = '+';
-       if (_pyg_type_from_name(type_name) == 0)
+       if (g_type_from_name(type_name) == 0)
            break;              /* we now have a unique name */
        ++name_serial;
     }
@@ -1180,6 +1180,10 @@ pyg_type_register(PyTypeObject *class, const char *type_name)
     g_type_set_qdata(instance_type, g_quark_from_string("PyGObject::class"),
                     class);
 
+    /* Mark this GType as a custom python type */
+    g_type_set_qdata(instance_type, pygobject_custom_key,
+                     GINT_TO_POINTER (1));
+
     /* set new value of __gtype__ on class */
     gtype = pyg_type_wrapper_new(instance_type);
     PyObject_SetAttrString((PyObject *)class, "__gtype__", gtype);
@@ -2066,7 +2070,8 @@ struct _PyGObject_Functions pygobject_api_functions = {
   add_warning_redirection,
   disable_warning_redirections,
 
-  pyg_type_register_custom_callback,
+  NULL, /* previously type_register_custom */
+
   pyg_gerror_exception_check,
 
   pyglib_option_group_new,
diff --git a/gi/_gobject/pygobject-private.h b/gi/_gobject/pygobject-private.h
index e1fc2b6..5de7488 100644
--- a/gi/_gobject/pygobject-private.h
+++ b/gi/_gobject/pygobject-private.h
@@ -81,6 +81,7 @@ extern GQuark pygobject_wrapper_key;
 extern GQuark pygpointer_class_key;
 extern GQuark pygobject_has_updated_constructor_key;
 extern GQuark pygobject_instance_data_key;
+extern GQuark pygobject_custom_key;
 
 void     pygobject_data_free  (PyGObjectData *data);
 void     pyg_destroy_notify   (gpointer     user_data);
@@ -214,12 +215,7 @@ extern PyObject * pyg_enum_from_gtype (GType        gtype,
                                       int          value);
 
 /* pygtype.c */
-extern GHashTable *custom_type_registration;
-void pyg_type_register_custom_callback(const gchar *type_name,
-                                      PyGTypeRegistrationFunction callback,
-                                      gpointer data);
-PyTypeObject * pyg_type_get_custom(const gchar *name);
-GType _pyg_type_from_name(const gchar *name);
+extern gboolean pyg_gtype_is_custom (GType gtype);
 
 /* pygobject.c */
 extern PyTypeObject PyGObjectWeakRef_Type;
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 93b42ee..102041c 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -45,6 +45,7 @@ static void pygobject_inherit_slots(PyTypeObject *type, PyObject *bases,
 static void pygobject_find_slot_for(PyTypeObject *type, PyObject *bases, int slot_offset,
                                    gboolean check_for_present);
 GType PY_TYPE_OBJECT = 0;
+GQuark pygobject_custom_key;
 GQuark pygobject_class_key;
 GQuark pygobject_class_init_key;
 GQuark pygobject_wrapper_key;
@@ -149,8 +150,6 @@ pygobject_get_inst_data(PyGObject *self)
 }
 
 
-GHashTable *custom_type_registration = NULL;
-
 PyTypeObject *PyGObject_MetaType = NULL;
 
 /**
@@ -934,10 +933,6 @@ pygobject_lookup_class(GType gtype)
     if (gtype == G_TYPE_INTERFACE)
        return &PyGInterface_Type;
     
-    py_type = pyg_type_get_custom(g_type_name(gtype));
-    if (py_type)
-       return py_type;
-
     py_type = g_type_get_qdata(gtype, pygobject_class_key);
     if (py_type == NULL) {
        py_type = g_type_get_qdata(gtype, pyginterface_type_key);
@@ -2447,6 +2442,7 @@ pygobject_object_register_types(PyObject *d)
 {
     PyObject *o, *descr;
 
+    pygobject_custom_key = g_quark_from_static_string("PyGObject::custom");
     pygobject_class_key = g_quark_from_static_string("PyGObject::class");
     pygobject_class_init_key = g_quark_from_static_string("PyGObject::class-init");
     pygobject_wrapper_key = g_quark_from_static_string("PyGObject::wrapper");
diff --git a/gi/_gobject/pygobject.h b/gi/_gobject/pygobject.h
index 0ef77b9..3c5e384 100644
--- a/gi/_gobject/pygobject.h
+++ b/gi/_gobject/pygobject.h
@@ -183,9 +183,11 @@ struct _PyGObject_Functions {
     void      (*add_warning_redirection) (const char *domain,
                                           PyObject   *warning);
     void      (*disable_warning_redirections) (void);
-    void      (*type_register_custom)(const gchar *type_name,
-                                     PyGTypeRegistrationFunction callback,
-                                     gpointer data);
+
+    /* type_register_custom API now removed, but leave a pointer here to not
+     * break ABI. */
+    void      *_type_register_custom;
+
     gboolean  (*gerror_exception_check) (GError **error);
     PyObject* (*option_group_new) (GOptionGroup *group);
     GType (* type_from_object_strict) (PyObject *obj, gboolean strict);
@@ -252,7 +254,6 @@ struct _PyGObject_Functions *_PyGObject_API;
 #define pyg_register_interface_info (_PyGObject_API->register_interface_info)
 #define pyg_add_warning_redirection   (_PyGObject_API->add_warning_redirection)
 #define pyg_disable_warning_redirections (_PyGObject_API->disable_warning_redirections)
-#define pyg_type_register_custom_callback (_PyGObject_API->type_register_custom)
 #define pyg_gerror_exception_check (_PyGObject_API->gerror_exception_check)
 #define pyg_option_group_new       (_PyGObject_API->option_group_new)
 
diff --git a/gi/_gobject/pygtype.c b/gi/_gobject/pygtype.c
index 94014ff..498c35e 100644
--- a/gi/_gobject/pygtype.c
+++ b/gi/_gobject/pygtype.c
@@ -268,7 +268,7 @@ _wrap_g_type_from_name(PyGTypeWrapper *_, PyObject *args)
     if (!PyArg_ParseTuple(args, "s:GType.from_name", &type_name))
        return NULL;
 
-    type = _pyg_type_from_name(type_name);
+    type = g_type_from_name(type_name);
     if (type == 0) {
        PyErr_SetString(PyExc_RuntimeError, "unknown type name");
        return NULL;
@@ -401,7 +401,7 @@ pyg_type_from_object_strict(PyObject *obj, gboolean strict)
     if (PYGLIB_PyUnicode_Check(obj)) {
        gchar *name = PYGLIB_PyUnicode_AsString(obj);
 
-       type = _pyg_type_from_name(name);
+       type = g_type_from_name(name);
        if (type != 0) {
            return type;
        }
@@ -1820,69 +1820,10 @@ pyg_param_gvalue_as_pyobject(const GValue* gvalue,
     }
 }
 
-/**
- * pyg_type_registration_callback
- * @gtypename: type name
- * @callback: function to run
- *
- */
-typedef struct {
-    PyGTypeRegistrationFunction callback;
-    gpointer data;
-} CustomTypeData;
-
-void
-pyg_type_register_custom_callback(const gchar *typename,
-                                 PyGTypeRegistrationFunction callback,
-                                 gpointer user_data)
+gboolean
+pyg_gtype_is_custom(GType gtype)
 {
-    CustomTypeData *data;
-
-    if (!custom_type_registration)
-       custom_type_registration = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                         g_free, g_free);
-
-    data = g_new (CustomTypeData, 1);
-    data->callback = callback;
-    data->data = user_data;
-
-    g_hash_table_insert(custom_type_registration,
-                       g_strdup(typename),
-                       data);
-}
-
-PyTypeObject *
-pyg_type_get_custom(const gchar *name)
-{
-    CustomTypeData *data;
-    PyTypeObject *retval;
-
-    if (!custom_type_registration)
-       return NULL;
-
-    data = g_hash_table_lookup(custom_type_registration, name);
-    if (!data)
-       return NULL;
-
-    retval = data->callback(name, data->data);
-
-    g_hash_table_remove(custom_type_registration, name);
-
-    return retval;
-}
-
-GType
-_pyg_type_from_name(const gchar *name)
-{
-    GType type;
-
-    type = g_type_from_name(name);
-    if (type == G_TYPE_INVALID) {
-       pyg_type_get_custom(name);
-       type = g_type_from_name(name);
-    }
-
-    return type;
+    return g_type_get_qdata (gtype, pygobject_custom_key) != NULL;
 }
 
 static PyObject *


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