From ba482c66c3afc35f7fb3676eced9ab93d8cb1c01 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Fri, 9 Jan 2004 14:40:31 +0000 Subject: [PATCH] added convenience macros G_IMPLEMENT_INTERFACE() and G_DEFINE_TYPE() plus Fri Jan 9 15:34:15 2004 Tim Janik * gtype.h: added convenience macros G_IMPLEMENT_INTERFACE() and G_DEFINE_TYPE() plus variants. --- docs/reference/glib/tmpl/arrays_pointer.sgml | 10 +++ docs/reference/glib/tmpl/threads.sgml | 3 - docs/reference/gobject/tmpl/objects.sgml | 22 +++--- gobject/ChangeLog | 5 ++ gobject/gtype.h | 79 ++++++++++++++++++-- tests/module-test.c | 2 +- 6 files changed, 100 insertions(+), 21 deletions(-) diff --git a/docs/reference/glib/tmpl/arrays_pointer.sgml b/docs/reference/glib/tmpl/arrays_pointer.sgml index c67c253e4..cbf7ae46c 100644 --- a/docs/reference/glib/tmpl/arrays_pointer.sgml +++ b/docs/reference/glib/tmpl/arrays_pointer.sgml @@ -226,3 +226,13 @@ Frees all of the memory allocated for the pointer array. @Returns: + + + + + +@array: +@func: +@user_data: + + diff --git a/docs/reference/glib/tmpl/threads.sgml b/docs/reference/glib/tmpl/threads.sgml index 3d15d41b6..ab7107a47 100644 --- a/docs/reference/glib/tmpl/threads.sgml +++ b/docs/reference/glib/tmpl/threads.sgml @@ -1613,9 +1613,6 @@ Any one-time initialization function must have its own unique GOnce< struct. -@status: the status of the function controled by this struct -@retval: the return value of the function controled by this struct. This field will be - %NULL unless status == G_ONCE_STATUS_READY. @Since: 2.4 diff --git a/docs/reference/gobject/tmpl/objects.sgml b/docs/reference/gobject/tmpl/objects.sgml index 083ba009c..137b81a60 100644 --- a/docs/reference/gobject/tmpl/objects.sgml +++ b/docs/reference/gobject/tmpl/objects.sgml @@ -21,17 +21,6 @@ to the #GObject implementation and should never be accessed directly. - - -The notify signal is emitted on an object when one of its properties -has been changed. Note that getting this signal doesn't guarantee that the -value of the property has actually changed, it may also be emitted when -the setter for the property is called to reinstate the previous value. - - -@gobject: the object which received the signal. -@pspec: the #GParamSpec of the property which changed - The class structure for the GObject type. @@ -859,3 +848,14 @@ properties in set_property() and get_property() implementations. @pspec: the #GParamSpec of the property + + +The notify signal is emitted on an object when one of its properties +has been changed. Note that getting this signal doesn't guarantee that the +value of the property has actually changed, it may also be emitted when +the setter for the property is called to reinstate the previous value. + + +@gobject: the object which received the signal. +@pspec: the #GParamSpec of the property which changed + diff --git a/gobject/ChangeLog b/gobject/ChangeLog index 923434216..845c83992 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,8 @@ +Fri Jan 9 15:34:15 2004 Tim Janik + + * gtype.h: added convenience macros G_IMPLEMENT_INTERFACE() and + G_DEFINE_TYPE() plus variants. + Fri Dec 26 01:34:01 2003 Matthias Clasen * gtype.c (g_type_class_peek_parent): Don't acquire a read lock diff --git a/gobject/gtype.h b/gobject/gtype.h index d8536fc19..f79743a41 100644 --- a/gobject/gtype.h +++ b/gobject/gtype.h @@ -304,13 +304,47 @@ void g_type_add_interface_dynamic (GType instance_type, GTypePlugin *plugin); void g_type_interface_add_prerequisite (GType interface_type, GType prerequisite_type); -GType *g_type_interface_prerequisites (GType interface_type, - guint *n_prerequisites); +GType*g_type_interface_prerequisites (GType interface_type, + guint *n_prerequisites); +void g_type_class_add_private (gpointer g_class, + gsize private_size); +gpointer g_type_instance_get_private (GTypeInstance *instance, + GType private_type); + + +/* --- GType boilerplate --- */ +/* convenience macros for type implementations, which for a type GtkGadget will: + * - prototype: static void gtk_gadget_class_init (GtkGadgetClass *klass); + * - prototype: static void gtk_gadget_init (GtkGadget *self); + * - define: static gpointer parent_class = NULL; + * parent_class is initialized prior to calling gtk_gadget_class_init() + * - implement: GType gtk_gadget_get_type (void) { ... } + * - support custom code in gtk_gadget_get_type() after the type is registered. + * + * macro arguments: TypeName, type_name, TYPE_PARENT, CODE + * example: G_DEFINE_TYPE_WITH_CODE (GtkGadget, gtk_gadget, GTK_TYPE_WIDGET, + * g_print ("GtkGadget-id: %lu\n", g_define_type_id)); + */ +#define G_DEFINE_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_INTERNAL (TN, t_n, T_P, 0, parent_class, {}) +#define G_DEFINE_TYPE_WITH_CODE(TN, t_n, T_P, _C_) G_DEFINE_TYPE_INTERNAL (TN, t_n, T_P, 0, parent_class, _C_) +#define G_DEFINE_ABSTRACT_TYPE(TN, t_n, T_P) G_DEFINE_TYPE_INTERNAL (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT, parent_class, {}) +#define G_DEFINE_ABSTRACT_TYPE_WITH_CODE(TN, t_n, T_P, _C_) G_DEFINE_TYPE_INTERNAL (TN, t_n, T_P, G_TYPE_FLAG_ABSTRACT, parent_class, _C_) + +/* convenience macro to ease interface addition in the CODE + * section of G_DEFINE_TYPE_WITH_CODE() (this macro relies on + * the g_define_type_id present within G_DEFINE_TYPE_WITH_CODE()). + * usage example: + * G_DEFINE_TYPE_WITH_CODE (GtkTreeStore, gtk_tree_store, G_TYPE_OBJECT, + * G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, + * gtk_tree_store_tree_model_init)); + */ +#define G_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) { \ + static const GInterfaceInfo g_implement_interface_info = { \ + (GInterfaceInitFunc) iface_init \ + }; \ + g_type_add_interface_static (g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \ +} -void g_type_class_add_private (gpointer g_class, - gsize private_size); -gpointer g_type_instance_get_private (GTypeInstance *instance, - GType private_type); /* --- protected (for fundamental type implementations) --- */ GTypePlugin* g_type_get_plugin (GType type); @@ -359,6 +393,39 @@ G_CONST_RETURN gchar* g_type_name_from_class (GTypeClass *g_class); /* --- implementation bits --- */ +#define G_DEFINE_TYPE_INTERNAL(TypeName, type_name, TYPE_PARENT, flags, type_parent_class, CODE) \ +\ +static void type_name##_init (TypeName *self); \ +static void type_name##_class_init (TypeName##Class *klass); \ +static gpointer type_parent_class = NULL; \ +static void type_name##_class_intern_init (gpointer klass) \ +{ \ + type_parent_class = g_type_class_peek_parent (klass); \ + type_name##_class_init ((TypeName##Class*) klass); \ +} \ +\ +GType \ +type_name##_get_type (void) \ +{ \ + static GType g_define_type_id = 0; \ + if (G_UNLIKELY (g_define_type_id == 0)) \ + { \ + static const GTypeInfo g_define_type_info = { \ + sizeof (TypeName##Class), \ + (GBaseInitFunc) NULL, \ + (GBaseFinalizeFunc) NULL, \ + (GClassInitFunc) type_name##_class_intern_init, \ + (GClassFinalizeFunc) NULL, \ + NULL, /* class_data */ \ + sizeof (TypeName), \ + 0, /* n_preallocs */ \ + (GInstanceInitFunc) type_name##_init, \ + }; \ + g_define_type_id = g_type_register_static (TYPE_PARENT, #TypeName, &g_define_type_info, flags); \ + { CODE ; } \ + } \ + return g_define_type_id; \ +} #ifndef G_DISABLE_CAST_CHECKS # define _G_TYPE_CIC(ip, gt, ct) \ ((ct*) g_type_check_instance_cast ((GTypeInstance*) ip, gt)) diff --git a/tests/module-test.c b/tests/module-test.c index 7d9149e8b..9b95b0a2a 100644 --- a/tests/module-test.c +++ b/tests/module-test.c @@ -81,7 +81,7 @@ main (int arg, GModuleFunc gmod_f; if (!g_module_supported ()) - return 0; + g_error ("dynamic modules not supported"); dir = g_get_current_dir ();