mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-09-27 17:52:58 +02:00
Define G_DEFINE_DYNAMIC_TYPE and and _EXTENDED variant. (#334437)
2006-12-29 Matthias Clasen <mclasen@redhat.com> * gtypemodule.h: Define G_DEFINE_DYNAMIC_TYPE and and _EXTENDED variant. (#334437)
This commit is contained in:
committed by
Matthias Clasen
parent
b1e4310d6f
commit
d7b7c44e40
@@ -1,3 +1,9 @@
|
|||||||
|
2006-12-29 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* tests/gobject/Makefile.am:
|
||||||
|
* tests/gobject/dynamictype.c: New test for dynamic type
|
||||||
|
registration macros.
|
||||||
|
|
||||||
Thu Dec 28 21:14:45 2006 Tim Janik <timj@imendio.com>
|
Thu Dec 28 21:14:45 2006 Tim Janik <timj@imendio.com>
|
||||||
|
|
||||||
* glib/gslice.c: removed pthread-dependant debugging bits, the code
|
* glib/gslice.c: removed pthread-dependant debugging bits, the code
|
||||||
|
@@ -1,3 +1,13 @@
|
|||||||
|
2006-12-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* gobject/tmpl/gtype.sgml: Updates
|
||||||
|
|
||||||
|
* gobject/tmpl/gtypemodule.sgml: Document dynamic type
|
||||||
|
registration macros.
|
||||||
|
|
||||||
|
* gobject/gobject-docs.sgml: Add "Since 2.14" index
|
||||||
|
* gobject/gobject-sections.txt: Add dynamic type macros
|
||||||
|
|
||||||
2006-12-28 Matthias Clasen <mclasen@redhat.com>
|
2006-12-28 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gobject/tmpl/objects.sgml: Clarify a detail about
|
* gobject/tmpl/objects.sgml: Clarify a detail about
|
||||||
|
@@ -145,5 +145,8 @@
|
|||||||
<index role="2.12">
|
<index role="2.12">
|
||||||
<title>Index of new symbols in 2.12</title>
|
<title>Index of new symbols in 2.12</title>
|
||||||
</index>
|
</index>
|
||||||
|
<index role="2.14">
|
||||||
|
<title>Index of new symbols in 2.14</title>
|
||||||
|
</index>
|
||||||
|
|
||||||
</book>
|
</book>
|
||||||
|
@@ -199,6 +199,10 @@ g_type_module_register_type
|
|||||||
g_type_module_add_interface
|
g_type_module_add_interface
|
||||||
g_type_module_register_enum
|
g_type_module_register_enum
|
||||||
g_type_module_register_flags
|
g_type_module_register_flags
|
||||||
|
|
||||||
|
G_DEFINE_DYNAMIC_TYPE
|
||||||
|
G_DEFINE_DYNAMIC_TYPE_EXTENDED
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
G_TYPE_MODULE
|
G_TYPE_MODULE
|
||||||
G_IS_TYPE_MODULE
|
G_IS_TYPE_MODULE
|
||||||
|
@@ -196,3 +196,96 @@ not be unloaded.
|
|||||||
members being 0.
|
members being 0.
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### MACRO G_DEFINE_DYNAMIC_TYPE ##### -->
|
||||||
|
<para>
|
||||||
|
A convenience macro for dynamic type implementations, which declares a
|
||||||
|
class initialization function, an instance initialization function (see
|
||||||
|
#GTypeInfo for information about these) and a static variable named
|
||||||
|
@t_n<!-- -->_parent_class pointing to the parent class. Furthermore,
|
||||||
|
it defines a <function>*_get_type()</function> and a static
|
||||||
|
<function>*_register_type()</function> function for use in your
|
||||||
|
<function>module_init()</function>.
|
||||||
|
See G_DEFINE_DYNAMIC_TYPE_EXTENDED() for an example.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
@TN: The name of the new type, in Camel case.
|
||||||
|
@t_n: The name of the new type, in lowercase, with words
|
||||||
|
separated by '_'.
|
||||||
|
@T_P: The #GType of the parent type.
|
||||||
|
|
||||||
|
@Since: 2.14
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ##### MACRO G_DEFINE_DYNAMIC_TYPE_EXTENDED ##### -->
|
||||||
|
<para>
|
||||||
|
A more general version of G_DEFINE_DYNAMIC_TYPE() which
|
||||||
|
allows to specify #GTypeFlags and custom code.
|
||||||
|
</para>
|
||||||
|
<informalexample><programlisting>
|
||||||
|
G_DEFINE_DYNAMIC_TYPE_EXTENDED (GtkGadget,
|
||||||
|
gtk_gadget,
|
||||||
|
GTK_TYPE_THING,
|
||||||
|
0,
|
||||||
|
G_IMPLEMENT_INTERFACE (TYPE_GIZMO,
|
||||||
|
gtk_gadget_gizmo_init));
|
||||||
|
</programlisting>
|
||||||
|
expands to
|
||||||
|
<programlisting>
|
||||||
|
static void gtk_gadget_init (GtkGadget *self);
|
||||||
|
static void gtk_gadget_class_init (GtkGadgetClass *klass);
|
||||||
|
static void gtk_gadget_class_finalize (GtkGadgetClass *klass);
|
||||||
|
<!-- -->
|
||||||
|
static gpointer gtk_gadget_parent_class = NULL;
|
||||||
|
static GType gtk_gadget_type_id = 0;
|
||||||
|
<!-- -->
|
||||||
|
static void gtk_gadget_class_intern_init (gpointer klass)
|
||||||
|
{
|
||||||
|
gtk_gadget_parent_class = g_type_class_peek_parent (klass);
|
||||||
|
gtk_gadget_class_init ((GtkGadgetClass*) klass);
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
GType
|
||||||
|
gtk_gadget_get_type (void)
|
||||||
|
{
|
||||||
|
return gtk_gadget_type_id;
|
||||||
|
}
|
||||||
|
<!-- -->
|
||||||
|
static void
|
||||||
|
gtk_gadget_register_type (GTypeModule *type_module)
|
||||||
|
{
|
||||||
|
const GTypeInfo g_define_type_info = {
|
||||||
|
sizeof (GtkGadgetClass),
|
||||||
|
(GBaseInitFunc) NULL,
|
||||||
|
(GBaseFinalizeFunc) NULL,
|
||||||
|
(GClassInitFunc) gtk_gadget_class_intern_init,
|
||||||
|
(GClassFinalizeFunc) gtk_gadget_class_finalize,
|
||||||
|
NULL, /* class_data */
|
||||||
|
sizeof (GtkGadget),
|
||||||
|
0, /* n_preallocs */
|
||||||
|
(GInstanceInitFunc) gtk_gadget_init,
|
||||||
|
NULL /* value_table */
|
||||||
|
};
|
||||||
|
gtk_gadget_type_id = g_type_module_register_type (type_module,
|
||||||
|
GTK_TYPE_THING,
|
||||||
|
GtkGadget,
|
||||||
|
&g_define_type_info,
|
||||||
|
(GTypeFlags) flags);
|
||||||
|
{
|
||||||
|
const GInterfaceInfo g_implement_interface_info = {
|
||||||
|
(GInterfaceInitFunc) gtk_gadget_gizmo_init
|
||||||
|
};
|
||||||
|
g_type_add_interface_static (g_define_type_id, TYPE_GIZMO, &g_implement_interface_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</informalexample>
|
||||||
|
|
||||||
|
@TypeName: The name of the new type, in Camel case.
|
||||||
|
@type_name: The name of the new type, in lowercase, with words
|
||||||
|
separated by '_'.
|
||||||
|
@TYPE_PARENT: The #GType of the parent type.
|
||||||
|
@flags: #GTypeFlags to pass to g_type_register_static()
|
||||||
|
@CODE: Custom code that gets inserted in the *_get_type() function.
|
||||||
|
|
||||||
|
@Since: 2.14
|
||||||
|
|
||||||
|
@@ -1,3 +1,8 @@
|
|||||||
|
2006-12-29 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
|
* gtypemodule.h: Define G_DEFINE_DYNAMIC_TYPE and
|
||||||
|
and _EXTENDED variant. (#334437)
|
||||||
|
|
||||||
Fri Dec 15 2006 Matthias Clasen <mclasen@redhat.com>
|
Fri Dec 15 2006 Matthias Clasen <mclasen@redhat.com>
|
||||||
|
|
||||||
* gtype.c (instance_real_class_get): Dereference the pointer
|
* gtype.c (instance_real_class_get): Dereference the pointer
|
||||||
|
@@ -66,6 +66,47 @@ struct _GTypeModuleClass
|
|||||||
void (*reserved4) (void);
|
void (*reserved4) (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define G_DEFINE_DYNAMIC_TYPE(TN, t_n, T_P) G_DEFINE_DYNAMIC_TYPE_EXTENDED (TN, t_n, T_P, 0, {})
|
||||||
|
#define G_DEFINE_DYNAMIC_TYPE_EXTENDED(TypeName, type_name, TYPE_PARENT, flags, CODE) \
|
||||||
|
static void type_name##_init (TypeName *self); \
|
||||||
|
static void type_name##_class_init (TypeName##Class *klass); \
|
||||||
|
static void type_name##_class_finalize (TypeName##Class *klass); \
|
||||||
|
static gpointer type_name##_parent_class = NULL; \
|
||||||
|
static GType type_name##_type_id = 0; \
|
||||||
|
static void type_name##_class_intern_init (gpointer klass) \
|
||||||
|
{ \
|
||||||
|
type_name##_parent_class = g_type_class_peek_parent (klass); \
|
||||||
|
type_name##_class_init ((TypeName##Class*) klass); \
|
||||||
|
} \
|
||||||
|
GType \
|
||||||
|
type_name##_get_type (void) \
|
||||||
|
{ \
|
||||||
|
return type_name##_type_id; \
|
||||||
|
} \
|
||||||
|
static void \
|
||||||
|
type_name##_register_type (GTypeModule *type_module) \
|
||||||
|
{ \
|
||||||
|
const GTypeInfo g_define_type_info = { \
|
||||||
|
sizeof (TypeName##Class), \
|
||||||
|
(GBaseInitFunc) NULL, \
|
||||||
|
(GBaseFinalizeFunc) NULL, \
|
||||||
|
(GClassInitFunc) type_name##_class_intern_init, \
|
||||||
|
(GClassFinalizeFunc) type_name##_class_finalize, \
|
||||||
|
NULL, /* class_data */ \
|
||||||
|
sizeof (TypeName), \
|
||||||
|
0, /* n_preallocs */ \
|
||||||
|
(GInstanceInitFunc) type_name##_init, \
|
||||||
|
NULL /* value_table */ \
|
||||||
|
}; \
|
||||||
|
type_name##_type_id = g_type_module_register_type (type_module, \
|
||||||
|
TYPE_PARENT, \
|
||||||
|
#TypeName, \
|
||||||
|
&g_define_type_info, \
|
||||||
|
(GTypeFlags) flags); \
|
||||||
|
{ CODE ; } \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GType g_type_module_get_type (void) G_GNUC_CONST;
|
GType g_type_module_get_type (void) G_GNUC_CONST;
|
||||||
gboolean g_type_module_use (GTypeModule *module);
|
gboolean g_type_module_use (GTypeModule *module);
|
||||||
void g_type_module_unuse (GTypeModule *module);
|
void g_type_module_unuse (GTypeModule *module);
|
||||||
|
@@ -51,6 +51,7 @@ test_programs = \
|
|||||||
paramspec-test \
|
paramspec-test \
|
||||||
accumulator \
|
accumulator \
|
||||||
defaultiface \
|
defaultiface \
|
||||||
|
dynamictype \
|
||||||
ifacecheck \
|
ifacecheck \
|
||||||
ifaceinit \
|
ifaceinit \
|
||||||
ifaceinherit \
|
ifaceinherit \
|
||||||
|
130
tests/gobject/dynamictype.c
Normal file
130
tests/gobject/dynamictype.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/* GObject - GLib Type, Object, Parameter and Signal Library
|
||||||
|
* Copyright (C) 2001, 2003 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General
|
||||||
|
* Public License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#undef G_LOG_DOMAIN
|
||||||
|
#define G_LOG_DOMAIN "TestDynamicType"
|
||||||
|
|
||||||
|
#undef G_DISABLE_ASSERT
|
||||||
|
#undef G_DISABLE_CHECKS
|
||||||
|
#undef G_DISABLE_CAST_CHECKS
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#include "testcommon.h"
|
||||||
|
#include "testmodule.h"
|
||||||
|
|
||||||
|
/* This test tests the macros for defining dynamic types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static gboolean loaded = FALSE;
|
||||||
|
|
||||||
|
#define DYNAMIC_OBJECT_TYPE (dynamic_object_get_type ())
|
||||||
|
|
||||||
|
typedef GObject DynamicObject;
|
||||||
|
typedef struct _DynamicObjectClass DynamicObjectClass;
|
||||||
|
|
||||||
|
struct _DynamicObjectClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
guint val;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_DYNAMIC_TYPE(DynamicObject, dynamic_object, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static void
|
||||||
|
dynamic_object_class_init (DynamicObjectClass *class)
|
||||||
|
{
|
||||||
|
class->val = 42;
|
||||||
|
loaded = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dynamic_object_class_finalize (DynamicObjectClass *class)
|
||||||
|
{
|
||||||
|
loaded = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dynamic_object_init (DynamicObject *dynamic_object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
module_register (GTypeModule *module)
|
||||||
|
{
|
||||||
|
dynamic_object_register_type (module);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_dynamic_type (void)
|
||||||
|
{
|
||||||
|
GTypeModule *module;
|
||||||
|
DynamicObjectClass *class;
|
||||||
|
|
||||||
|
module = test_module_new (module_register);
|
||||||
|
|
||||||
|
/* Not loaded until we call ref for the first time */
|
||||||
|
class = g_type_class_peek (DYNAMIC_OBJECT_TYPE);
|
||||||
|
g_assert (class == NULL);
|
||||||
|
g_assert (!loaded);
|
||||||
|
|
||||||
|
/* Ref loads */
|
||||||
|
class = g_type_class_ref (DYNAMIC_OBJECT_TYPE);
|
||||||
|
g_assert (class && class->val == 42);
|
||||||
|
g_assert (loaded);
|
||||||
|
|
||||||
|
/* Peek then works */
|
||||||
|
class = g_type_class_peek (DYNAMIC_OBJECT_TYPE);
|
||||||
|
g_assert (class && class->val == 42);
|
||||||
|
g_assert (loaded);
|
||||||
|
|
||||||
|
/* Unref causes finalize */
|
||||||
|
g_type_class_unref (class);
|
||||||
|
|
||||||
|
/* Peek returns NULL */
|
||||||
|
class = g_type_class_peek (DYNAMIC_OBJECT_TYPE);
|
||||||
|
g_assert (!class);
|
||||||
|
g_assert (!loaded);
|
||||||
|
|
||||||
|
/* Ref reloads */
|
||||||
|
class = g_type_class_ref (DYNAMIC_OBJECT_TYPE);
|
||||||
|
g_assert (class && class->val == 42);
|
||||||
|
g_assert (loaded);
|
||||||
|
|
||||||
|
/* And Unref causes finalize once more*/
|
||||||
|
g_type_class_unref (class);
|
||||||
|
class = g_type_class_peek (DYNAMIC_OBJECT_TYPE);
|
||||||
|
g_assert (!class);
|
||||||
|
g_assert (!loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) |
|
||||||
|
G_LOG_LEVEL_WARNING |
|
||||||
|
G_LOG_LEVEL_CRITICAL);
|
||||||
|
g_type_init ();
|
||||||
|
|
||||||
|
test_dynamic_type ();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user