mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 08:22:16 +01:00 
			
		
		
		
	added support for a "default vtable" per interface, that interface vtables
Tue Sep 2 19:37:21 2003 Tim Janik <timj@gtk.org> * gtype.[hc]: added support for a "default vtable" per interface, that interface vtables are initialized from. the default vtable is initialized and finalized through class_init, class_finalize and class_data from the interfaces GTypeInfo struct. (type_data_last_unref_Wm): unload child plugin before unreffing parent type. testifaceinit.c: minor fixups. fixed up base_init() assertions, since with a default vtable, base_init() may be called multiple times. added default initializer to iface1.
This commit is contained in:
		| @@ -154,7 +154,7 @@ Looks up a #GEnumValue by name. | |||||||
| @enum_class: a #GEnumClass | @enum_class: a #GEnumClass | ||||||
| @name: the name to look up | @name: the name to look up | ||||||
| @Returns: the #GEnumValue with name @name, or %NULL if the enumeration doesn' | @Returns: the #GEnumValue with name @name, or %NULL if the enumeration doesn' | ||||||
| t have a member with that name  | t have a member with that name | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_enum_get_value_by_nick ##### --> | <!-- ##### FUNCTION g_enum_get_value_by_nick ##### --> | ||||||
| @@ -165,7 +165,7 @@ Looks up a #GEnumValue by nickname. | |||||||
| @enum_class: a #GEnumClass | @enum_class: a #GEnumClass | ||||||
| @nick: the nickname to look up | @nick: the nickname to look up | ||||||
| @Returns: the #GEnumValue with nickname @nick, or %NULL if the enumeration doesn' | @Returns: the #GEnumValue with nickname @nick, or %NULL if the enumeration doesn' | ||||||
| t have a member with that nickname  | t have a member with that nickname | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_flags_get_first_value ##### --> | <!-- ##### FUNCTION g_flags_get_first_value ##### --> | ||||||
| @@ -174,7 +174,7 @@ Returns the first #GFlagsValue which is set in @value. | |||||||
| </para> | </para> | ||||||
|  |  | ||||||
| @flags_class: a #GFlagsClass | @flags_class: a #GFlagsClass | ||||||
| @value: the value  | @value: the value | ||||||
| @Returns: the first #GFlagsValue which is set in @value, or %NULL if none is set | @Returns: the first #GFlagsValue which is set in @value, or %NULL if none is set | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -186,7 +186,7 @@ Looks up a #GFlagsValue by name. | |||||||
| @flags_class: a #GFlagsClass | @flags_class: a #GFlagsClass | ||||||
| @name: the name to look up | @name: the name to look up | ||||||
| @Returns: the #GFlagsValue with name @name, or %NULL if there is no flag with | @Returns: the #GFlagsValue with name @name, or %NULL if there is no flag with | ||||||
| that name  | that name | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_flags_get_value_by_nick ##### --> | <!-- ##### FUNCTION g_flags_get_value_by_nick ##### --> | ||||||
| @@ -197,7 +197,7 @@ Looks up a #GFlagsValue by nickname. | |||||||
| @flags_class: a #GFlagsClass | @flags_class: a #GFlagsClass | ||||||
| @nick: the nickname to look up | @nick: the nickname to look up | ||||||
| @Returns: the #GFlagsValue with nickname @nick, or %NULL if there is no flag | @Returns: the #GFlagsValue with nickname @nick, or %NULL if there is no flag | ||||||
| with that nickname  | with that nickname | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_enum_register_static ##### --> | <!-- ##### FUNCTION g_enum_register_static ##### --> | ||||||
|   | |||||||
| @@ -473,6 +473,7 @@ class_init function with g_type_class_add_private(). | |||||||
| @g_type: the type identifying which private data to retrieve. | @g_type: the type identifying which private data to retrieve. | ||||||
| @c_type: The C type for the private structure. | @c_type: The C type for the private structure. | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### MACRO G_TYPE_CHECK_INSTANCE ##### --> | <!-- ##### MACRO G_TYPE_CHECK_INSTANCE ##### --> | ||||||
| <para> | <para> | ||||||
|  |  | ||||||
| @@ -746,6 +747,7 @@ my_object_get_some_field (MyObject *my_object) | |||||||
| @g_class: class structure for an instantiatable type | @g_class: class structure for an instantiatable type | ||||||
| @private_size: size of private structure. | @private_size: size of private structure. | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_type_interface_peek ##### --> | <!-- ##### FUNCTION g_type_interface_peek ##### --> | ||||||
| <para> | <para> | ||||||
| Returns the #GTypeInterface structure of an interface to which the passed in  | Returns the #GTypeInterface structure of an interface to which the passed in  | ||||||
| @@ -1469,3 +1471,6 @@ mode: sgml | |||||||
| sgml-parent-document: ("../gobject-docs.sgml" "book" "refsect2" "") | sgml-parent-document: ("../gobject-docs.sgml" "book" "refsect2" "") | ||||||
| End: | End: | ||||||
| --> | --> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -914,7 +914,7 @@ See g_param_spec_internal() for details on property names. | |||||||
| @name:          canonical name of the property specified | @name:          canonical name of the property specified | ||||||
| @nick:          nick name for the property specified | @nick:          nick name for the property specified | ||||||
| @blurb:         description of the property specified | @blurb:         description of the property specified | ||||||
| @enum_type:     a #GType derived from %G_TYPE_ENUM  | @enum_type:     a #GType derived from %G_TYPE_ENUM | ||||||
| @default_value: default value for the property specified | @default_value: default value for the property specified | ||||||
| @flags:         flags for the property specified | @flags:         flags for the property specified | ||||||
| @Returns:  a newly created parameter specification | @Returns:  a newly created parameter specification | ||||||
| @@ -979,7 +979,6 @@ properties. | |||||||
| @flags_class: the #GFlagsClass for the flags | @flags_class: the #GFlagsClass for the flags | ||||||
| @default_value:   default value for the property specified | @default_value:   default value for the property specified | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_param_spec_flags ##### --> | <!-- ##### FUNCTION g_param_spec_flags ##### --> | ||||||
| <para> | <para> | ||||||
| Creates a new #GParamSpecEnum instance specifying a %G_TYPE_FLAGS | Creates a new #GParamSpecEnum instance specifying a %G_TYPE_FLAGS | ||||||
| @@ -992,7 +991,7 @@ See g_param_spec_internal() for details on property names. | |||||||
| @name:          canonical name of the property specified | @name:          canonical name of the property specified | ||||||
| @nick:          nick name for the property specified | @nick:          nick name for the property specified | ||||||
| @blurb:         description of the property specified | @blurb:         description of the property specified | ||||||
| @flags_type:     a #GType derived from %G_TYPE_FLAGS  | @flags_type:     a #GType derived from %G_TYPE_FLAGS | ||||||
| @default_value: default value for the property specified | @default_value: default value for the property specified | ||||||
| @flags:         flags for the property specified | @flags:         flags for the property specified | ||||||
| @Returns:  a newly created parameter specification | @Returns:  a newly created parameter specification | ||||||
| @@ -1110,8 +1109,8 @@ This is an internal function introduced mainly for C marshallers. | |||||||
|  |  | ||||||
| @value:   a valid #GValue of type %G_TYPE_STRING | @value:   a valid #GValue of type %G_TYPE_STRING | ||||||
| @v_string: duplicated unowned string to be set | @v_string: duplicated unowned string to be set | ||||||
|  | <!-- # Unused Parameters # --> | ||||||
| @value:  a valid #GValue  | @value:  a valid #GValue | ||||||
| @v_string: string to be set | @v_string: string to be set | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1172,7 +1171,6 @@ properties. | |||||||
|  |  | ||||||
| @parent_instance: private #GParamSpec portion | @parent_instance: private #GParamSpec portion | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_param_spec_param ##### --> | <!-- ##### FUNCTION g_param_spec_param ##### --> | ||||||
| <para> | <para> | ||||||
| Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM | Creates a new #GParamSpecParam instance specifying a %G_TYPE_PARAM | ||||||
| @@ -1186,9 +1184,10 @@ See g_param_spec_internal() for details on property names. | |||||||
| @nick:          nick name for the property specified | @nick:          nick name for the property specified | ||||||
| @blurb:         description of the property specified | @blurb:         description of the property specified | ||||||
| @param_type:    a #GType derived from %G_TYPE_PARAM | @param_type:    a #GType derived from %G_TYPE_PARAM | ||||||
| @default_value: default value for the property specified |  | ||||||
| @flags:         flags for the property specified | @flags:         flags for the property specified | ||||||
| @Returns:  a newly created parameter specification | @Returns:  a newly created parameter specification | ||||||
|  | <!-- # Unused Parameters # --> | ||||||
|  | @default_value: default value for the property specified | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_value_set_param ##### --> | <!-- ##### FUNCTION g_value_set_param ##### --> | ||||||
| @@ -1257,6 +1256,7 @@ The #GType of #GParamSpecBoxed. | |||||||
| </para> | </para> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### STRUCT GParamSpecBoxed ##### --> | <!-- ##### STRUCT GParamSpecBoxed ##### --> | ||||||
| <para> | <para> | ||||||
| A #GParamSpec derived structure that contains the meta data for boxed properties. | A #GParamSpec derived structure that contains the meta data for boxed properties. | ||||||
| @@ -1368,7 +1368,6 @@ A #GParamSpec derived structure that contains the meta data for pointer properti | |||||||
|  |  | ||||||
| @parent_instance: private #GParamSpec portion | @parent_instance: private #GParamSpec portion | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_param_spec_pointer ##### --> | <!-- ##### FUNCTION g_param_spec_pointer ##### --> | ||||||
| <para> | <para> | ||||||
| Creates a new #GParamSpecPoiner instance specifying a pointer property. | Creates a new #GParamSpecPoiner instance specifying a pointer property. | ||||||
| @@ -1440,7 +1439,6 @@ A #GParamSpec derived structure that contains the meta data for object propertie | |||||||
|  |  | ||||||
| @parent_instance: private #GParamSpec portion | @parent_instance: private #GParamSpec portion | ||||||
|  |  | ||||||
|  |  | ||||||
| <!-- ##### FUNCTION g_param_spec_object ##### --> | <!-- ##### FUNCTION g_param_spec_object ##### --> | ||||||
| <para> | <para> | ||||||
| Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT  | Creates a new #GParamSpecBoxed instance specifying a %G_TYPE_OBJECT  | ||||||
|   | |||||||
| @@ -1,3 +1,16 @@ | |||||||
|  | Tue Sep  2 19:37:21 2003  Tim Janik  <timj@gtk.org> | ||||||
|  |  | ||||||
|  | 	* gtype.[hc]: added support for a "default vtable" per interface, | ||||||
|  | 	that interface vtables are initialized from. | ||||||
|  | 	the default vtable is initialized and finalized through class_init, | ||||||
|  | 	class_finalize and class_data from the interfaces GTypeInfo struct. | ||||||
|  | 	(type_data_last_unref_Wm): unload child plugin before unreffing | ||||||
|  | 	parent type. | ||||||
|  |  | ||||||
|  | 	testifaceinit.c: minor fixups. fixed up base_init() assertions, since | ||||||
|  | 	with a default vtable, base_init() may be called multiple times. | ||||||
|  | 	added default initializer to iface1. | ||||||
|  |  | ||||||
| Tue Sep  2 14:53:41 2003  Tim Janik  <timj@gtk.org> | Tue Sep  2 14:53:41 2003  Tim Janik  <timj@gtk.org> | ||||||
|  |  | ||||||
| 	* gobject-query.c (main): fix iterating over fundamental types. | 	* gobject-query.c (main): fix iterating over fundamental types. | ||||||
|   | |||||||
| @@ -241,6 +241,10 @@ struct _IFaceData | |||||||
|   guint16            vtable_size; |   guint16            vtable_size; | ||||||
|   GBaseInitFunc      vtable_init_base; |   GBaseInitFunc      vtable_init_base; | ||||||
|   GBaseFinalizeFunc  vtable_finalize_base; |   GBaseFinalizeFunc  vtable_finalize_base; | ||||||
|  |   GClassInitFunc     dflt_init; | ||||||
|  |   GClassFinalizeFunc dflt_finalize; | ||||||
|  |   gconstpointer      dflt_data; | ||||||
|  |   gpointer           dflt_vtable; | ||||||
| }; | }; | ||||||
| struct _ClassData | struct _ClassData | ||||||
| { | { | ||||||
| @@ -736,9 +740,9 @@ check_type_info_I (TypeNode        *pnode, | |||||||
|       return FALSE; |       return FALSE; | ||||||
|     } |     } | ||||||
|   /* check class & interface members */ |   /* check class & interface members */ | ||||||
|   if (!(finfo->type_flags & G_TYPE_FLAG_CLASSED) && |   if (!((finfo->type_flags & G_TYPE_FLAG_CLASSED) || is_interface) && | ||||||
|       (info->class_init || info->class_finalize || info->class_data || |       (info->class_init || info->class_finalize || info->class_data || | ||||||
|        (!is_interface && (info->class_size || info->base_init || info->base_finalize)))) |        info->class_size || info->base_init || info->base_finalize)) | ||||||
|     { |     { | ||||||
|       if (pnode) |       if (pnode) | ||||||
| 	g_warning ("cannot create class for `%s', derived from non-classed parent type `%s'", | 	g_warning ("cannot create class for `%s', derived from non-classed parent type `%s'", | ||||||
| @@ -985,6 +989,10 @@ type_data_make_W (TypeNode              *node, | |||||||
|       data->iface.vtable_size = info->class_size; |       data->iface.vtable_size = info->class_size; | ||||||
|       data->iface.vtable_init_base = info->base_init; |       data->iface.vtable_init_base = info->base_init; | ||||||
|       data->iface.vtable_finalize_base = info->base_finalize; |       data->iface.vtable_finalize_base = info->base_finalize; | ||||||
|  |       data->iface.dflt_init = info->class_init; | ||||||
|  |       data->iface.dflt_finalize = info->class_finalize; | ||||||
|  |       data->iface.dflt_data = info->class_data; | ||||||
|  |       data->iface.dflt_vtable = NULL; | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
| @@ -1581,6 +1589,31 @@ g_type_free_instance (GTypeInstance *instance) | |||||||
|   g_type_class_unref (class); |   g_type_class_unref (class); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | type_iface_ensure_dflt_vtable_Wm (TypeNode *iface) | ||||||
|  | { | ||||||
|  |   g_assert (iface->data); | ||||||
|  |  | ||||||
|  |   if (!iface->data->iface.dflt_vtable) | ||||||
|  |     { | ||||||
|  |       GTypeInterface *vtable = g_malloc0 (iface->data->iface.vtable_size); | ||||||
|  |       iface->data->iface.dflt_vtable = vtable; | ||||||
|  |       vtable->g_type = NODE_TYPE (iface); | ||||||
|  |       vtable->g_instance_type = 0; | ||||||
|  |       if (iface->data->iface.vtable_init_base || | ||||||
|  |           iface->data->iface.dflt_init) | ||||||
|  |         { | ||||||
|  |           G_WRITE_UNLOCK (&type_rw_lock); | ||||||
|  |           if (iface->data->iface.vtable_init_base) | ||||||
|  |             iface->data->iface.vtable_init_base (vtable); | ||||||
|  |           if (iface->data->iface.dflt_init) | ||||||
|  |             iface->data->iface.dflt_init (vtable, (gpointer) iface->data->iface.dflt_data); | ||||||
|  |           G_WRITE_LOCK (&type_rw_lock); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* This is called to allocate and do the first part of initializing | /* This is called to allocate and do the first part of initializing | ||||||
|  * the interface vtable; type_iface_vtable_iface_init_Wm() does the remainder. |  * the interface vtable; type_iface_vtable_iface_init_Wm() does the remainder. | ||||||
|  * |  * | ||||||
| @@ -1593,7 +1626,7 @@ static gboolean | |||||||
| type_iface_vtable_base_init_Wm (TypeNode *iface, | type_iface_vtable_base_init_Wm (TypeNode *iface, | ||||||
| 				TypeNode *node) | 				TypeNode *node) | ||||||
| { | { | ||||||
|   IFaceEntry *entry = type_lookup_iface_entry_L (node, iface); |   IFaceEntry *entry; | ||||||
|   IFaceHolder *iholder; |   IFaceHolder *iholder; | ||||||
|   GTypeInterface *vtable = NULL; |   GTypeInterface *vtable = NULL; | ||||||
|   TypeNode *pnode; |   TypeNode *pnode; | ||||||
| @@ -1602,7 +1635,11 @@ type_iface_vtable_base_init_Wm (TypeNode *iface, | |||||||
|   iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), TRUE); |   iholder = type_iface_retrieve_holder_info_Wm (iface, NODE_TYPE (node), TRUE); | ||||||
|   if (!iholder) |   if (!iholder) | ||||||
|     return FALSE;	/* we don't modify write lock upon FALSE */ |     return FALSE;	/* we don't modify write lock upon FALSE */ | ||||||
|    |  | ||||||
|  |   type_iface_ensure_dflt_vtable_Wm (iface); | ||||||
|  |  | ||||||
|  |   entry = type_lookup_iface_entry_L (node, iface); | ||||||
|  |  | ||||||
|   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info); |   g_assert (iface->data && entry && entry->vtable == NULL && iholder && iholder->info); | ||||||
|    |    | ||||||
|   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); |   pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); | ||||||
| @@ -1614,7 +1651,7 @@ type_iface_vtable_base_init_Wm (TypeNode *iface, | |||||||
| 	vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size); | 	vtable = g_memdup (pentry->vtable, iface->data->iface.vtable_size); | ||||||
|     } |     } | ||||||
|   if (!vtable) |   if (!vtable) | ||||||
|     vtable = g_malloc0 (iface->data->iface.vtable_size); |     vtable = g_memdup (iface->data->iface.dflt_vtable, iface->data->iface.vtable_size); | ||||||
|   entry->vtable = vtable; |   entry->vtable = vtable; | ||||||
|   vtable->g_type = NODE_TYPE (iface); |   vtable->g_type = NODE_TYPE (iface); | ||||||
|   vtable->g_instance_type = NODE_TYPE (node); |   vtable->g_instance_type = NODE_TYPE (node); | ||||||
| @@ -1622,8 +1659,7 @@ type_iface_vtable_base_init_Wm (TypeNode *iface, | |||||||
|   if (iface->data->iface.vtable_init_base) |   if (iface->data->iface.vtable_init_base) | ||||||
|     { |     { | ||||||
|       G_WRITE_UNLOCK (&type_rw_lock); |       G_WRITE_UNLOCK (&type_rw_lock); | ||||||
|       if (iface->data->iface.vtable_init_base) |       iface->data->iface.vtable_init_base (vtable); | ||||||
| 	iface->data->iface.vtable_init_base (vtable); |  | ||||||
|       G_WRITE_LOCK (&type_rw_lock); |       G_WRITE_LOCK (&type_rw_lock); | ||||||
|     } |     } | ||||||
|   return TRUE;	/* initialized the vtable */ |   return TRUE;	/* initialized the vtable */ | ||||||
| @@ -1930,7 +1966,6 @@ type_data_finalize_class_U (TypeNode  *node, | |||||||
|     if (bnode->data->class.class_finalize_base) |     if (bnode->data->class.class_finalize_base) | ||||||
|       bnode->data->class.class_finalize_base (class); |       bnode->data->class.class_finalize_base (class); | ||||||
|    |    | ||||||
|   class->g_type = 0; |  | ||||||
|   g_free (cdata->class); |   g_free (cdata->class); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1999,22 +2034,37 @@ type_data_last_unref_Wm (GType    type, | |||||||
| 	  type_data_finalize_class_U (node, &tdata->class); | 	  type_data_finalize_class_U (node, &tdata->class); | ||||||
| 	  G_WRITE_LOCK (&type_rw_lock); | 	  G_WRITE_LOCK (&type_rw_lock); | ||||||
| 	} | 	} | ||||||
|  |       else if (NODE_IS_IFACE (node) && tdata->iface.dflt_vtable) | ||||||
|  |         { | ||||||
|  |           node->mutatable_check_cache = FALSE; | ||||||
|  |           node->data = NULL; | ||||||
|  |           if (tdata->iface.dflt_finalize || tdata->iface.vtable_finalize_base) | ||||||
|  |             { | ||||||
|  |               G_WRITE_UNLOCK (&type_rw_lock); | ||||||
|  |               if (tdata->iface.dflt_finalize) | ||||||
|  |                 tdata->iface.dflt_finalize (tdata->iface.dflt_vtable, (gpointer) tdata->iface.dflt_data); | ||||||
|  |               if (tdata->iface.vtable_finalize_base) | ||||||
|  |                 tdata->iface.vtable_finalize_base (tdata->iface.dflt_vtable); | ||||||
|  |               G_WRITE_LOCK (&type_rw_lock); | ||||||
|  |             } | ||||||
|  |           g_free (tdata->iface.dflt_vtable); | ||||||
|  |         } | ||||||
|       else |       else | ||||||
| 	{ |         { | ||||||
| 	  node->mutatable_check_cache = FALSE; |           node->mutatable_check_cache = FALSE; | ||||||
| 	  node->data = NULL; |           node->data = NULL; | ||||||
| 	} |         } | ||||||
|        |  | ||||||
|       /* freeing tdata->common.value_table and its contents is taking care of |       /* freeing tdata->common.value_table and its contents is taken care of | ||||||
|        * by allocating it in one chunk with tdata |        * by allocating it in one chunk with tdata | ||||||
|        */ |        */ | ||||||
|       g_free (tdata); |       g_free (tdata); | ||||||
|        |        | ||||||
|       if (ptype) |  | ||||||
| 	type_data_unref_Wm (lookup_type_node_I (ptype), FALSE); |  | ||||||
|       G_WRITE_UNLOCK (&type_rw_lock); |       G_WRITE_UNLOCK (&type_rw_lock); | ||||||
|       g_type_plugin_unuse (node->plugin); |       g_type_plugin_unuse (node->plugin); | ||||||
|       G_WRITE_LOCK (&type_rw_lock); |       G_WRITE_LOCK (&type_rw_lock); | ||||||
|  |       if (ptype) | ||||||
|  | 	type_data_unref_Wm (lookup_type_node_I (ptype), FALSE); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -234,7 +234,7 @@ struct _GTypeInfo | |||||||
|   GBaseInitFunc          base_init; |   GBaseInitFunc          base_init; | ||||||
|   GBaseFinalizeFunc      base_finalize; |   GBaseFinalizeFunc      base_finalize; | ||||||
|    |    | ||||||
|   /* classed types, instantiated types */ |   /* interface types, classed types, instantiated types */ | ||||||
|   GClassInitFunc         class_init; |   GClassInitFunc         class_init; | ||||||
|   GClassFinalizeFunc     class_finalize; |   GClassFinalizeFunc     class_finalize; | ||||||
|   gconstpointer          class_data; |   gconstpointer          class_data; | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ | |||||||
|  * The test defines 5 interfaces: |  * The test defines 5 interfaces: | ||||||
|  *  |  *  | ||||||
|  * - TestIface1 is added before the class is initialized |  * - TestIface1 is added before the class is initialized | ||||||
|  * - TestIface2 is added in base_object_baes_init() |  * - TestIface2 is added in base_object_base_init() | ||||||
|  * - TestIface3 is added in test_iface1_base_init() |  * - TestIface3 is added in test_iface1_base_init() | ||||||
|  * - TestIface4 is added in test_object_class_init() |  * - TestIface4 is added in test_object_class_init() | ||||||
|  * - TestIface5 is added in test_object_test_iface1_init() |  * - TestIface5 is added in test_object_test_iface1_init() | ||||||
| @@ -66,7 +66,7 @@ prefix ## _get_type (void)					\ | |||||||
|   return object_type;						\ |   return object_type;						\ | ||||||
| } | } | ||||||
|  |  | ||||||
| #define DEFINE_IFACE(name, prefix, base_init)			\ | #define DEFINE_IFACE(name, prefix, base_init, dflt_init)	\ | ||||||
| GType								\ | GType								\ | ||||||
| prefix ## _get_type (void)					\ | prefix ## _get_type (void)					\ | ||||||
| {								\ | {								\ | ||||||
| @@ -79,6 +79,7 @@ prefix ## _get_type (void)					\ | |||||||
| 	sizeof (name ## Class),					\ | 	sizeof (name ## Class),					\ | ||||||
| 	(GBaseInitFunc)	base_init,				\ | 	(GBaseInitFunc)	base_init,				\ | ||||||
| 	(GBaseFinalizeFunc) NULL,				\ | 	(GBaseFinalizeFunc) NULL,				\ | ||||||
|  | 	(GClassInitFunc) dflt_init,				\ | ||||||
|       };							\ |       };							\ | ||||||
| 								\ | 								\ | ||||||
|       iface_type = g_type_register_static (G_TYPE_INTERFACE,	\ |       iface_type = g_type_register_static (G_TYPE_INTERFACE,	\ | ||||||
| @@ -98,6 +99,7 @@ struct _TestIfaceClass | |||||||
|   GTypeInterface base_iface; |   GTypeInterface base_iface; | ||||||
|   guint val; |   guint val; | ||||||
|   guint base_val; |   guint base_val; | ||||||
|  |   guint default_val; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE1           (test_iface1_get_type ()) | #define TEST_TYPE_IFACE1           (test_iface1_get_type ()) | ||||||
| @@ -105,9 +107,10 @@ struct _TestIfaceClass | |||||||
| typedef struct _TestIface1      TestIface1; | typedef struct _TestIface1      TestIface1; | ||||||
| typedef struct _TestIfaceClass  TestIface1Class; | typedef struct _TestIfaceClass  TestIface1Class; | ||||||
|  |  | ||||||
| static void test_iface1_base_init (TestIface1Class *iface); | static void test_iface1_base_init    (TestIface1Class *iface); | ||||||
|  | static void test_iface1_default_init (TestIface1Class *iface, gpointer class_data); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface1, test_iface1, test_iface1_base_init) | static DEFINE_IFACE(TestIface1, test_iface1, test_iface1_base_init, test_iface1_default_init) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE2           (test_iface2_get_type ()) | #define TEST_TYPE_IFACE2           (test_iface2_get_type ()) | ||||||
| #define TEST_IFACE2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE2, TestIface2Class)) | #define TEST_IFACE2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE2, TestIface2Class)) | ||||||
| @@ -116,7 +119,7 @@ typedef struct _TestIfaceClass  TestIface2Class; | |||||||
|  |  | ||||||
| static void test_iface2_base_init (TestIface2Class *iface); | static void test_iface2_base_init (TestIface2Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface2, test_iface2, test_iface2_base_init) | static DEFINE_IFACE(TestIface2, test_iface2, test_iface2_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE3           (test_iface3_get_type ()) | #define TEST_TYPE_IFACE3           (test_iface3_get_type ()) | ||||||
| #define TEST_IFACE3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE3, TestIface3Class)) | #define TEST_IFACE3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE3, TestIface3Class)) | ||||||
| @@ -125,7 +128,7 @@ typedef struct _TestIfaceClass  TestIface3Class; | |||||||
|  |  | ||||||
| static void  test_iface3_base_init (TestIface3Class *iface); | static void  test_iface3_base_init (TestIface3Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface3, test_iface3, test_iface3_base_init) | static DEFINE_IFACE(TestIface3, test_iface3, test_iface3_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE4           (test_iface4_get_type ()) | #define TEST_TYPE_IFACE4           (test_iface4_get_type ()) | ||||||
| #define TEST_IFACE4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE4, TestIface4Class)) | #define TEST_IFACE4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE4, TestIface4Class)) | ||||||
| @@ -134,7 +137,7 @@ typedef struct _TestIfaceClass  TestIface4Class; | |||||||
|  |  | ||||||
| static void  test_iface4_base_init (TestIface4Class *iface); | static void  test_iface4_base_init (TestIface4Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface4, test_iface4, test_iface4_base_init) | static DEFINE_IFACE(TestIface4, test_iface4, test_iface4_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE5           (test_iface5_get_type ()) | #define TEST_TYPE_IFACE5           (test_iface5_get_type ()) | ||||||
| #define TEST_IFACE5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE5, TestIface5Class)) | #define TEST_IFACE5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE5, TestIface5Class)) | ||||||
| @@ -143,7 +146,7 @@ typedef struct _TestIfaceClass  TestIface5Class; | |||||||
|  |  | ||||||
| static void  test_iface5_base_init (TestIface5Class *iface); | static void  test_iface5_base_init (TestIface5Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface5, test_iface5, test_iface5_base_init) | static DEFINE_IFACE(TestIface5, test_iface5, test_iface5_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE6           (test_iface6_get_type ()) | #define TEST_TYPE_IFACE6           (test_iface6_get_type ()) | ||||||
| #define TEST_IFACE6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE6, TestIface6Class)) | #define TEST_IFACE6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE6, TestIface6Class)) | ||||||
| @@ -152,7 +155,7 @@ typedef struct _TestIfaceClass  TestIface6Class; | |||||||
|  |  | ||||||
| static void  test_iface6_base_init (TestIface6Class *iface); | static void  test_iface6_base_init (TestIface6Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface6, test_iface6, test_iface6_base_init) | static DEFINE_IFACE(TestIface6, test_iface6, test_iface6_base_init, NULL) | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * BaseObject, a parent class for TestObject |  * BaseObject, a parent class for TestObject | ||||||
| @@ -187,9 +190,20 @@ struct _TestObjectClass | |||||||
| }; | }; | ||||||
|  |  | ||||||
| #define TEST_CALLED_ONCE() G_STMT_START { \ | #define TEST_CALLED_ONCE() G_STMT_START { \ | ||||||
|   static gboolean called = FALSE;         \ |   static gboolean called = 0;           \ | ||||||
|   g_assert (!called);                     \ |   g_assert (!called);                   \ | ||||||
|   called = TRUE;                          \ |   called = TRUE;                        \ | ||||||
|  | } G_STMT_END | ||||||
|  |  | ||||||
|  | #define CHECK_IFACE_TWICE(iface) G_STMT_START {                                 \ | ||||||
|  |   static guint n_calls = 0;                                                     \ | ||||||
|  |   n_calls++;                                                                    \ | ||||||
|  |   g_assert (n_calls <= 2);                                                      \ | ||||||
|  |   g_assert (G_TYPE_IS_INTERFACE (((GTypeInterface*) iface)->g_type));           \ | ||||||
|  |   if (n_calls == 1)                                                             \ | ||||||
|  |     g_assert (((GTypeInterface*) iface)->g_instance_type == 0);                 \ | ||||||
|  |   else                                                                          \ | ||||||
|  |     g_assert (G_TYPE_IS_OBJECT (((GTypeInterface*) iface)->g_instance_type));   \ | ||||||
| } G_STMT_END | } G_STMT_END | ||||||
|  |  | ||||||
| #define ADD_IFACE(n)  G_STMT_START {				\ | #define ADD_IFACE(n)  G_STMT_START {				\ | ||||||
| @@ -219,12 +233,15 @@ static void | |||||||
| test_object_test_iface1_init (TestIface1Class *iface) | test_object_test_iface1_init (TestIface1Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   TEST_CALLED_ONCE(); | ||||||
|    |  | ||||||
|  |   g_assert (iface->default_val == 0x111111); | ||||||
|  |  | ||||||
|   iface->val = 0x10001; |   iface->val = 0x10001; | ||||||
|  |  | ||||||
|   ADD_IFACE(5); |   ADD_IFACE(5); | ||||||
|  |  | ||||||
|   iface1 = TRUE; |   iface1 = TRUE; | ||||||
|  |   g_print ("interface1 object initializer\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| @@ -278,21 +295,48 @@ test_object_test_iface6_init (TestIface6Class *iface) | |||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| test_iface1_base_init (TestIface1Class *iface) | test_iface1_default_init (TestIface1Class *iface, | ||||||
|  |                           gpointer         class_data) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   TEST_CALLED_ONCE(); | ||||||
|  |   g_assert (iface->base_iface.g_type == TEST_TYPE_IFACE1); | ||||||
|  |   g_assert (iface->base_iface.g_instance_type == 0); | ||||||
|  |   g_assert (iface->base_val == 0x110011); | ||||||
|  |   g_assert (iface->val == 0); | ||||||
|  |   g_assert (iface->default_val == 0); | ||||||
|  |   iface->default_val = 0x111111; | ||||||
|  |   g_print ("interface1 default initializer\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|   iface->base_val = 0x110011; | static void | ||||||
|    | test_iface1_base_init (TestIface1Class *iface) | ||||||
|   ADD_IFACE(3); | { | ||||||
|  |   static guint n_calls = 0; | ||||||
|  |   n_calls++; | ||||||
|  |   g_assert (n_calls <= 2); | ||||||
|  |  | ||||||
|  |   if (n_calls == 1) | ||||||
|  |     { | ||||||
|  |       iface->base_val = 0x110011; | ||||||
|  |       g_assert (iface->default_val == 0); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       g_assert (iface->base_val == 0x110011); | ||||||
|  |       g_assert (iface->default_val == 0x111111); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (n_calls == 1) | ||||||
|  |     ADD_IFACE(3); | ||||||
|    |    | ||||||
|   base1 = TRUE; |   base1 = TRUE; | ||||||
|  |   g_print ("interface1 base initializer\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| test_iface2_base_init (TestIface2Class *iface) | test_iface2_base_init (TestIface2Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x220022; |   iface->base_val = 0x220022; | ||||||
|    |    | ||||||
| @@ -302,7 +346,7 @@ test_iface2_base_init (TestIface2Class *iface) | |||||||
| static void | static void | ||||||
| test_iface3_base_init (TestIface3Class *iface) | test_iface3_base_init (TestIface3Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x330033; |   iface->base_val = 0x330033; | ||||||
|    |    | ||||||
| @@ -312,7 +356,7 @@ test_iface3_base_init (TestIface3Class *iface) | |||||||
| static void | static void | ||||||
| test_iface4_base_init (TestIface4Class *iface) | test_iface4_base_init (TestIface4Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x440044; |   iface->base_val = 0x440044; | ||||||
|  |  | ||||||
| @@ -322,7 +366,7 @@ test_iface4_base_init (TestIface4Class *iface) | |||||||
| static void | static void | ||||||
| test_iface5_base_init (TestIface5Class *iface) | test_iface5_base_init (TestIface5Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x550055; |   iface->base_val = 0x550055; | ||||||
|  |  | ||||||
| @@ -332,7 +376,7 @@ test_iface5_base_init (TestIface5Class *iface) | |||||||
| static void | static void | ||||||
| test_iface6_base_init (TestIface6Class *iface) | test_iface6_base_init (TestIface6Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x660066; |   iface->base_val = 0x660066; | ||||||
|    |    | ||||||
| @@ -424,5 +468,7 @@ main (int   argc, | |||||||
|   iface = TEST_IFACE6_GET_CLASS (object); |   iface = TEST_IFACE6_GET_CLASS (object); | ||||||
|   g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); |   g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); | ||||||
|  |  | ||||||
|  |   g_print ("testifaceinit: all done.\n"); | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ | |||||||
|  * The test defines 5 interfaces: |  * The test defines 5 interfaces: | ||||||
|  *  |  *  | ||||||
|  * - TestIface1 is added before the class is initialized |  * - TestIface1 is added before the class is initialized | ||||||
|  * - TestIface2 is added in base_object_baes_init() |  * - TestIface2 is added in base_object_base_init() | ||||||
|  * - TestIface3 is added in test_iface1_base_init() |  * - TestIface3 is added in test_iface1_base_init() | ||||||
|  * - TestIface4 is added in test_object_class_init() |  * - TestIface4 is added in test_object_class_init() | ||||||
|  * - TestIface5 is added in test_object_test_iface1_init() |  * - TestIface5 is added in test_object_test_iface1_init() | ||||||
| @@ -66,7 +66,7 @@ prefix ## _get_type (void)					\ | |||||||
|   return object_type;						\ |   return object_type;						\ | ||||||
| } | } | ||||||
|  |  | ||||||
| #define DEFINE_IFACE(name, prefix, base_init)			\ | #define DEFINE_IFACE(name, prefix, base_init, dflt_init)	\ | ||||||
| GType								\ | GType								\ | ||||||
| prefix ## _get_type (void)					\ | prefix ## _get_type (void)					\ | ||||||
| {								\ | {								\ | ||||||
| @@ -79,6 +79,7 @@ prefix ## _get_type (void)					\ | |||||||
| 	sizeof (name ## Class),					\ | 	sizeof (name ## Class),					\ | ||||||
| 	(GBaseInitFunc)	base_init,				\ | 	(GBaseInitFunc)	base_init,				\ | ||||||
| 	(GBaseFinalizeFunc) NULL,				\ | 	(GBaseFinalizeFunc) NULL,				\ | ||||||
|  | 	(GClassInitFunc) dflt_init,				\ | ||||||
|       };							\ |       };							\ | ||||||
| 								\ | 								\ | ||||||
|       iface_type = g_type_register_static (G_TYPE_INTERFACE,	\ |       iface_type = g_type_register_static (G_TYPE_INTERFACE,	\ | ||||||
| @@ -98,6 +99,7 @@ struct _TestIfaceClass | |||||||
|   GTypeInterface base_iface; |   GTypeInterface base_iface; | ||||||
|   guint val; |   guint val; | ||||||
|   guint base_val; |   guint base_val; | ||||||
|  |   guint default_val; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE1           (test_iface1_get_type ()) | #define TEST_TYPE_IFACE1           (test_iface1_get_type ()) | ||||||
| @@ -105,9 +107,10 @@ struct _TestIfaceClass | |||||||
| typedef struct _TestIface1      TestIface1; | typedef struct _TestIface1      TestIface1; | ||||||
| typedef struct _TestIfaceClass  TestIface1Class; | typedef struct _TestIfaceClass  TestIface1Class; | ||||||
|  |  | ||||||
| static void test_iface1_base_init (TestIface1Class *iface); | static void test_iface1_base_init    (TestIface1Class *iface); | ||||||
|  | static void test_iface1_default_init (TestIface1Class *iface, gpointer class_data); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface1, test_iface1, test_iface1_base_init) | static DEFINE_IFACE(TestIface1, test_iface1, test_iface1_base_init, test_iface1_default_init) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE2           (test_iface2_get_type ()) | #define TEST_TYPE_IFACE2           (test_iface2_get_type ()) | ||||||
| #define TEST_IFACE2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE2, TestIface2Class)) | #define TEST_IFACE2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE2, TestIface2Class)) | ||||||
| @@ -116,7 +119,7 @@ typedef struct _TestIfaceClass  TestIface2Class; | |||||||
|  |  | ||||||
| static void test_iface2_base_init (TestIface2Class *iface); | static void test_iface2_base_init (TestIface2Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface2, test_iface2, test_iface2_base_init) | static DEFINE_IFACE(TestIface2, test_iface2, test_iface2_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE3           (test_iface3_get_type ()) | #define TEST_TYPE_IFACE3           (test_iface3_get_type ()) | ||||||
| #define TEST_IFACE3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE3, TestIface3Class)) | #define TEST_IFACE3_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE3, TestIface3Class)) | ||||||
| @@ -125,7 +128,7 @@ typedef struct _TestIfaceClass  TestIface3Class; | |||||||
|  |  | ||||||
| static void  test_iface3_base_init (TestIface3Class *iface); | static void  test_iface3_base_init (TestIface3Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface3, test_iface3, test_iface3_base_init) | static DEFINE_IFACE(TestIface3, test_iface3, test_iface3_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE4           (test_iface4_get_type ()) | #define TEST_TYPE_IFACE4           (test_iface4_get_type ()) | ||||||
| #define TEST_IFACE4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE4, TestIface4Class)) | #define TEST_IFACE4_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE4, TestIface4Class)) | ||||||
| @@ -134,7 +137,7 @@ typedef struct _TestIfaceClass  TestIface4Class; | |||||||
|  |  | ||||||
| static void  test_iface4_base_init (TestIface4Class *iface); | static void  test_iface4_base_init (TestIface4Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface4, test_iface4, test_iface4_base_init) | static DEFINE_IFACE(TestIface4, test_iface4, test_iface4_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE5           (test_iface5_get_type ()) | #define TEST_TYPE_IFACE5           (test_iface5_get_type ()) | ||||||
| #define TEST_IFACE5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE5, TestIface5Class)) | #define TEST_IFACE5_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE5, TestIface5Class)) | ||||||
| @@ -143,7 +146,7 @@ typedef struct _TestIfaceClass  TestIface5Class; | |||||||
|  |  | ||||||
| static void  test_iface5_base_init (TestIface5Class *iface); | static void  test_iface5_base_init (TestIface5Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface5, test_iface5, test_iface5_base_init) | static DEFINE_IFACE(TestIface5, test_iface5, test_iface5_base_init, NULL) | ||||||
|  |  | ||||||
| #define TEST_TYPE_IFACE6           (test_iface6_get_type ()) | #define TEST_TYPE_IFACE6           (test_iface6_get_type ()) | ||||||
| #define TEST_IFACE6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE6, TestIface6Class)) | #define TEST_IFACE6_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), TEST_TYPE_IFACE6, TestIface6Class)) | ||||||
| @@ -152,7 +155,7 @@ typedef struct _TestIfaceClass  TestIface6Class; | |||||||
|  |  | ||||||
| static void  test_iface6_base_init (TestIface6Class *iface); | static void  test_iface6_base_init (TestIface6Class *iface); | ||||||
|  |  | ||||||
| static DEFINE_IFACE(TestIface6, test_iface6, test_iface6_base_init) | static DEFINE_IFACE(TestIface6, test_iface6, test_iface6_base_init, NULL) | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * BaseObject, a parent class for TestObject |  * BaseObject, a parent class for TestObject | ||||||
| @@ -187,9 +190,20 @@ struct _TestObjectClass | |||||||
| }; | }; | ||||||
|  |  | ||||||
| #define TEST_CALLED_ONCE() G_STMT_START { \ | #define TEST_CALLED_ONCE() G_STMT_START { \ | ||||||
|   static gboolean called = FALSE;         \ |   static gboolean called = 0;           \ | ||||||
|   g_assert (!called);                     \ |   g_assert (!called);                   \ | ||||||
|   called = TRUE;                          \ |   called = TRUE;                        \ | ||||||
|  | } G_STMT_END | ||||||
|  |  | ||||||
|  | #define CHECK_IFACE_TWICE(iface) G_STMT_START {                                 \ | ||||||
|  |   static guint n_calls = 0;                                                     \ | ||||||
|  |   n_calls++;                                                                    \ | ||||||
|  |   g_assert (n_calls <= 2);                                                      \ | ||||||
|  |   g_assert (G_TYPE_IS_INTERFACE (((GTypeInterface*) iface)->g_type));           \ | ||||||
|  |   if (n_calls == 1)                                                             \ | ||||||
|  |     g_assert (((GTypeInterface*) iface)->g_instance_type == 0);                 \ | ||||||
|  |   else                                                                          \ | ||||||
|  |     g_assert (G_TYPE_IS_OBJECT (((GTypeInterface*) iface)->g_instance_type));   \ | ||||||
| } G_STMT_END | } G_STMT_END | ||||||
|  |  | ||||||
| #define ADD_IFACE(n)  G_STMT_START {				\ | #define ADD_IFACE(n)  G_STMT_START {				\ | ||||||
| @@ -219,12 +233,15 @@ static void | |||||||
| test_object_test_iface1_init (TestIface1Class *iface) | test_object_test_iface1_init (TestIface1Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   TEST_CALLED_ONCE(); | ||||||
|    |  | ||||||
|  |   g_assert (iface->default_val == 0x111111); | ||||||
|  |  | ||||||
|   iface->val = 0x10001; |   iface->val = 0x10001; | ||||||
|  |  | ||||||
|   ADD_IFACE(5); |   ADD_IFACE(5); | ||||||
|  |  | ||||||
|   iface1 = TRUE; |   iface1 = TRUE; | ||||||
|  |   g_print ("interface1 object initializer\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| @@ -278,21 +295,48 @@ test_object_test_iface6_init (TestIface6Class *iface) | |||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| test_iface1_base_init (TestIface1Class *iface) | test_iface1_default_init (TestIface1Class *iface, | ||||||
|  |                           gpointer         class_data) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   TEST_CALLED_ONCE(); | ||||||
|  |   g_assert (iface->base_iface.g_type == TEST_TYPE_IFACE1); | ||||||
|  |   g_assert (iface->base_iface.g_instance_type == 0); | ||||||
|  |   g_assert (iface->base_val == 0x110011); | ||||||
|  |   g_assert (iface->val == 0); | ||||||
|  |   g_assert (iface->default_val == 0); | ||||||
|  |   iface->default_val = 0x111111; | ||||||
|  |   g_print ("interface1 default initializer\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|   iface->base_val = 0x110011; | static void | ||||||
|    | test_iface1_base_init (TestIface1Class *iface) | ||||||
|   ADD_IFACE(3); | { | ||||||
|  |   static guint n_calls = 0; | ||||||
|  |   n_calls++; | ||||||
|  |   g_assert (n_calls <= 2); | ||||||
|  |  | ||||||
|  |   if (n_calls == 1) | ||||||
|  |     { | ||||||
|  |       iface->base_val = 0x110011; | ||||||
|  |       g_assert (iface->default_val == 0); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       g_assert (iface->base_val == 0x110011); | ||||||
|  |       g_assert (iface->default_val == 0x111111); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (n_calls == 1) | ||||||
|  |     ADD_IFACE(3); | ||||||
|    |    | ||||||
|   base1 = TRUE; |   base1 = TRUE; | ||||||
|  |   g_print ("interface1 base initializer\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| test_iface2_base_init (TestIface2Class *iface) | test_iface2_base_init (TestIface2Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x220022; |   iface->base_val = 0x220022; | ||||||
|    |    | ||||||
| @@ -302,7 +346,7 @@ test_iface2_base_init (TestIface2Class *iface) | |||||||
| static void | static void | ||||||
| test_iface3_base_init (TestIface3Class *iface) | test_iface3_base_init (TestIface3Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x330033; |   iface->base_val = 0x330033; | ||||||
|    |    | ||||||
| @@ -312,7 +356,7 @@ test_iface3_base_init (TestIface3Class *iface) | |||||||
| static void | static void | ||||||
| test_iface4_base_init (TestIface4Class *iface) | test_iface4_base_init (TestIface4Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x440044; |   iface->base_val = 0x440044; | ||||||
|  |  | ||||||
| @@ -322,7 +366,7 @@ test_iface4_base_init (TestIface4Class *iface) | |||||||
| static void | static void | ||||||
| test_iface5_base_init (TestIface5Class *iface) | test_iface5_base_init (TestIface5Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x550055; |   iface->base_val = 0x550055; | ||||||
|  |  | ||||||
| @@ -332,7 +376,7 @@ test_iface5_base_init (TestIface5Class *iface) | |||||||
| static void | static void | ||||||
| test_iface6_base_init (TestIface6Class *iface) | test_iface6_base_init (TestIface6Class *iface) | ||||||
| { | { | ||||||
|   TEST_CALLED_ONCE(); |   CHECK_IFACE_TWICE (iface); | ||||||
|  |  | ||||||
|   iface->base_val = 0x660066; |   iface->base_val = 0x660066; | ||||||
|    |    | ||||||
| @@ -424,5 +468,7 @@ main (int   argc, | |||||||
|   iface = TEST_IFACE6_GET_CLASS (object); |   iface = TEST_IFACE6_GET_CLASS (object); | ||||||
|   g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); |   g_assert (iface && iface->val == 0x60006 && iface->base_val == 0x660066); | ||||||
|  |  | ||||||
|  |   g_print ("testifaceinit: all done.\n"); | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user