diff options
author | Gustavo J. A. M. Carneiro <gjc@src.gnome.org> | 2005-01-09 14:49:57 +0000 |
---|---|---|
committer | Gustavo J. A. M. Carneiro <gjc@src.gnome.org> | 2005-01-09 14:49:57 +0000 |
commit | d953b545f6fa8f0e24b265044bc52ab5896702eb (patch) | |
tree | 0f49bc5dc293e8896c17cecb7033386a1364c8e9 | |
parent | b3ca96724b71162b93011736b2cca5f00802dae1 (diff) | |
download | pygobject-d953b545f6fa8f0e24b265044bc52ab5896702eb.tar.gz pygobject-d953b545f6fa8f0e24b265044bc52ab5896702eb.tar.xz pygobject-d953b545f6fa8f0e24b265044bc52ab5896702eb.zip |
#154974: Interface implementation support
-rw-r--r-- | gobject/gobjectmodule.c | 41 | ||||
-rw-r--r-- | gobject/pygobject.h | 2 |
2 files changed, 43 insertions, 0 deletions
diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c index bbd152e..5ed9d64 100644 --- a/gobject/gobjectmodule.c +++ b/gobject/gobjectmodule.c @@ -32,6 +32,9 @@ static const gchar *pyginterface_type_id = "PyGInterface::type"; GQuark pyginterface_type_key = 0; static const gchar *pygobject_class_init_id = "PyGObject::class-init"; GQuark pygobject_class_init_key = 0; +static const gchar *pyginterface_info_id = "PyGInterface::info"; +GQuark pyginterface_info_key = 0; + static void pyg_flags_add_constants(PyObject *module, GType flags_type, const gchar *strip_prefix); @@ -207,6 +210,18 @@ pyg_register_interface(PyObject *dict, const gchar *class_name, } +static void +pyg_register_interface_info(GType gtype, const GInterfaceInfo *info) +{ + g_type_set_qdata(gtype, pyginterface_info_key, (gpointer) info); +} + +static const GInterfaceInfo * +pyg_lookup_interface_info(GType gtype) +{ + return g_type_get_qdata(gtype, pyginterface_info_key); +} + /* -------------- GMainContext objects ---------------------------- */ @@ -1016,6 +1031,30 @@ pyg_type_register(PyObject *self, PyObject *args) return NULL; } g_type_class_unref(gclass); + + /* Register interface implementations */ + if (class->tp_bases) { + for (i = 0; i < PyTuple_GET_SIZE(class->tp_bases); ++i) + { + PyTypeObject *base = (PyTypeObject *) PyTuple_GET_ITEM(class->tp_bases, i); + GType itype; + const GInterfaceInfo *iinfo; + + if (PyObject_IsSubclass((PyObject *) base, + (PyObject *) &PyGInterface_Type) != 1) + continue; + itype = pyg_type_from_object((PyObject *) base); + iinfo = pyg_lookup_interface_info(itype); + if (!iinfo) { + PyErr_Format(PyExc_NotImplementedError, "Interface type %s " + "has no python implementation support", base->tp_name); + return NULL; + } + g_type_add_interface_static(instance_type, itype, iinfo); + } + } else + g_warning("type has no tp_bases"); + Py_INCREF(Py_None); return Py_None; } @@ -2110,6 +2149,7 @@ struct _PyGObject_Functions pygobject_api_functions = { pyg_gil_state_ensure_py23, pyg_gil_state_release_py23, pyg_register_class_init, + pyg_register_interface_info }; #define REGISTER_TYPE(d, type, name) \ @@ -2159,6 +2199,7 @@ initgobject(void) PyDict_SetItemString(PyGInterface_Type.tp_dict, "__gdoc__", pyg_object_descr_doc_get()); pyginterface_type_key = g_quark_from_static_string(pyginterface_type_id); + pyginterface_info_key = g_quark_from_static_string(pyginterface_info_id); pygobject_class_init_key = g_quark_from_static_string(pygobject_class_init_id); diff --git a/gobject/pygobject.h b/gobject/pygobject.h index ae399d1..22e488c 100644 --- a/gobject/pygobject.h +++ b/gobject/pygobject.h @@ -159,6 +159,7 @@ struct _PyGObject_Functions { int (*gil_state_ensure) (void); void (*gil_state_release) (int flag); void (*register_class_init) (GType gtype, PyGClassInitFunc class_init); + void (*register_interface_info) (GType gtype, const GInterfaceInfo *info); }; #ifndef _INSIDE_PYGOBJECT_ @@ -211,6 +212,7 @@ struct _PyGObject_Functions *_PyGObject_API; #define pyg_flags_from_gtype (_PyGObject_API->flags_from_gtype) #define pyg_enable_threads (_PyGObject_API->enable_threads) #define pyg_register_class_init (_PyGObject_API->register_class_init) +#define pyg_register_interface_info (_PyGObject_API->register_interface_info) #define pyg_block_threads() G_STMT_START { \ if (_PyGObject_API->block_threads != NULL) \ |