From 09f8e937f21552d441a5a2b06767a67459195653 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Sat, 24 Jun 2000 22:30:10 +0000 Subject: [PATCH] define gstring in terms of gchar*. this typedef reflects the type name of Fri Jun 23 17:20:26 2000 Tim Janik * glib.h: define gstring in terms of gchar*. this typedef reflects the type name of the primitive G_TYPE_STRING in the gobject module. Sat Jun 24 23:03:04 2000 Tim Janik * gtype.[hc]: provide G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN, G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_FLOAT, G_TYPE_DOUBLE and G_TYPE_STRING fundamental types. added a GTypeValueTable* pointer to GTypeInfo structure for types to implement GValue handling functions. GTypeValueTable contains the following members: value_init(): initialize a GValue structure. value_free(): free GValue structure contents (optional). value_copy(): copy one GValue contents to another GValue structure of collect_type: varargs collection type for the first variable argument to be collected by collect_value(). collect_value(): variable arguments collection function (optional). lcopy_type: varargs collection type for the first variable argument to be location copyied by lcopy_value(). lcopy_value(): variable arguments location copy function (optional). g_type_value_table_peek(): new function to retrive the GTypeValueTable* for a type node. ValueTables get inherited from parent types, unless overridden through the GTypeInfo structure. internally, GTypeValueTable support means an added overhead of one pointer per static or used dynamic type node. g_type_add_class_cache_func(): provide a cache_func/data pair to be called prior to a type nodes last_unref() function, this can be used to prevent premature class destruction. multiple installed cache_func() will be chained upon last_unref() untill one of them returns TRUE. the cache_func()s have to check the type id passed in to figure whether they actually wants to cache the class of this type (since any types are routed through the cache_func() chain). g_type_remove_class_cache_func(): remove a previously installed cache_func/data pair. the cache maintained by this function has to be clear when calling g_type_remove_class_cache_func() to avoid leaks. g_type_class_unref_uncached(): class unref function for cache_func() implementations, unreferences a class omitting the cache chain (and therefore unref->cache->unref->... loops). * gvaluetypes.[hc]: provide the value setters/getters for the primitive fundamental types boolean, char, uchar, int, uint, long, ulong, float, double and string. * gvalue.[hc]: provide G_TYPE_IS_VALUE() in terms of whether a GTypeValueTable is provided for this type. removed g_value_init_default(), g_value_validate(), g_value_defaults(), g_value_set_default() and g_values_cmp() as these are supplied by the GParamSpec API now. moved g_values_exchange() into the "implementation details" section, since it just provides the underlying functionality for g_value_convert(). * gvaluecollector.h: renamed the varargs value container from GParamCValue to GTypeCValue as the value collection methods are supplied by the type system now. G_PARAM_COLLECT_VALUE() and G_PARAM_LCOPY_VALUE() got renamed to G_VALUE_COLLECT() and G_VALUE_LCOPY() and operate without a GParamSpec structure now. * genums.h: macros cleanups/fixes. * genum.c: provide G_TYPE_ENUM and G_TYPE_FLAGS type and assorted g_value_{s|g}et_{enum|flags}() implementations. * gobject.[hc]: provide G_IS_VALUE_OBJECT(), G_TYPE_OBJECT ValueTable methods and g_value_{s|g}et_object(). * gparam.[hc]: reduced class to value_set_default(), value_validate() and values_cmp(). also parameters now need to fill in a GType value_type; field to indicate the GValue type they are handling. provide g_param_value_set_default(), g_param_value_defaults(), g_param_value_validate() and g_param_values_cmp(). * gparamspecs.[hc]: got rid of the g_value_* functions and the G_IS_VALUE_* macros. adapted param spec implementations according to the GParamSpecClass changes. --- ChangeLog | 5 + ChangeLog.pre-2-0 | 5 + ChangeLog.pre-2-10 | 5 + ChangeLog.pre-2-12 | 5 + ChangeLog.pre-2-2 | 5 + ChangeLog.pre-2-4 | 5 + ChangeLog.pre-2-6 | 5 + ChangeLog.pre-2-8 | 5 + glib-object.h | 1 + glib.h | 1 + glib/glib-object.h | 1 + glib/glib.h | 1 + gobject/ChangeLog | 76 +++ gobject/Makefile.am | 2 + gobject/genums.c | 112 ++++- gobject/genums.h | 29 +- gobject/gobject.c | 325 +++++++++---- gobject/gobject.h | 6 + gobject/gparam.c | 106 ++++- gobject/gparam.h | 51 +- gobject/gparamspecs.c | 1135 ++++++++++----------------------------------- gobject/gparamspecs.h | 91 +--- gobject/gtype.c | 342 ++++++++++---- gobject/gtype.h | 157 ++++--- gobject/gvalue.c | 268 ++++------- gobject/gvalue.h | 30 +- gobject/gvaluecollector.h | 66 +-- gobject/gvaluetypes.c | 588 +++++++++++++++++++++++ gobject/gvaluetypes.h | 86 ++++ 29 files changed, 1992 insertions(+), 1522 deletions(-) create mode 100644 gobject/gvaluetypes.c create mode 100644 gobject/gvaluetypes.h diff --git a/ChangeLog b/ChangeLog index 7626503..92a9f80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 7626503..92a9f80 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,8 @@ +Fri Jun 23 17:20:26 2000 Tim Janik + + * glib.h: define gstring in terms of gchar*. this typedef reflects + the type name of the primitive G_TYPE_STRING in the gobject module. + Wed Jun 21 12:09:03 2000 Owen Taylor * gunicode.h gutf8.c guniprop.c gunidecomp.[ch] gunichartables.h diff --git a/glib-object.h b/glib-object.h index 14f54ab..9336241 100644 --- a/glib-object.h +++ b/glib-object.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/glib.h b/glib.h index 952014e..7baeb48 100644 --- a/glib.h +++ b/glib.h @@ -500,6 +500,7 @@ typedef short gshort; typedef long glong; typedef int gint; typedef gint gboolean; +typedef gchar* gstring; typedef unsigned char guchar; typedef unsigned short gushort; diff --git a/glib/glib-object.h b/glib/glib-object.h index 14f54ab..9336241 100644 --- a/glib/glib-object.h +++ b/glib/glib-object.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/glib/glib.h b/glib/glib.h index 952014e..7baeb48 100644 --- a/glib/glib.h +++ b/glib/glib.h @@ -500,6 +500,7 @@ typedef short gshort; typedef long glong; typedef int gint; typedef gint gboolean; +typedef gchar* gstring; typedef unsigned char guchar; typedef unsigned short gushort; diff --git a/gobject/ChangeLog b/gobject/ChangeLog index 2c6c318..0d0ea87 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,79 @@ +Sat Jun 24 23:03:04 2000 Tim Janik + + * gtype.[hc]: provide G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_BOOLEAN, + G_TYPE_INT, G_TYPE_UINT, G_TYPE_LONG, G_TYPE_ULONG, G_TYPE_FLOAT, + G_TYPE_DOUBLE and G_TYPE_STRING fundamental types. + added a GTypeValueTable* pointer to GTypeInfo structure for types + to implement GValue handling functions. + GTypeValueTable contains the following members: + value_init(): initialize a GValue structure. + value_free(): free GValue structure contents (optional). + value_copy(): copy one GValue contents to another GValue structure of + collect_type: varargs collection type for the first variable argument + to be collected by collect_value(). + collect_value(): variable arguments collection function (optional). + lcopy_type: varargs collection type for the first variable argument + to be location copyied by lcopy_value(). + lcopy_value(): variable arguments location copy function (optional). + g_type_value_table_peek(): new function to retrive the GTypeValueTable* + for a type node. ValueTables get inherited from parent types, unless + overridden through the GTypeInfo structure. internally, GTypeValueTable + support means an added overhead of one pointer per static or used + dynamic type node. + g_type_add_class_cache_func(): provide a cache_func/data pair to be + called prior to a type nodes last_unref() function, this can be used + to prevent premature class destruction. multiple installed cache_func() + will be chained upon last_unref() untill one of them returns TRUE. + the cache_func()s have to check the type id passed in to figure whether + they actually wants to cache the class of this type (since any types are + routed through the cache_func() chain). + g_type_remove_class_cache_func(): remove a previously installed + cache_func/data pair. the cache maintained by this function has to be + clear when calling g_type_remove_class_cache_func() to avoid leaks. + g_type_class_unref_uncached(): class unref function for cache_func() + implementations, unreferences a class omitting the cache chain (and + therefore unref->cache->unref->... loops). + + * gvaluetypes.[hc]: provide the value setters/getters for the primitive + fundamental types boolean, char, uchar, int, uint, long, ulong, float, + double and string. + + * gvalue.[hc]: provide G_TYPE_IS_VALUE() in terms of whether a + GTypeValueTable is provided for this type. + removed g_value_init_default(), g_value_validate(), g_value_defaults(), + g_value_set_default() and g_values_cmp() as these are supplied by the + GParamSpec API now. + moved g_values_exchange() into the "implementation details" section, + since it just provides the underlying functionality for + g_value_convert(). + + * gvaluecollector.h: renamed the varargs value container from + GParamCValue to GTypeCValue as the value collection methods are + supplied by the type system now. + G_PARAM_COLLECT_VALUE() and G_PARAM_LCOPY_VALUE() got renamed to + G_VALUE_COLLECT() and G_VALUE_LCOPY() and operate without a + GParamSpec structure now. + + * genums.h: macros cleanups/fixes. + + * genum.c: provide G_TYPE_ENUM and G_TYPE_FLAGS type + and assorted g_value_{s|g}et_{enum|flags}() implementations. + + * gobject.[hc]: + provide G_IS_VALUE_OBJECT(), G_TYPE_OBJECT ValueTable methods + and g_value_{s|g}et_object(). + + * gparam.[hc]: reduced class to value_set_default(), + value_validate() and values_cmp(). also parameters now need to fill + in a GType value_type; field to indicate the GValue type they + are handling. provide g_param_value_set_default(), + g_param_value_defaults(), g_param_value_validate() and + g_param_values_cmp(). + + * gparamspecs.[hc]: got rid of the g_value_* functions and + the G_IS_VALUE_* macros. adapted param spec implementations + according to the GParamSpecClass changes. + Sat Jun 10 08:38:27 2000 Tim Janik * gtype.c (type_class_init): fetch the nth iface entry of the diff --git a/gobject/Makefile.am b/gobject/Makefile.am index d7859bc..dac3c43 100644 --- a/gobject/Makefile.am +++ b/gobject/Makefile.am @@ -28,6 +28,7 @@ libgobject_la_LIBADD = # $(libglib) # GObject header files for public installation (non-generated) gobject_public_h_sources = @STRIP_BEGIN@ \ gvalue.h \ + gvaluetypes.h \ gparam.h \ gparamspecs.h \ genums.h \ @@ -42,6 +43,7 @@ gobject_private_h_sources = @STRIP_BEGIN@ \ # GObject C sources to build the library from gobject_c_sources = @STRIP_BEGIN@ \ gvalue.c \ + gvaluetypes.c \ gparam.c \ gparamspecs.c \ genums.c \ diff --git a/gobject/genums.c b/gobject/genums.c index 3fcadb5..ef5e41a 100644 --- a/gobject/genums.c +++ b/gobject/genums.c @@ -18,24 +18,35 @@ */ #include "genums.h" +#include "gvalue.h" +#include "gvaluecollector.h" + /* --- prototypes --- */ -extern void g_enum_types_init (void); static void g_enum_class_init (GEnumClass *class, gpointer class_data); static void g_flags_class_init (GFlagsClass *class, gpointer class_data); +static void g_value_enum_init (GValue *value); +static void g_value_enum_copy_value (const GValue *src_value, + GValue *dest_value); +static gchar* g_value_enum_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value); +static gchar* g_value_enum_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value); /* --- functions --- */ void -g_enum_types_init (void) /* sync with glib-gtype.c */ +g_enum_types_init (void) /* sync with gtype.c */ { static gboolean initialized = FALSE; static const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_DERIVABLE, - 0 /* n_collect_bytes */, - NULL /* GTypeParamCollector */, }; static GTypeInfo info = { 0 /* class_size */, @@ -45,21 +56,32 @@ g_enum_types_init (void) /* sync with glib-gtype.c */ NULL /* class_finalize */, NULL /* class_data */, }; + static const GTypeValueTable value_table = { + g_value_enum_init, /* value_init */ + NULL, /* value_free */ + g_value_enum_copy_value, /* value_copy */ + G_VALUE_COLLECT_INT, /* collect_type */ + g_value_enum_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + g_value_enum_lcopy_value, /* lcopy_value */ + }; GType type; g_return_if_fail (initialized == FALSE); initialized = TRUE; - + + info.value_table = &value_table; + /* G_TYPE_ENUM */ info.class_size = sizeof (GEnumClass); - type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &finfo, &info); + type = g_type_register_fundamental (G_TYPE_ENUM, "GEnum", &info, &finfo); g_assert (type == G_TYPE_ENUM); /* G_TYPE_FLAGS */ info.class_size = sizeof (GFlagsClass); - type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &finfo, &info); + type = g_type_register_fundamental (G_TYPE_FLAGS, "GFlags", &info, &finfo); g_assert (type == G_TYPE_FLAGS); } @@ -304,3 +326,79 @@ g_flags_get_first_value (GFlagsClass *flags_class, return NULL; } + +void +g_value_set_enum (GValue *value, + gint v_enum) +{ + g_return_if_fail (G_IS_VALUE_ENUM (value)); + + value->data[0].v_long = v_enum; +} + +gint +g_value_get_enum (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_ENUM (value), 0); + + return value->data[0].v_long; +} + +void +g_value_set_flags (GValue *value, + guint v_flags) +{ + g_return_if_fail (G_IS_VALUE_FLAGS (value)); + + value->data[0].v_ulong = v_flags; +} + +guint +g_value_get_flags (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_FLAGS (value), 0); + + return value->data[0].v_ulong; +} + +static void +g_value_enum_init (GValue *value) +{ + value->data[0].v_long = 0; +} + +static void +g_value_enum_copy_value (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_long = src_value->data[0].v_long; +} + +static gchar* +g_value_enum_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + value->data[0].v_long = collect_value->v_int; + + *collect_type = 0; + return NULL; +} + +static gchar* +g_value_enum_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gint *int_p = collect_value->v_pointer; + + if (!int_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *int_p = value->data[0].v_long; + + *collect_type = 0; + return NULL; +} diff --git a/gobject/genums.h b/gobject/genums.h index 4e90c67..79dbb03 100644 --- a/gobject/genums.h +++ b/gobject/genums.h @@ -28,16 +28,18 @@ extern "C" { /* --- type macros --- */ -#define G_TYPE_IS_ENUM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM) -#define G_ENUM_TYPE(class) (G_TYPE_FROM_CLASS (class)) -#define G_ENUM_NAME(class) (g_type_name (G_ENUM_TYPE (class))) -#define G_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_ENUM, GEnumClass)) -#define G_IS_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ENUM)) -#define G_TYPE_IS_FLAGS(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS) -#define G_FLAGS_TYPE(class) (G_TYPE_FROM_CLASS (class)) -#define G_FLAGS_NAME(class) (g_type_name (G_FLAGS_TYPE (class))) -#define G_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_FLAGS, GFlagsClass)) -#define G_IS_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_FLAGS)) +#define G_TYPE_IS_ENUM(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_ENUM) +#define G_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_ENUM, GEnumClass)) +#define G_IS_ENUM_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_ENUM)) +#define G_ENUM_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define G_ENUM_CLASS_TYPE_NAME(class) (g_type_name (G_ENUM_TYPE (class))) +#define G_TYPE_IS_FLAGS(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_FLAGS) +#define G_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_FLAGS, GFlagsClass)) +#define G_IS_FLAGS_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_FLAGS)) +#define G_FLAGS_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) +#define G_FLAGS_CLASS_TYPE_NAME(class) (g_type_name (G_FLAGS_TYPE (class))) +#define G_IS_VALUE_ENUM(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_ENUM)) +#define G_IS_VALUE_FLAGS(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_FLAGS)) /* --- enum/flag values & classes --- */ @@ -89,6 +91,13 @@ GFlagsValue* g_flags_get_value_by_name (GFlagsClass *flags_class, const gchar *name); GFlagsValue* g_flags_get_value_by_nick (GFlagsClass *flags_class, const gchar *nick); +void g_value_set_enum (GValue *value, + gint v_enum); +gint g_value_get_enum (GValue *value); +void g_value_set_flags (GValue *value, + guint v_flags); +guint g_value_get_flags (GValue *value); + /* --- registration functions --- */ diff --git a/gobject/gobject.c b/gobject/gobject.c index 8d54b34..3448a34 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -19,7 +19,6 @@ #include "gobject.h" -#include "gvalue.h" #include "gvaluecollector.h" @@ -31,18 +30,29 @@ /* --- prototypes --- */ -extern void g_object_type_init (void); static void g_object_base_class_init (GObjectClass *class); static void g_object_base_class_finalize (GObjectClass *class); static void g_object_do_class_init (GObjectClass *class); static void g_object_do_init (GObject *object); -static void g_object_do_queue_param_changed (GObject *object, - GParamSpec *pspec); -static void g_object_do_dispatch_param_changed (GObject *object, - GParamSpec *pspec); +static void g_object_do_queue_param_changed (GObject *object, + GParamSpec *pspec); +static void g_object_do_dispatch_param_changed (GObject *object, + GParamSpec *pspec); static void g_object_last_unref (GObject *object); static void g_object_do_shutdown (GObject *object); static void g_object_do_finalize (GObject *object); +static void g_value_object_init (GValue *value); +static void g_value_object_free_value (GValue *value); +static void g_value_object_copy_value (const GValue *src_value, + GValue *dest_value); +static gchar* g_value_object_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value); +static gchar* g_value_object_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value); /* --- variables --- */ @@ -61,7 +71,7 @@ debug_objects_foreach (gpointer key, gpointer user_data) { GObject *object = value; - + g_message ("[%p] stale %s\tref_count=%u", object, G_OBJECT_TYPE_NAME (object), @@ -79,13 +89,11 @@ debug_objects_atexit (void) #endif DEBUG_OBJECTS void -g_object_type_init (void) /* sync with glib-gtype.c */ +g_object_type_init (void) /* sync with gtype.c */ { static gboolean initialized = FALSE; static const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE, - 0 /* n_collect_bytes */, - NULL /* GTypeParamCollector */, }; static GTypeInfo info = { sizeof (GObjectClass), @@ -97,6 +105,16 @@ g_object_type_init (void) /* sync with glib-gtype.c */ sizeof (GObject), 0 /* n_preallocs */, (GInstanceInitFunc) g_object_do_init, + NULL, /* value_table */ + }; + static const GTypeValueTable value_table = { + g_value_object_init, /* value_init */ + g_value_object_free_value, /* value_free */ + g_value_object_copy_value, /* value_copy */ + G_VALUE_COLLECT_POINTER, /* collect_type */ + g_value_object_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + g_value_object_lcopy_value, /* lcopy_value */ }; GType type; @@ -105,12 +123,13 @@ g_object_type_init (void) /* sync with glib-gtype.c */ /* G_TYPE_OBJECT */ - type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &finfo, &info); + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_OBJECT, "GObject", &info, &finfo); g_assert (type == G_TYPE_OBJECT); - -#ifdef DEBUG_OBJECTS + +#ifdef DEBUG_OBJECTS g_atexit (debug_objects_atexit); -#endif DEBUG_OBJECTS +#endif DEBUG_OBJECTS } static void @@ -127,7 +146,7 @@ static void g_object_base_class_finalize (GObjectClass *class) { guint i; - + g_message ("finallizing base class of %s", G_OBJECT_CLASS_NAME (class)); for (i = 0; i < class->n_param_specs; i++) @@ -158,11 +177,11 @@ g_object_do_class_init (GObjectClass *class) void g_object_class_install_param (GObjectClass *class, - guint param_id, + guint param_id, GParamSpec *pspec /* 1 ref_count taken over */) { guint i; - + g_return_if_fail (G_IS_OBJECT_CLASS (class)); g_return_if_fail (G_IS_PARAM_SPEC (pspec)); if (pspec->flags & G_PARAM_WRITABLE) @@ -171,7 +190,7 @@ g_object_class_install_param (GObjectClass *class, g_return_if_fail (class->get_param != NULL); g_return_if_fail (param_id > 0); g_return_if_fail (PARAM_SPEC_PARAM_ID (pspec) == 0); /* paranoid */ - + /* expensive paranoia checks ;( */ for (i = 0; i < class->n_param_specs; i++) if (PARAM_SPEC_PARAM_ID (class->param_specs[i]) == param_id) @@ -191,7 +210,7 @@ g_object_class_install_param (GObjectClass *class, pspec->name); return; } - + g_param_spec_set_qdata (pspec, quark_param_id, GUINT_TO_POINTER (param_id)); g_param_spec_hash_table_insert (param_spec_hash_table, pspec, G_OBJECT_CLASS_TYPE (class)); i = class->n_param_specs++; @@ -205,7 +224,7 @@ g_object_class_find_param_spec (GObjectClass *class, { g_return_val_if_fail (G_IS_OBJECT_CLASS (class), NULL); g_return_val_if_fail (param_name != NULL, NULL); - + return g_param_spec_hash_table_lookup (param_spec_hash_table, param_name, G_OBJECT_CLASS_TYPE (class), @@ -217,7 +236,7 @@ g_object_do_init (GObject *object) { object->ref_count = 1; object->qdata = NULL; - + #ifdef DEBUG_OBJECTS if (!debug_objects_ht) debug_objects_ht = g_hash_table_new (g_direct_hash, NULL); @@ -230,12 +249,12 @@ static void g_object_last_unref (GObject *object) { g_return_if_fail (object->ref_count > 0); - + if (object->ref_count == 1) /* may have been re-referenced meanwhile */ G_OBJECT_GET_CLASS (object)->shutdown (object); - + object->ref_count -= 1; - + if (object->ref_count == 0) /* may have been re-referenced meanwhile */ G_OBJECT_GET_CLASS (object)->finalize (object); } @@ -265,31 +284,31 @@ g_object_do_finalize (GObject *object) } gpointer -g_object_new (GType object_type, +g_object_new (GType object_type, const gchar *first_param_name, ...) { GObject *object; va_list var_args; - + g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); - + va_start (var_args, first_param_name); object = g_object_new_valist (object_type, first_param_name, var_args); va_end (var_args); - + return object; } gpointer -g_object_new_valist (GType object_type, +g_object_new_valist (GType object_type, const gchar *first_param_name, - va_list var_args) + va_list var_args) { GObject *object; - + g_return_val_if_fail (G_TYPE_IS_OBJECT (object_type), NULL); - + object = (GObject*) g_type_create_instance (object_type); if (first_param_name) g_object_set_valist (object, first_param_name, var_args); @@ -312,15 +331,15 @@ notify_param_changed_handler (gpointer data) GObject *object; GObjectClass *class; GSList *slist; - + /* FIXME: need GDK_THREADS lock */ - + object = G_OBJECT (data); class = G_OBJECT_GET_CLASS (object); slist = g_datalist_id_get_data (&object->qdata, quark_param_changed_queue); - + /* a reference count is still being held */ - + for (; slist; slist = slist->next) if (slist->data) { @@ -376,11 +395,11 @@ object_get_param (GObject *object, const gchar *trailer) { GObjectClass *class; - + g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */ - + class = g_type_class_peek (pspec->owner_type); - + class->get_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer); } @@ -391,36 +410,36 @@ object_set_param (GObject *object, const gchar *trailer) { GObjectClass *class; - + g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (object), pspec->owner_type)); /* paranoid */ - + class = g_type_class_peek (pspec->owner_type); - + class->set_param (object, PARAM_SPEC_PARAM_ID (pspec), value, pspec, trailer); - + class->queue_param_changed (object, pspec); } void -g_object_set_valist (GObject *object, +g_object_set_valist (GObject *object, const gchar *first_param_name, - va_list var_args) + va_list var_args) { const gchar *name; - + g_return_if_fail (G_IS_OBJECT (object)); - + g_object_ref (object); - + name = first_param_name; - + while (name) { const gchar *trailer = NULL; GValue value = { 0, }; GParamSpec *pspec; gchar *error = NULL; - + pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, name, G_OBJECT_TYPE (object), @@ -442,10 +461,10 @@ g_object_set_valist (GObject *object, G_OBJECT_TYPE_NAME (object)); break; } - - g_value_init (&value, G_PARAM_SPEC_TYPE (pspec)); - - G_PARAM_COLLECT_VALUE (&value, pspec, var_args, &error); + + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + + G_VALUE_COLLECT (&value, var_args, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); @@ -456,37 +475,37 @@ g_object_set_valist (GObject *object, */ break; } - + object_set_param (object, &value, pspec, trailer); g_value_unset (&value); - + name = va_arg (var_args, gchar*); } - + g_object_unref (object); } void -g_object_get_valist (GObject *object, +g_object_get_valist (GObject *object, const gchar *first_param_name, - va_list var_args) + va_list var_args) { const gchar *name; - + g_return_if_fail (G_IS_OBJECT (object)); - + g_object_ref (object); - + name = first_param_name; - + while (name) { const gchar *trailer = NULL; GValue value = { 0, }; GParamSpec *pspec; gchar *error = NULL; - + pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, name, G_OBJECT_TYPE (object), @@ -508,12 +527,12 @@ g_object_get_valist (GObject *object, G_OBJECT_TYPE_NAME (object)); break; } - - g_value_init (&value, G_PARAM_SPEC_TYPE (pspec)); - + + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + object_get_param (object, &value, pspec, trailer); - - G_PARAM_LCOPY_VALUE (&value, pspec, var_args, &error); + + G_VALUE_LCOPY (&value, var_args, &error); if (error) { g_warning ("%s: %s", G_STRLOC, error); @@ -526,55 +545,55 @@ g_object_get_valist (GObject *object, } g_value_unset (&value); - + name = va_arg (var_args, gchar*); } - + g_object_unref (object); } void -g_object_set (GObject *object, +g_object_set (GObject *object, const gchar *first_param_name, ...) { va_list var_args; - + g_return_if_fail (G_IS_OBJECT (object)); - + va_start (var_args, first_param_name); g_object_set_valist (object, first_param_name, var_args); va_end (var_args); } void -g_object_get (GObject *object, +g_object_get (GObject *object, const gchar *first_param_name, ...) { va_list var_args; - + g_return_if_fail (G_IS_OBJECT (object)); - + va_start (var_args, first_param_name); g_object_get_valist (object, first_param_name, var_args); va_end (var_args); } void -g_object_set_param (GObject *object, - const gchar *param_name, +g_object_set_param (GObject *object, + const gchar *param_name, const GValue *value) { GParamSpec *pspec; const gchar *trailer; - + g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (param_name != NULL); g_return_if_fail (G_IS_VALUE (value)); - + g_object_ref (object); - + pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, param_name, G_OBJECT_TYPE (object), @@ -588,17 +607,17 @@ g_object_set_param (GObject *object, else { GValue tmp_value = { 0, }; - + /* provide a copy to work from and convert if necessary */ - g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec)); - + g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + if (!g_value_convert (value, &tmp_value) || - g_value_validate (&tmp_value, pspec)) - g_warning ("%s: can't convert `%s' value to parameter `%s' of type `%s'", + g_param_value_validate (pspec, &tmp_value)) + g_warning ("%s: cannot convert `%s' value to parameter `%s' value of type `%s'", G_STRLOC, G_VALUE_TYPE_NAME (value), pspec->name, - G_PARAM_SPEC_TYPE_NAME (pspec)); + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec))); else object_set_param (object, &tmp_value, pspec, trailer); @@ -609,9 +628,9 @@ g_object_set_param (GObject *object, } void -g_object_get_param (GObject *object, +g_object_get_param (GObject *object, const gchar *param_name, - GValue *value) + GValue *value) { GParamSpec *pspec; const gchar *trailer; @@ -642,13 +661,13 @@ g_object_get_param (GObject *object, * (though, at this point, GValue should exclusively be modified * through the accessor functions anyways) */ - g_value_init (&tmp_value, G_PARAM_SPEC_TYPE (pspec)); + g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_TYPE (pspec))) - g_warning ("%s: can't retrive parameter `%s' of type `%s' as value of type `%s'", + if (!g_value_types_exchangable (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec))) + g_warning ("%s: can't retrive parameter `%s' value of type `%s' as value of type `%s'", G_STRLOC, pspec->name, - G_PARAM_SPEC_TYPE_NAME (pspec), + g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)), G_VALUE_TYPE_NAME (value)); else { @@ -664,14 +683,14 @@ g_object_get_param (GObject *object, } void -g_object_queue_param_changed (GObject *object, +g_object_queue_param_changed (GObject *object, const gchar *param_name) { GParamSpec *pspec; g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (param_name != NULL); - + pspec = g_param_spec_hash_table_lookup (param_spec_hash_table, param_name, G_OBJECT_TYPE (object), @@ -690,9 +709,9 @@ g_object_ref (GObject *object) { g_return_val_if_fail (G_IS_OBJECT (object), NULL); g_return_val_if_fail (object->ref_count > 0, NULL); - + object->ref_count += 1; - + return object; } @@ -701,7 +720,7 @@ g_object_unref (GObject *object) { g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (object->ref_count > 0); - + if (object->ref_count > 1) object->ref_count -= 1; else @@ -713,7 +732,7 @@ g_object_get_qdata (GObject *object, GQuark quark) { g_return_val_if_fail (G_IS_OBJECT (object), NULL); - + return quark ? g_datalist_id_get_data (&object->qdata, quark) : NULL; } @@ -730,8 +749,8 @@ g_object_set_qdata (GObject *object, void g_object_set_qdata_full (GObject *object, - GQuark quark, - gpointer data, + GQuark quark, + gpointer data, GDestroyNotify destroy) { g_return_if_fail (G_IS_OBJECT (object)); @@ -749,3 +768,105 @@ g_object_steal_qdata (GObject *object, return g_datalist_id_remove_no_notify (&object->qdata, quark); } + +static void +g_value_object_init (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +g_value_object_free_value (GValue *value) +{ + if (value->data[0].v_pointer) + g_object_unref (value->data[0].v_pointer); +} + +static void +g_value_object_copy_value (const GValue *src_value, + GValue *dest_value) +{ + if (src_value->data[0].v_pointer) + dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer); + else + dest_value->data[0].v_pointer = NULL; +} + +static gchar* +g_value_object_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + if (collect_value->v_pointer) + { + GObject *object = collect_value->v_pointer; + + if (object->g_type_instance.g_class == NULL) + return g_strconcat ("invalid unclassed object pointer for value type `", + G_VALUE_TYPE_NAME (value), + "'", + NULL); + else if (!g_type_is_a (G_OBJECT_TYPE (object), G_VALUE_TYPE (value))) + return g_strconcat ("invalid object type `", + G_OBJECT_TYPE_NAME (object), + "' for value type `", + G_VALUE_TYPE_NAME (value), + "'", + NULL); + value->data[0].v_pointer = g_object_ref (object); + } + else + value->data[0].v_pointer = NULL; + + *collect_type = 0; + return NULL; +} + +static gchar* +g_value_object_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + GObject **object_p = collect_value->v_pointer; + + if (!object_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; + + *collect_type = 0; + return NULL; +} + +void +g_value_set_object (GValue *value, + GObject *v_object) +{ + g_return_if_fail (G_IS_VALUE_OBJECT (value)); + if (v_object) + g_return_if_fail (G_IS_OBJECT (v_object)); + + if (value->data[0].v_pointer) + g_object_unref (value->data[0].v_pointer); + value->data[0].v_pointer = v_object; + if (value->data[0].v_pointer) + g_object_ref (value->data[0].v_pointer); +} + +GObject* +g_value_get_object (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL); + + return value->data[0].v_pointer; +} + +GObject* +g_value_dup_object (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL); + + return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; +} diff --git a/gobject/gobject.h b/gobject/gobject.h index 69c718d..68657ab 100644 --- a/gobject/gobject.h +++ b/gobject/gobject.h @@ -20,6 +20,7 @@ #define __G_GOBJECT_H__ #include +#include #include @@ -43,6 +44,7 @@ extern "C" { #define G_OBJECT_TYPE_NAME(object) (g_type_name (G_OBJECT_TYPE (object))) #define G_OBJECT_CLASS_TYPE(class) (G_TYPE_FROM_CLASS (class)) #define G_OBJECT_CLASS_NAME(class) (g_type_name (G_OBJECT_CLASS_TYPE (class))) +#define G_IS_VALUE_OBJECT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_OBJECT)) #define G_NOTIFY_PRIORITY (G_PRIORITY_HIGH_IDLE + 20) @@ -140,6 +142,10 @@ void g_object_set_qdata_full (GObject *object, GDestroyNotify destroy); gpointer g_object_steal_qdata (GObject *object, GQuark quark); +void g_value_set_object (GValue *value, + GObject *v_object); +GObject* g_value_get_object (GValue *value); +GObject* g_value_dup_object (GValue *value); /* --- implementation macros --- */ diff --git a/gobject/gparam.c b/gobject/gparam.c index e29b1a7..7d0199e 100644 --- a/gobject/gparam.c +++ b/gobject/gparam.c @@ -28,8 +28,6 @@ /* --- prototypes --- */ -extern void g_param_types_init (void); -extern void g_param_spec_types_init (void); /* sync with glib-gparamspecs.c */ static void g_param_spec_class_base_init (GParamSpecClass *class); static void g_param_spec_class_base_finalize (GParamSpecClass *class); static void g_param_spec_class_init (GParamSpecClass *class, @@ -40,15 +38,13 @@ static void g_param_spec_finalize (GParamSpec *pspec); /* --- functions --- */ void -g_param_types_init (void) /* sync with glib-gtype.c */ +g_param_type_init (void) /* sync with gtype.c */ { static const GTypeFundamentalInfo finfo = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE), - 0 /* n_collect_bytes */, - NULL /* GTypeParamCollector */, }; static const GTypeInfo param_spec_info = { sizeof (GParamSpecClass), @@ -57,20 +53,18 @@ g_param_types_init (void) /* sync with glib-gtype.c */ (GBaseFinalizeFunc) g_param_spec_class_base_finalize, (GClassInitFunc) g_param_spec_class_init, (GClassFinalizeFunc) NULL, - NULL /* class_data */, + NULL, /* class_data */ sizeof (GParamSpec), - 0 /* n_preallocs */, + 0, /* n_preallocs */ (GInstanceInitFunc) g_param_spec_init, + + NULL, /* value_table */ }; GType type; - type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", &finfo, ¶m_spec_info); + type = g_type_register_fundamental (G_TYPE_PARAM, "GParam", ¶m_spec_info, &finfo); g_assert (type == G_TYPE_PARAM); - - /* derived param specs - */ - g_param_spec_types_init (); } static void @@ -87,16 +81,11 @@ static void g_param_spec_class_init (GParamSpecClass *class, gpointer class_data) { + class->value_type = G_TYPE_NONE; class->finalize = g_param_spec_finalize; - class->param_init = NULL; - class->param_free_value = NULL; - class->param_validate = NULL; - class->param_values_cmp = NULL; - class->param_copy_value = NULL; - class->collect_type = 0; - class->param_collect_value = NULL; - class->lcopy_type = 0; - class->param_lcopy_value = NULL; + class->value_set_default = NULL; + class->value_validate = NULL; + class->values_cmp = NULL; } static void @@ -209,6 +198,81 @@ g_param_spec_steal_qdata (GParamSpec *pspec, return g_datalist_id_remove_no_notify (&pspec->qdata, quark); } +void +g_param_value_set_default (GParamSpec *pspec, + GValue *value) +{ + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + g_return_if_fail (G_IS_VALUE (value)); + g_return_if_fail (G_IS_PARAM_VALUE (pspec, value)); + + g_value_reset (value); + G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value); +} + +gboolean +g_param_value_defaults (GParamSpec *pspec, + GValue *value) +{ + GValue dflt_value = { 0, }; + gboolean defaults; + + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); + g_return_val_if_fail (G_IS_VALUE (value), FALSE); + g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE); + + g_value_init (&dflt_value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + G_PARAM_SPEC_GET_CLASS (pspec)->value_set_default (pspec, value); + defaults = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value, &dflt_value) == 0; + g_value_unset (&dflt_value); + + return defaults; +} + +gboolean +g_param_value_validate (GParamSpec *pspec, + GValue *value) +{ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); + g_return_val_if_fail (G_IS_VALUE (value), FALSE); + g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value), FALSE); + + if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate) + { + GValue oval = *value; + + if (G_PARAM_SPEC_GET_CLASS (pspec)->value_validate (pspec, value) || + memcmp (&oval.data, &value->data, sizeof (oval.data))) + return TRUE; + } + + return FALSE; +} + +gint +g_param_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + gint cmp; + + /* param_values_cmp() effectively does: value1 - value2 + * so the return values are: + * -1) value1 < value2 + * 0) value1 == value2 + * 1) value1 > value2 + */ + g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0); + g_return_val_if_fail (G_IS_VALUE (value1), 0); + g_return_val_if_fail (G_IS_VALUE (value2), 0); + g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value1), 0); + g_return_val_if_fail (G_IS_PARAM_VALUE (pspec, value2), 0); + + cmp = G_PARAM_SPEC_GET_CLASS (pspec)->values_cmp (pspec, value1, value2); + + return CLAMP (cmp, -1, 1); +} + static guint param_spec_hash (gconstpointer key_spec) { diff --git a/gobject/gparam.h b/gobject/gparam.h index fb6ef1e..3551b15 100644 --- a/gobject/gparam.h +++ b/gobject/gparam.h @@ -22,7 +22,7 @@ #define __G_PARAM_H__ -#include +#include #ifdef __cplusplus @@ -37,7 +37,8 @@ extern "C" { #define G_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM, GParamSpec)) #define G_IS_PARAM_SPEC(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM)) #define G_PARAM_SPEC_GET_CLASS(pspec) (G_TYPE_INSTANCE_GET_CLASS ((pspec), G_TYPE_PARAM, GParamSpecClass)) -#define G_IS_VALUE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM)) +#define G_IS_PARAM_VALUE(pspec, value) (g_type_is_a (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (pspec))) // FIXME +#define G_PARAM_SPEC_VALUE_TYPE(pspec) (G_PARAM_SPEC_GET_CLASS (pspec)->value_type) /* --- flags --- */ @@ -54,39 +55,22 @@ typedef enum /* --- typedefs & structures --- */ typedef struct _GParamSpecClass GParamSpecClass; typedef struct _GParamSpec GParamSpec; -typedef struct _GValue GValue; -typedef union _GParamCValue GParamCValue; -typedef void (*GValueExchange) (GValue*, GValue*); struct _GParamSpecClass { GTypeClass g_type_class; + GType value_type; + void (*finalize) (GParamSpec *pspec); /* GParam methods */ - void (*param_init) (GValue *value, - GParamSpec *pspec); - void (*param_free_value) (GValue *value); - gboolean (*param_validate) (GValue *value, - GParamSpec *pspec); - gint (*param_values_cmp) (const GValue *value1, - const GValue *value2, - GParamSpec *pspec); - void (*param_copy_value) (const GValue *src_value, - GValue *dest_value); - /* varargs functionality (optional) */ - guint collect_type; - gchar* (*param_collect_value) (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value); - guint lcopy_type; - gchar* (*param_lcopy_value) (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value); + void (*value_set_default) (GParamSpec *pspec, + GValue *value); + gboolean (*value_validate) (GParamSpec *pspec, + GValue *value); + gint (*values_cmp) (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); }; struct _GParamSpec { @@ -118,6 +102,15 @@ void g_param_spec_set_qdata_full (GParamSpec *pspec, GDestroyNotify destroy); gpointer g_param_spec_steal_qdata (GParamSpec *pspec, GQuark quark); +void g_param_value_set_default (GParamSpec *pspec, + GValue *value); +gboolean g_param_value_defaults (GParamSpec *pspec, + GValue *value); +gboolean g_param_value_validate (GParamSpec *pspec, + GValue *value); +gint g_param_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); /* --- private --- */ @@ -141,6 +134,8 @@ GParamSpec* g_param_spec_hash_table_lookup (GHashTable *hash_table, /* contracts: * + * +++ OUTDATED +++ + * * class functions may not evaluate param->pspec directly, * instead, pspec will be passed as argument if required. * diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c index 628d134..c62bf2f 100644 --- a/gobject/gparamspecs.c +++ b/gobject/gparamspecs.c @@ -26,10 +26,6 @@ #define G_DOUBLE_EPSILON (1e-90) -/* --- prototypes --- */ -extern void g_param_spec_types_init (void); - - /* --- param spec functions --- */ static void param_spec_char_init (GParamSpec *pspec) @@ -42,16 +38,15 @@ param_spec_char_init (GParamSpec *pspec) } static void -param_char_init (GValue *value, - GParamSpec *pspec) +param_char_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value; + value->data[0].v_int = G_PARAM_SPEC_CHAR (pspec)->default_value; } static gboolean -param_char_validate (GValue *value, - GParamSpec *pspec) +param_char_validate (GParamSpec *pspec, + GValue *value) { GParamSpecChar *cspec = G_PARAM_SPEC_CHAR (pspec); gint oval = value->data[0].v_int; @@ -61,25 +56,6 @@ param_char_validate (GValue *value, return value->data[0].v_int != oval; } -static gchar* -param_char_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gint8 *int8_p = collect_value->v_pointer; - - if (!int8_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *int8_p = value->data[0].v_int; - - *collect_type = 0; - return NULL; -} - static void param_spec_uchar_init (GParamSpec *pspec) { @@ -91,16 +67,15 @@ param_spec_uchar_init (GParamSpec *pspec) } static void -param_uchar_init (GValue *value, - GParamSpec *pspec) +param_uchar_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value; + value->data[0].v_uint = G_PARAM_SPEC_UCHAR (pspec)->default_value; } static gboolean -param_uchar_validate (GValue *value, - GParamSpec *pspec) +param_uchar_validate (GParamSpec *pspec, + GValue *value) { GParamSpecUChar *uspec = G_PARAM_SPEC_UCHAR (pspec); guint oval = value->data[0].v_uint; @@ -111,16 +86,15 @@ param_uchar_validate (GValue *value, } static void -param_bool_init (GValue *value, - GParamSpec *pspec) +param_boolean_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_int = G_PARAM_SPEC_BOOL (pspec)->default_value; + value->data[0].v_int = G_PARAM_SPEC_BOOLEAN (pspec)->default_value; } static gboolean -param_bool_validate (GValue *value, - GParamSpec *pspec) +param_boolean_validate (GParamSpec *pspec, + GValue *value) { gint oval = value->data[0].v_int; @@ -129,25 +103,6 @@ param_bool_validate (GValue *value, return value->data[0].v_int != oval; } -static gchar* -param_bool_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gboolean *bool_p = collect_value->v_pointer; - - if (!bool_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *bool_p = value->data[0].v_int; - - *collect_type = 0; - return NULL; -} - static void param_spec_int_init (GParamSpec *pspec) { @@ -159,16 +114,15 @@ param_spec_int_init (GParamSpec *pspec) } static void -param_int_init (GValue *value, - GParamSpec *pspec) +param_int_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value; + value->data[0].v_int = G_PARAM_SPEC_INT (pspec)->default_value; } static gboolean -param_int_validate (GValue *value, - GParamSpec *pspec) +param_int_validate (GParamSpec *pspec, + GValue *value) { GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec); gint oval = value->data[0].v_int; @@ -179,46 +133,14 @@ param_int_validate (GValue *value, } static gint -param_int_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_int_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { if (value1->data[0].v_int < value2->data[0].v_int) return -1; else - return value1->data[0].v_int - value2->data[0].v_int; -} - -static gchar* -param_int_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - value->data[0].v_int = collect_value->v_int; - - *collect_type = 0; - return NULL; -} - -static gchar* -param_int_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gint *int_p = collect_value->v_pointer; - - if (!int_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *int_p = value->data[0].v_int; - - *collect_type = 0; - return NULL; + return value1->data[0].v_int > value2->data[0].v_int; } static void @@ -232,16 +154,15 @@ param_spec_uint_init (GParamSpec *pspec) } static void -param_uint_init (GValue *value, - GParamSpec *pspec) +param_uint_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value; + value->data[0].v_uint = G_PARAM_SPEC_UINT (pspec)->default_value; } static gboolean -param_uint_validate (GValue *value, - GParamSpec *pspec) +param_uint_validate (GParamSpec *pspec, + GValue *value) { GParamSpecUInt *uspec = G_PARAM_SPEC_UINT (pspec); guint oval = value->data[0].v_uint; @@ -252,14 +173,14 @@ param_uint_validate (GValue *value, } static gint -param_uint_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_uint_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { if (value1->data[0].v_uint < value2->data[0].v_uint) return -1; else - return value1->data[0].v_uint - value2->data[0].v_uint; + return value1->data[0].v_uint > value2->data[0].v_uint; } static void @@ -278,16 +199,15 @@ param_spec_long_init (GParamSpec *pspec) } static void -param_long_init (GValue *value, - GParamSpec *pspec) +param_long_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value; + value->data[0].v_long = G_PARAM_SPEC_LONG (pspec)->default_value; } static gboolean -param_long_validate (GValue *value, - GParamSpec *pspec) +param_long_validate (GParamSpec *pspec, + GValue *value) { GParamSpecLong *lspec = G_PARAM_SPEC_LONG (pspec); glong oval = value->data[0].v_long; @@ -298,46 +218,14 @@ param_long_validate (GValue *value, } static gint -param_long_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_long_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { if (value1->data[0].v_long < value2->data[0].v_long) return -1; else - return value1->data[0].v_long - value2->data[0].v_long; -} - -static gchar* -param_long_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - value->data[0].v_long = collect_value->v_long; - - *collect_type = 0; - return NULL; -} - -static gchar* -param_long_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - glong *long_p = collect_value->v_pointer; - - if (!long_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *long_p = value->data[0].v_long; - - *collect_type = 0; - return NULL; + return value1->data[0].v_long > value2->data[0].v_long; } static void @@ -355,16 +243,15 @@ param_spec_ulong_init (GParamSpec *pspec) } static void -param_ulong_init (GValue *value, - GParamSpec *pspec) +param_ulong_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value; + value->data[0].v_ulong = G_PARAM_SPEC_ULONG (pspec)->default_value; } static gboolean -param_ulong_validate (GValue *value, - GParamSpec *pspec) +param_ulong_validate (GParamSpec *pspec, + GValue *value) { GParamSpecULong *uspec = G_PARAM_SPEC_ULONG (pspec); gulong oval = value->data[0].v_ulong; @@ -375,14 +262,14 @@ param_ulong_validate (GValue *value, } static gint -param_ulong_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_ulong_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { if (value1->data[0].v_ulong < value2->data[0].v_ulong) return -1; else - return value1->data[0].v_ulong - value2->data[0].v_ulong; + return value1->data[0].v_ulong > value2->data[0].v_ulong; } static void @@ -410,16 +297,15 @@ param_spec_enum_finalize (GParamSpec *pspec) } static void -param_enum_init (GValue *value, - GParamSpec *pspec) +param_enum_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value; + value->data[0].v_long = G_PARAM_SPEC_ENUM (pspec)->default_value; } static gboolean -param_enum_validate (GValue *value, - GParamSpec *pspec) +param_enum_validate (GParamSpec *pspec, + GValue *value) { GParamSpecEnum *espec = G_PARAM_SPEC_ENUM (pspec); glong oval = value->data[0].v_long; @@ -431,38 +317,6 @@ param_enum_validate (GValue *value, return value->data[0].v_long != oval; } -static gchar* -param_enum_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - value->data[0].v_long = collect_value->v_int; - - *collect_type = 0; - return NULL; -} - -static gchar* -param_enum_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gint *int_p = collect_value->v_pointer; - - if (!int_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *int_p = value->data[0].v_long; - - *collect_type = 0; - return NULL; -} - static void param_spec_flags_init (GParamSpec *pspec) { @@ -488,16 +342,15 @@ param_spec_flags_finalize (GParamSpec *pspec) } static void -param_flags_init (GValue *value, - GParamSpec *pspec) +param_flags_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value; + value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value; } static gboolean -param_flags_validate (GValue *value, - GParamSpec *pspec) +param_flags_validate (GParamSpec *pspec, + GValue *value) { GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); gulong oval = value->data[0].v_ulong; @@ -522,16 +375,15 @@ param_spec_float_init (GParamSpec *pspec) } static void -param_float_init (GValue *value, - GParamSpec *pspec) +param_float_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value; + value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value; } static gboolean -param_float_validate (GValue *value, - GParamSpec *pspec) +param_float_validate (GParamSpec *pspec, + GValue *value) { GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); gfloat oval = value->data[0].v_float; @@ -542,11 +394,11 @@ param_float_validate (GValue *value, } static gint -param_float_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_float_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { - gfloat epsilon = pspec ? G_PARAM_SPEC_FLOAT (pspec)->epsilon : G_FLOAT_EPSILON; + gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon; if (value1->data[0].v_float < value2->data[0].v_float) return - (value2->data[0].v_float - value1->data[0].v_float > epsilon); @@ -554,38 +406,6 @@ param_float_values_cmp (const GValue *value1, return value1->data[0].v_float - value2->data[0].v_float > epsilon; } -static gchar* -param_float_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - value->data[0].v_float = collect_value->v_double; - - *collect_type = 0; - return NULL; -} - -static gchar* -param_float_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gfloat *float_p = collect_value->v_pointer; - - if (!float_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *float_p = value->data[0].v_float; - - *collect_type = 0; - return NULL; -} - static void param_spec_double_init (GParamSpec *pspec) { @@ -598,16 +418,15 @@ param_spec_double_init (GParamSpec *pspec) } static void -param_double_init (GValue *value, - GParamSpec *pspec) +param_double_set_default (GParamSpec *pspec, + GValue *value) { - if (pspec) - value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value; + value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value; } static gboolean -param_double_validate (GValue *value, - GParamSpec *pspec) +param_double_validate (GParamSpec *pspec, + GValue *value) { GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); gdouble oval = value->data[0].v_double; @@ -618,11 +437,11 @@ param_double_validate (GValue *value, } static gint -param_double_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_double_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { - gdouble epsilon = pspec ? G_PARAM_SPEC_DOUBLE (pspec)->epsilon : G_DOUBLE_EPSILON; + gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon; if (value1->data[0].v_double < value2->data[0].v_double) return - (value2->data[0].v_double - value1->data[0].v_double > epsilon); @@ -630,38 +449,6 @@ param_double_values_cmp (const GValue *value1, return value1->data[0].v_double - value2->data[0].v_double > epsilon; } -static gchar* -param_double_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - value->data[0].v_double = collect_value->v_double; - - *collect_type = 0; - return NULL; -} - -static gchar* -param_double_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gdouble *double_p = collect_value->v_pointer; - - if (!double_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *double_p = value->data[0].v_double; - - *collect_type = 0; - return NULL; -} - static void param_spec_string_init (GParamSpec *pspec) { @@ -692,22 +479,15 @@ param_spec_string_finalize (GParamSpec *pspec) } static void -param_string_init (GValue *value, - GParamSpec *pspec) -{ - if (pspec) - value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value); -} - -static void -param_string_free_value (GValue *value) +param_string_set_default (GParamSpec *pspec, + GValue *value) { - g_free (value->data[0].v_pointer); + value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value); } static gboolean -param_string_validate (GValue *value, - GParamSpec *pspec) +param_string_validate (GParamSpec *pspec, + GValue *value) { GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); gchar *string = value->data[0].v_pointer; @@ -748,9 +528,9 @@ param_string_validate (GValue *value, } static gint -param_string_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_string_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { if (!value1->data[0].v_pointer) return value2->data[0].v_pointer != NULL ? -1 : 0; @@ -761,45 +541,6 @@ param_string_values_cmp (const GValue *value1, } static void -param_string_copy_value (const GValue *src_value, - GValue *dest_value) -{ - dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer); -} - -static gchar* -param_string_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - value->data[0].v_pointer = g_strdup (collect_value->v_pointer); - - *collect_type = 0; - return NULL; -} - -static gchar* -param_string_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - gchar **string_p = collect_value->v_pointer; - - if (!string_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *string_p = g_strdup (value->data[0].v_pointer); - - *collect_type = 0; - return NULL; -} - -static void param_spec_object_init (GParamSpec *pspec) { GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); @@ -808,22 +549,15 @@ param_spec_object_init (GParamSpec *pspec) } static void -param_object_init (GValue *value, - GParamSpec *pspec) +param_object_set_default (GParamSpec *pspec, + GValue *value) { value->data[0].v_pointer = NULL; } -static void -param_object_free_value (GValue *value) -{ - if (value->data[0].v_pointer) - g_object_unref (value->data[0].v_pointer); -} - static gboolean -param_object_validate (GValue *value, - GParamSpec *pspec) +param_object_validate (GParamSpec *pspec, + GValue *value) { GParamSpecObject *ospec = G_PARAM_SPEC_OBJECT (pspec); GObject *object = value->data[0].v_pointer; @@ -840,77 +574,14 @@ param_object_validate (GValue *value, } static gint -param_object_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) +param_object_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) { return value1->data[0].v_pointer != value2->data[0].v_pointer; } static void -param_object_copy_value (const GValue *src_value, - GValue *dest_value) -{ - if (src_value->data[0].v_pointer) - dest_value->data[0].v_pointer = g_object_ref (src_value->data[0].v_pointer); - else - dest_value->data[0].v_pointer = NULL; -} - -static gchar* -param_object_collect_value (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - if (collect_value->v_pointer) - { - GObject *object = collect_value->v_pointer; - - if (object->g_type_instance.g_class == NULL) - return g_strconcat ("invalid unclassed object pointer for param type `", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value)), - "'", - NULL); - else if (pspec && !g_type_is_a (G_OBJECT_TYPE (object), G_PARAM_SPEC_OBJECT (pspec)->object_type)) - return g_strconcat ("invalid object `", - G_OBJECT_TYPE_NAME (object), - "' for param type `", - g_type_name (G_PARAM_SPEC_TYPE (pspec)), - "' which requires `", - g_type_name (G_PARAM_SPEC_OBJECT (pspec)->object_type), - "'", - NULL); - value->data[0].v_pointer = g_object_ref (object); - } - else - value->data[0].v_pointer = NULL; - - *collect_type = 0; - return NULL; -} - -static gchar* -param_object_lcopy_value (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value) -{ - GObject **object_p = collect_value->v_pointer; - - if (!object_p) - return g_strdup_printf ("value location for `%s' passed as NULL", - g_type_name (pspec ? G_PARAM_SPEC_TYPE (pspec) : G_VALUE_TYPE (value))); - - *object_p = value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; - - *collect_type = 0; - return NULL; -} - -static void value_exch_memcpy (GValue *value1, GValue *value2) { @@ -1040,29 +711,15 @@ value_exch_double_float (GValue *value1, /* --- type initialization --- */ typedef struct { + GType value_type; void (*finalize) (GParamSpec *pspec); - void (*param_init) (GValue *value, - GParamSpec *pspec); - void (*param_free_value) (GValue *value); - gboolean (*param_validate) (GValue *value, - GParamSpec *pspec); - gint (*param_values_cmp) (const GValue *value1, - const GValue *value2, - GParamSpec *pspec); - void (*param_copy_value) (const GValue *src_value, - GValue *dest_value); - guint collect_type; - gchar* (*param_collect_value) (GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value); - guint lcopy_type; - gchar* (*param_lcopy_value) (const GValue *value, - GParamSpec *pspec, - guint nth_value, - GType *collect_type, - GParamCValue *collect_value); + void (*value_set_default) (GParamSpec *pspec, + GValue *value); + gboolean (*value_validate) (GParamSpec *pspec, + GValue *value); + gint (*values_cmp) (GParamSpec *pspec, + const GValue *value1, + const GValue *value2); } ParamSpecClassInfo; static void @@ -1071,27 +728,22 @@ param_spec_class_init (gpointer g_class, { GParamSpecClass *class = g_class; ParamSpecClassInfo *info = class_data; - + + g_assert (info->value_type && !G_TYPE_IS_PARAM (info->value_type)); + + class->value_type = info->value_type; if (info->finalize) class->finalize = info->finalize; - if (info->param_init) - class->param_init = info->param_init; - if (info->param_free_value) - class->param_free_value = info->param_free_value; - if (info->param_validate) - class->param_validate = info->param_validate; - if (info->param_values_cmp) - class->param_values_cmp = info->param_values_cmp; - if (info->param_copy_value) - class->param_copy_value = info->param_copy_value; - class->collect_type = info->collect_type; - class->param_collect_value = info->param_collect_value; - class->lcopy_type = info->lcopy_type; - class->param_lcopy_value = info->param_lcopy_value; + if (info->value_set_default) + class->value_set_default = info->value_set_default; + if (info->value_validate) + class->value_validate = info->value_validate; + if (info->values_cmp) + class->values_cmp = info->values_cmp; } void -g_param_spec_types_init (void) /* sync with glib-gparam.c */ +g_param_spec_types_init (void) /* sync with gtype.c */ { GTypeInfo info = { sizeof (GParamSpecClass), /* class_size */ @@ -1110,16 +762,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_CHAR, /* value_type */ NULL, /* finalize */ - param_char_init, /* param_init */ - NULL, /* param_free_value */ - param_char_validate, /* param_validate */ - param_int_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_int_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_char_lcopy_value, /* param_lcopy_value */ + param_char_set_default, /* value_set_default */ + param_char_validate, /* value_validate */ + param_int_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecChar); @@ -1132,16 +779,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_UCHAR, /* value_type */ NULL, /* finalize */ - param_uchar_init, /* param_init */ - NULL, /* param_free_value */ - param_uchar_validate, /* param_validate */ - param_uint_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_int_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_char_lcopy_value, /* param_lcopy_value */ + param_uchar_set_default, /* value_set_default */ + param_uchar_validate, /* value_validate */ + param_uint_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecUChar); @@ -1150,42 +792,32 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ g_assert (type == G_TYPE_PARAM_UCHAR); } - /* G_TYPE_PARAM_BOOL + /* G_TYPE_PARAM_BOOLEAN */ { static const ParamSpecClassInfo class_info = { - NULL, /* finalize */ - param_bool_init, /* param_init */ - NULL, /* param_free_value */ - param_bool_validate, /* param_validate */ - param_int_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_int_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_bool_lcopy_value, /* param_lcopy_value */ + G_TYPE_BOOLEAN, /* value_type */ + NULL, /* finalize */ + param_boolean_set_default, /* value_set_default */ + param_boolean_validate, /* value_validate */ + param_int_values_cmp, /* values_cmp */ }; info.class_data = &class_info; - info.instance_size = sizeof (GParamSpecBool); + info.instance_size = sizeof (GParamSpecBoolean); info.instance_init = (GInstanceInitFunc) NULL; - type = g_type_register_static (G_TYPE_PARAM, "GParamBool", &info); - g_assert (type == G_TYPE_PARAM_BOOL); + type = g_type_register_static (G_TYPE_PARAM, "GParamBoolean", &info); + g_assert (type == G_TYPE_PARAM_BOOLEAN); } /* G_TYPE_PARAM_INT */ { static const ParamSpecClassInfo class_info = { + G_TYPE_INT, /* value_type */ NULL, /* finalize */ - param_int_init, /* param_init */ - NULL, /* param_free_value */ - param_int_validate, /* param_validate */ - param_int_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_int_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_int_lcopy_value, /* param_lcopy_value */ + param_int_set_default, /* value_set_default */ + param_int_validate, /* value_validate */ + param_int_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecInt); @@ -1198,16 +830,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_UINT, /* value_type */ NULL, /* finalize */ - param_uint_init, /* param_init */ - NULL, /* param_free_value */ - param_uint_validate, /* param_validate */ - param_uint_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_int_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_int_lcopy_value, /* param_lcopy_value */ + param_uint_set_default, /* value_set_default */ + param_uint_validate, /* value_validate */ + param_uint_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecUInt); @@ -1220,16 +847,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_LONG, /* value_type */ NULL, /* finalize */ - param_long_init, /* param_init */ - NULL, /* param_free_value */ - param_long_validate, /* param_validate */ - param_long_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_LONG, /* collect_type */ - param_long_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_long_lcopy_value, /* param_lcopy_value */ + param_long_set_default, /* value_set_default */ + param_long_validate, /* value_validate */ + param_long_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecLong); @@ -1242,16 +864,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_ULONG, /* value_type */ NULL, /* finalize */ - param_ulong_init, /* param_init */ - NULL, /* param_free_value */ - param_ulong_validate, /* param_validate */ - param_ulong_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_LONG, /* collect_type */ - param_long_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_long_lcopy_value, /* param_lcopy_value */ + param_ulong_set_default, /* value_set_default */ + param_ulong_validate, /* value_validate */ + param_ulong_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecULong); @@ -1264,16 +881,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_ENUM, /* value_type */ param_spec_enum_finalize, /* finalize */ - param_enum_init, /* param_init */ - NULL, /* param_free_value */ - param_enum_validate, /* param_validate */ - param_long_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_enum_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_enum_lcopy_value, /* param_lcopy_value */ + param_enum_set_default, /* value_set_default */ + param_enum_validate, /* value_validate */ + param_long_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecEnum); @@ -1286,16 +898,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_FLAGS, /* value_type */ param_spec_flags_finalize,/* finalize */ - param_flags_init, /* param_init */ - NULL, /* param_free_value */ - param_flags_validate, /* param_validate */ - param_ulong_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_INT, /* collect_type */ - param_enum_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_enum_lcopy_value, /* param_lcopy_value */ + param_flags_set_default, /* value_set_default */ + param_flags_validate, /* value_validate */ + param_ulong_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecFlags); @@ -1308,16 +915,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_FLOAT, /* value_type */ NULL, /* finalize */ - param_float_init, /* param_init */ - NULL, /* param_free_value */ - param_float_validate, /* param_validate */ - param_float_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_DOUBLE, /* collect_type */ - param_float_collect_value,/* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_float_lcopy_value, /* param_lcopy_value */ + param_float_set_default, /* value_set_default */ + param_float_validate, /* value_validate */ + param_float_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecFloat); @@ -1330,16 +932,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { - NULL, /* finalize */ - param_double_init, /* param_init */ - NULL, /* param_free_value */ - param_double_validate, /* param_validate */ - param_double_values_cmp, /* param_values_cmp */ - NULL, /* param_copy_value */ - G_VALUE_COLLECT_DOUBLE, /* collect_type */ - param_double_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_double_lcopy_value, /* param_lcopy_value */ + G_TYPE_DOUBLE, /* value_type */ + NULL, /* finalize */ + param_double_set_default, /* value_set_default */ + param_double_validate, /* value_validate */ + param_double_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecDouble); @@ -1352,16 +949,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { + G_TYPE_STRING, /* value_type */ param_spec_string_finalize, /* finalize */ - param_string_init, /* param_init */ - param_string_free_value, /* param_free_value */ - param_string_validate, /* param_validate */ - param_string_values_cmp, /* param_values_cmp */ - param_string_copy_value, /* param_copy_value */ - G_VALUE_COLLECT_POINTER, /* collect_type */ - param_string_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_string_lcopy_value, /* param_lcopy_value */ + param_string_set_default, /* value_set_default */ + param_string_validate, /* value_validate */ + param_string_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecString); @@ -1374,16 +966,11 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ */ { static const ParamSpecClassInfo class_info = { - NULL, /* finalize */ - param_object_init, /* param_init */ - param_object_free_value, /* param_free_value */ - param_object_validate, /* param_validate */ - param_object_values_cmp, /* param_values_cmp */ - param_object_copy_value, /* param_copy_value */ - G_VALUE_COLLECT_POINTER, /* collect_type */ - param_object_collect_value, /* param_collect_value */ - G_VALUE_COLLECT_POINTER, /* lcopy_type */ - param_object_lcopy_value, /* param_lcopy_value */ + G_TYPE_OBJECT, /* value_type */ + NULL, /* finalize */ + param_object_set_default, /* value_set_default */ + param_object_validate, /* value_validate */ + param_object_values_cmp, /* values_cmp */ }; info.class_data = &class_info; info.instance_size = sizeof (GParamSpecObject); @@ -1392,307 +979,61 @@ g_param_spec_types_init (void) /* sync with glib-gparam.c */ g_assert (type == G_TYPE_PARAM_OBJECT); } - g_value_register_exchange_func (G_TYPE_PARAM_CHAR, G_TYPE_PARAM_UCHAR, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_CHAR, G_TYPE_PARAM_BOOL, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_CHAR, G_TYPE_PARAM_INT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_CHAR, G_TYPE_PARAM_UINT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_CHAR, G_TYPE_PARAM_ENUM, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_CHAR, G_TYPE_PARAM_FLAGS, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UCHAR, G_TYPE_PARAM_BOOL, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UCHAR, G_TYPE_PARAM_INT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UCHAR, G_TYPE_PARAM_UINT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UCHAR, G_TYPE_PARAM_ENUM, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UCHAR, G_TYPE_PARAM_FLAGS, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_BOOL, G_TYPE_PARAM_INT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_BOOL, G_TYPE_PARAM_UINT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_BOOL, G_TYPE_PARAM_ENUM, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_BOOL, G_TYPE_PARAM_FLAGS, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_INT, G_TYPE_PARAM_UINT, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_INT, G_TYPE_PARAM_ENUM, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_INT, G_TYPE_PARAM_FLAGS, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UINT, G_TYPE_PARAM_ENUM, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_UINT, G_TYPE_PARAM_FLAGS, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_CHAR, value_exch_long_int); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_UCHAR, value_exch_long_uint); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_BOOL, value_exch_long_int); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_INT, value_exch_long_int); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_UINT, value_exch_long_uint); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_ULONG, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_ENUM, value_exch_long_int); - g_value_register_exchange_func (G_TYPE_PARAM_LONG, G_TYPE_PARAM_FLAGS, value_exch_long_uint); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_CHAR, value_exch_ulong_int); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_UCHAR, value_exch_ulong_uint); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_BOOL, value_exch_ulong_int); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_INT, value_exch_ulong_int); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_UINT, value_exch_ulong_uint); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_ENUM, value_exch_ulong_int); - g_value_register_exchange_func (G_TYPE_PARAM_ULONG, G_TYPE_PARAM_FLAGS, value_exch_ulong_uint); - g_value_register_exchange_func (G_TYPE_PARAM_ENUM, G_TYPE_PARAM_FLAGS, value_exch_memcpy); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_CHAR, value_exch_float_int); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_UCHAR, value_exch_float_uint); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_BOOL, value_exch_float_int); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_INT, value_exch_float_int); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_UINT, value_exch_float_uint); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_LONG, value_exch_float_long); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_ULONG, value_exch_float_ulong); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_ENUM, value_exch_float_int); - g_value_register_exchange_func (G_TYPE_PARAM_FLOAT, G_TYPE_PARAM_FLAGS, value_exch_float_uint); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_CHAR, value_exch_double_int); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_UCHAR, value_exch_double_uint); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_BOOL, value_exch_double_int); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_INT, value_exch_double_int); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_UINT, value_exch_double_uint); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_LONG, value_exch_double_long); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_ULONG, value_exch_double_ulong); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_ENUM, value_exch_double_int); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_FLAGS, value_exch_double_uint); - g_value_register_exchange_func (G_TYPE_PARAM_DOUBLE, G_TYPE_PARAM_FLOAT, value_exch_double_float); -} - - -/* --- GValue functions --- */ -void -g_value_set_char (GValue *value, - gint8 v_char) -{ - g_return_if_fail (G_IS_VALUE_CHAR (value)); - - value->data[0].v_int = v_char; -} - -gint8 -g_value_get_char (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_CHAR (value), 0); - - return value->data[0].v_int; -} - -void -g_value_set_uchar (GValue *value, - guint8 v_uchar) -{ - g_return_if_fail (G_IS_VALUE_UCHAR (value)); - - value->data[0].v_uint = v_uchar; -} - -guint8 -g_value_get_uchar (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_UCHAR (value), 0); - - return value->data[0].v_uint; -} - -void -g_value_set_bool (GValue *value, - gboolean v_bool) -{ - g_return_if_fail (G_IS_VALUE_BOOL (value)); - - value->data[0].v_int = v_bool; -} - -gboolean -g_value_get_bool (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_BOOL (value), 0); - - return value->data[0].v_int; -} - -void -g_value_set_int (GValue *value, - gint v_int) -{ - g_return_if_fail (G_IS_VALUE_INT (value)); - - value->data[0].v_int = v_int; -} - -gint -g_value_get_int (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_INT (value), 0); - - return value->data[0].v_int; -} - -void -g_value_set_uint (GValue *value, - guint v_uint) -{ - g_return_if_fail (G_IS_VALUE_UINT (value)); - - value->data[0].v_uint = v_uint; -} - -guint -g_value_get_uint (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_UINT (value), 0); - - return value->data[0].v_uint; -} - -void -g_value_set_long (GValue *value, - glong v_long) -{ - g_return_if_fail (G_IS_VALUE_LONG (value)); - - value->data[0].v_long = v_long; -} - -glong -g_value_get_long (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_LONG (value), 0); - - return value->data[0].v_long; -} - -void -g_value_set_ulong (GValue *value, - gulong v_ulong) -{ - g_return_if_fail (G_IS_VALUE_ULONG (value)); - - value->data[0].v_ulong = v_ulong; -} - -gulong -g_value_get_ulong (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_ULONG (value), 0); - - return value->data[0].v_ulong; -} - -void -g_value_set_enum (GValue *value, - gint v_enum) -{ - g_return_if_fail (G_IS_VALUE_ENUM (value)); - - value->data[0].v_long = v_enum; -} - -gint -g_value_get_enum (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_ENUM (value), 0); - - return value->data[0].v_long; -} - -void -g_value_set_flags (GValue *value, - guint v_flags) -{ - g_return_if_fail (G_IS_VALUE_FLAGS (value)); - - value->data[0].v_ulong = v_flags; -} - -guint -g_value_get_flags (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_FLAGS (value), 0); - - return value->data[0].v_ulong; -} - -void -g_value_set_float (GValue *value, - gfloat v_float) -{ - g_return_if_fail (G_IS_VALUE_FLOAT (value)); - - value->data[0].v_float = v_float; -} - -gfloat -g_value_get_float (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_FLOAT (value), 0); - - return value->data[0].v_float; -} - -void -g_value_set_double (GValue *value, - gdouble v_double) -{ - g_return_if_fail (G_IS_VALUE_DOUBLE (value)); - - value->data[0].v_double = v_double; -} - -gdouble -g_value_get_double (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_DOUBLE (value), 0); - - return value->data[0].v_double; -} - -void -g_value_set_string (GValue *value, - const gchar *v_string) -{ - g_return_if_fail (G_IS_VALUE_STRING (value)); - - g_free (value->data[0].v_pointer); - value->data[0].v_pointer = g_strdup (v_string); -} - -gchar* -g_value_get_string (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL); - - return value->data[0].v_pointer; -} - -gchar* -g_value_dup_string (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL); - - return g_strdup (value->data[0].v_pointer); -} - -void -g_value_set_object (GValue *value, - GObject *v_object) -{ - g_return_if_fail (G_IS_VALUE_OBJECT (value)); - if (v_object) - g_return_if_fail (G_IS_OBJECT (v_object)); - - if (value->data[0].v_pointer) - g_object_unref (value->data[0].v_pointer); - value->data[0].v_pointer = v_object; - if (value->data[0].v_pointer) - g_object_ref (value->data[0].v_pointer); -} - -GObject* -g_value_get_object (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL); - - return value->data[0].v_pointer; -} - -GObject* -g_value_dup_object (GValue *value) -{ - g_return_val_if_fail (G_IS_VALUE_OBJECT (value), NULL); - - return value->data[0].v_pointer ? g_object_ref (value->data[0].v_pointer) : NULL; + g_value_register_exchange_func (G_TYPE_CHAR, G_TYPE_UCHAR, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_CHAR, G_TYPE_BOOLEAN, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_CHAR, G_TYPE_INT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_CHAR, G_TYPE_UINT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_CHAR, G_TYPE_ENUM, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_CHAR, G_TYPE_FLAGS, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UCHAR, G_TYPE_BOOLEAN, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UCHAR, G_TYPE_INT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UCHAR, G_TYPE_UINT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UCHAR, G_TYPE_ENUM, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UCHAR, G_TYPE_FLAGS, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_INT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_UINT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_ENUM, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_BOOLEAN, G_TYPE_FLAGS, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_INT, G_TYPE_UINT, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_INT, G_TYPE_ENUM, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_INT, G_TYPE_FLAGS, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UINT, G_TYPE_ENUM, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_UINT, G_TYPE_FLAGS, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_CHAR, value_exch_long_int); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_UCHAR, value_exch_long_uint); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_BOOLEAN, value_exch_long_int); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_INT, value_exch_long_int); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_UINT, value_exch_long_uint); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_ULONG, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_ENUM, value_exch_long_int); + g_value_register_exchange_func (G_TYPE_LONG, G_TYPE_FLAGS, value_exch_long_uint); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_CHAR, value_exch_ulong_int); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_UCHAR, value_exch_ulong_uint); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_BOOLEAN, value_exch_ulong_int); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_INT, value_exch_ulong_int); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_UINT, value_exch_ulong_uint); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_ENUM, value_exch_ulong_int); + g_value_register_exchange_func (G_TYPE_ULONG, G_TYPE_FLAGS, value_exch_ulong_uint); + g_value_register_exchange_func (G_TYPE_ENUM, G_TYPE_FLAGS, value_exch_memcpy); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_CHAR, value_exch_float_int); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_UCHAR, value_exch_float_uint); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_BOOLEAN, value_exch_float_int); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_INT, value_exch_float_int); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_UINT, value_exch_float_uint); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_LONG, value_exch_float_long); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_ULONG, value_exch_float_ulong); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_ENUM, value_exch_float_int); + g_value_register_exchange_func (G_TYPE_FLOAT, G_TYPE_FLAGS, value_exch_float_uint); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_CHAR, value_exch_double_int); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_UCHAR, value_exch_double_uint); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_BOOLEAN, value_exch_double_int); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_INT, value_exch_double_int); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_UINT, value_exch_double_uint); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_LONG, value_exch_double_long); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_ULONG, value_exch_double_ulong); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_ENUM, value_exch_double_int); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_FLAGS, value_exch_double_uint); + g_value_register_exchange_func (G_TYPE_DOUBLE, G_TYPE_FLOAT, value_exch_double_float); } @@ -1742,17 +1083,17 @@ g_param_spec_uchar (const gchar *name, } GParamSpec* -g_param_spec_bool (const gchar *name, - const gchar *nick, - const gchar *blurb, - gboolean default_value, - GParamFlags flags) -{ - GParamSpecBool *bspec = g_param_spec_internal (G_TYPE_PARAM_BOOL, - name, - nick, - blurb, - flags); +g_param_spec_boolean (const gchar *name, + const gchar *nick, + const gchar *blurb, + gboolean default_value, + GParamFlags flags) +{ + GParamSpecBoolean *bspec = g_param_spec_internal (G_TYPE_PARAM_BOOLEAN, + name, + nick, + blurb, + flags); bspec->default_value = default_value; diff --git a/gobject/gparamspecs.h b/gobject/gparamspecs.h index 1becdef..01219d0 100644 --- a/gobject/gparamspecs.h +++ b/gobject/gparamspecs.h @@ -33,61 +33,48 @@ extern "C" { /* --- type macros --- */ -#define G_IS_VALUE_CHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_CHAR)) #define G_IS_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_CHAR)) #define G_PARAM_SPEC_CHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_CHAR, GParamSpecChar)) -#define G_IS_VALUE_UCHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_UCHAR)) #define G_IS_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UCHAR)) #define G_PARAM_SPEC_UCHAR(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UCHAR, GParamSpecUChar)) -#define G_IS_VALUE_BOOL(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_BOOL)) -#define G_IS_PARAM_SPEC_BOOL(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOL)) -#define G_PARAM_SPEC_BOOL(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOL, GParamSpecBool)) -#define G_IS_VALUE_INT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_INT)) +#define G_IS_PARAM_SPEC_BOOLEAN(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_BOOLEAN)) +#define G_PARAM_SPEC_BOOLEAN(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_BOOLEAN, GParamSpecBoolean)) #define G_IS_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_INT)) #define G_PARAM_SPEC_INT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_INT, GParamSpecInt)) -#define G_IS_VALUE_UINT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_UINT)) #define G_IS_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_UINT)) #define G_PARAM_SPEC_UINT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_UINT, GParamSpecUInt)) -#define G_IS_VALUE_LONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_LONG)) #define G_IS_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_LONG)) #define G_PARAM_SPEC_LONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_LONG, GParamSpecLong)) -#define G_IS_VALUE_ULONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_ULONG)) #define G_IS_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ULONG)) #define G_PARAM_SPEC_ULONG(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ULONG, GParamSpecULong)) -#define G_IS_VALUE_ENUM(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_ENUM)) #define G_IS_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_ENUM)) #define G_PARAM_SPEC_ENUM(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_ENUM, GParamSpecEnum)) -#define G_IS_VALUE_FLAGS(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_FLAGS)) #define G_IS_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLAGS)) #define G_PARAM_SPEC_FLAGS(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLAGS, GParamSpecFlags)) -#define G_IS_VALUE_FLOAT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_FLOAT)) #define G_IS_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_FLOAT)) #define G_PARAM_SPEC_FLOAT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_FLOAT, GParamSpecFloat)) -#define G_IS_VALUE_DOUBLE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_DOUBLE)) #define G_IS_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_DOUBLE)) #define G_PARAM_SPEC_DOUBLE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_DOUBLE, GParamSpecDouble)) -#define G_IS_VALUE_STRING(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_STRING)) #define G_IS_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_STRING)) #define G_PARAM_SPEC_STRING(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_STRING, GParamSpecString)) -#define G_IS_VALUE_OBJECT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM_OBJECT)) #define G_IS_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OBJECT)) #define G_PARAM_SPEC_OBJECT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OBJECT, GParamSpecObject)) /* --- typedefs & structures --- */ -typedef struct _GParamSpecChar GParamSpecChar; -typedef struct _GParamSpecUChar GParamSpecUChar; -typedef struct _GParamSpecBool GParamSpecBool; -typedef struct _GParamSpecInt GParamSpecInt; -typedef struct _GParamSpecUInt GParamSpecUInt; -typedef struct _GParamSpecLong GParamSpecLong; -typedef struct _GParamSpecULong GParamSpecULong; -typedef struct _GParamSpecEnum GParamSpecEnum; -typedef struct _GParamSpecFlags GParamSpecFlags; -typedef struct _GParamSpecFloat GParamSpecFloat; -typedef struct _GParamSpecDouble GParamSpecDouble; -typedef struct _GParamSpecString GParamSpecString; -typedef struct _GParamSpecObject GParamSpecObject; +typedef struct _GParamSpecChar GParamSpecChar; +typedef struct _GParamSpecUChar GParamSpecUChar; +typedef struct _GParamSpecBoolean GParamSpecBoolean; +typedef struct _GParamSpecInt GParamSpecInt; +typedef struct _GParamSpecUInt GParamSpecUInt; +typedef struct _GParamSpecLong GParamSpecLong; +typedef struct _GParamSpecULong GParamSpecULong; +typedef struct _GParamSpecEnum GParamSpecEnum; +typedef struct _GParamSpecFlags GParamSpecFlags; +typedef struct _GParamSpecFloat GParamSpecFloat; +typedef struct _GParamSpecDouble GParamSpecDouble; +typedef struct _GParamSpecString GParamSpecString; +typedef struct _GParamSpecObject GParamSpecObject; struct _GParamSpecChar { GParamSpec parent_instance; @@ -104,7 +91,7 @@ struct _GParamSpecUChar guint8 maximum; guint8 default_value; }; -struct _GParamSpecBool +struct _GParamSpecBoolean { GParamSpec parent_instance; @@ -193,50 +180,6 @@ struct _GParamSpecObject }; -/* --- GValue prototypes --- */ -void g_value_set_char (GValue *value, - gint8 v_char); -gint8 g_value_get_char (GValue *value); -void g_value_set_uchar (GValue *value, - guint8 v_uchar); -guint8 g_value_get_uchar (GValue *value); -void g_value_set_bool (GValue *value, - gboolean v_bool); -gboolean g_value_get_bool (GValue *value); -void g_value_set_int (GValue *value, - gint v_int); -gint g_value_get_int (GValue *value); -void g_value_set_uint (GValue *value, - guint v_uint); -guint g_value_get_uint (GValue *value); -void g_value_set_long (GValue *value, - glong v_long); -glong g_value_get_long (GValue *value); -void g_value_set_ulong (GValue *value, - gulong v_ulong); -gulong g_value_get_ulong (GValue *value); -void g_value_set_enum (GValue *value, - gint v_enum); -gint g_value_get_enum (GValue *value); -void g_value_set_flags (GValue *value, - guint v_flags); -guint g_value_get_flags (GValue *value); -void g_value_set_float (GValue *value, - gfloat v_float); -gfloat g_value_get_float (GValue *value); -void g_value_set_double (GValue *value, - gdouble v_double); -gdouble g_value_get_double (GValue *value); -void g_value_set_string (GValue *value, - const gchar *v_string); -gchar* g_value_get_string (GValue *value); -gchar* g_value_dup_string (GValue *value); -void g_value_set_object (GValue *value, - GObject *v_object); -GObject* g_value_get_object (GValue *value); -GObject* g_value_dup_object (GValue *value); - - /* --- GParamSpec prototypes --- */ GParamSpec* g_param_spec_char (const gchar *name, const gchar *nick, @@ -252,7 +195,7 @@ GParamSpec* g_param_spec_uchar (const gchar *name, guint8 maximum, guint8 default_value, GParamFlags flags); -GParamSpec* g_param_spec_bool (const gchar *name, +GParamSpec* g_param_spec_boolean (const gchar *name, const gchar *nick, const gchar *blurb, gboolean default_value, diff --git a/gobject/gtype.c b/gobject/gtype.c index b00e58b..80394d5 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -18,8 +18,6 @@ */ #include "gtype.h" -#include "genums.h" -#include "gobject.h" #include #define FIXME_DISABLE_PREALLOCATIONS @@ -45,7 +43,7 @@ G_TYPE_FLAG_DEEP_DERIVABLE) #define g_type_plugin_ref(p) ((p)->vtable->plugin_ref (p)) #define g_type_plugin_unref(p) ((p)->vtable->plugin_unref (p)) -#define g_type_plugin_complete_type_info(p,t,i) ((p)->vtable->complete_type_info ((p), (t), (i))) +#define g_type_plugin_complete_type_info(p,t,i,v) ((p)->vtable->complete_type_info ((p), (t), (i), (v))) #define g_type_plugin_complete_interface_info(p,f,t,i) ((p)->vtable->complete_interface_info ((p), (f), (t), (i))) typedef struct _TypeNode TypeNode; @@ -61,10 +59,13 @@ typedef struct _IFaceHolder IFaceHolder; /* --- prototypes --- */ static inline GTypeFundamentalInfo* type_node_fundamental_info (TypeNode *node); static void type_data_make (TypeNode *node, - const GTypeInfo *info); + const GTypeInfo *info, + const GTypeValueTable *value_table); static inline void type_data_ref (TypeNode *node); -static inline void type_data_unref (TypeNode *node); -static void type_data_last_unref (GType type); +static inline void type_data_unref (TypeNode *node, + gboolean uncached); +static void type_data_last_unref (GType type, + gboolean uncached); /* --- structures --- */ @@ -83,7 +84,7 @@ struct _TypeNode GData *static_gdata; union { IFaceEntry *iface_entries; - IFaceHolder *iholders; + IFaceHolder *iface_conformants; } private; GType supers[1]; /* flexible array */ }; @@ -99,21 +100,27 @@ struct _IFaceHolder GTypePlugin *plugin; IFaceHolder *next; }; +struct _IFaceEntry +{ + GType iface_type; + GTypeInterface *vtable; +}; struct _CommonData { - guint ref_count; + guint ref_count; + GTypeValueTable *value_table; }; struct _IFaceData { CommonData common; - guint vtable_size; + guint16 vtable_size; GBaseInitFunc vtable_init_base; GBaseFinalizeFunc vtable_finalize_base; }; struct _ClassData { CommonData common; - guint class_size; + guint16 class_size; GBaseInitFunc class_init_base; GBaseFinalizeFunc class_finalize_base; GClassInitFunc class_init; @@ -124,7 +131,7 @@ struct _ClassData struct _InstanceData { CommonData common; - guint class_size; + guint16 class_size; GBaseInitFunc class_init_base; GBaseFinalizeFunc class_finalize_base; GClassInitFunc class_init; @@ -143,11 +150,15 @@ union _TypeData ClassData class; InstanceData instance; }; -struct _IFaceEntry -{ - GType iface_type; - GTypeInterface *vtable; -}; +typedef struct { + gpointer cache_data; + GTypeClassCacheFunc cache_func; +} ClassCacheFunc; + + +/* --- variables --- */ +static guint n_class_cache_funcs = 0; +static ClassCacheFunc *class_cache_funcs = NULL; /* --- externs --- */ @@ -193,7 +204,7 @@ type_node_any_new (TypeNode *pnode, g_type_nodes[ftype] = g_renew (TypeNode*, g_type_nodes[ftype], 1 << g_bit_storage (g_branch_seqnos[ftype] - 1)); if (!pnode) - node_size += sizeof (GTypeFundamentalInfo); /* fundamental type */ + node_size += sizeof (GTypeFundamentalInfo); /* fundamental type info */ node_size += SIZEOF_BASE_TYPE_NODE (); /* TypeNode structure */ node_size += sizeof (GType[1 + n_supers + 1]); /* self + anchestors + 0 for ->supers[] */ node = g_malloc0 (node_size); @@ -213,7 +224,7 @@ type_node_any_new (TypeNode *pnode, node->n_ifaces = 0; if (node->is_iface) - node->private.iholders = NULL; + node->private.iface_conformants = NULL; else node->private.iface_entries = NULL; } @@ -229,7 +240,7 @@ type_node_any_new (TypeNode *pnode, if (node->is_iface) { node->n_ifaces = 0; - node->private.iholders = NULL; + node->private.iface_conformants = NULL; } else { @@ -315,8 +326,8 @@ type_node_new (TypeNode *pnode, } static inline IFaceEntry* -type_lookup_iface_entry (TypeNode *node, - TypeNode *iface) +type_lookup_iface_entry (TypeNode *node, + TypeNode *iface) { if (iface->is_iface && node->n_ifaces) { @@ -476,10 +487,59 @@ check_derivation (GType parent_type, } static gboolean -check_type_info (TypeNode *pnode, - GType ftype, - const gchar *type_name, - const GTypeInfo *info) +check_value_table (const gchar *type_name, + const GTypeValueTable *value_table) +{ + if (!value_table) + return FALSE; + else if (value_table->value_init == NULL) + { + if (value_table->value_free || value_table->value_copy || + value_table->collect_type || value_table->collect_value || + value_table->lcopy_type || value_table->lcopy_value) + g_warning ("cannot handle uninitializable values of type `%s'", + type_name); + + return FALSE; + } + else /* value_table->value_init != NULL */ + { + if (!value_table->value_free) + { + /* +++ optional +++ + * g_warning ("missing `value_free()' for type `%s'", type_name); + * return FALSE; + */ + } + if (!value_table->value_copy) + { + g_warning ("missing `value_copy()' for type `%s'", type_name); + return FALSE; + } + if ((value_table->collect_type || value_table->collect_value) && + (!value_table->collect_type || !value_table->collect_value)) + { + g_warning ("one of `collect_type' and `collect_value()' is unspecified for type `%s'", + type_name); + return FALSE; + } + if ((value_table->lcopy_type || value_table->lcopy_value) && + (!value_table->lcopy_type || !value_table->lcopy_value)) + { + g_warning ("one of `lcopy_type' and `lcopy_value()' is unspecified for type `%s'", + type_name); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +check_type_info (TypeNode *pnode, + GType ftype, + const gchar *type_name, + const GTypeInfo *info) { GTypeFundamentalInfo *finfo = type_node_fundamental_info (LOOKUP_TYPE_NODE (ftype)); gboolean is_interface = G_TYPE_IS_INTERFACE (ftype); @@ -636,16 +696,37 @@ check_interface_info (TypeNode *iface, /* --- type info (type node data) --- */ static void -type_data_make (TypeNode *node, - const GTypeInfo *info) +type_data_make (TypeNode *node, + const GTypeInfo *info, + const GTypeValueTable *value_table) { - TypeData *data = NULL; - + TypeData *data; + GTypeValueTable *vtable = NULL; + guint vtable_size = 0; + g_assert (node->data == NULL && info != NULL); + if (!value_table) + { + TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node)); + + if (pnode) + vtable = pnode->data->common.value_table; + else + { + static const GTypeValueTable zero_vtable = { NULL, }; + + value_table = &zero_vtable; + } + } + if (value_table) + vtable_size = sizeof (GTypeValueTable); + if (node->is_instantiatable) /* carefull, is_instantiatable is also is_classed */ { - data = g_malloc0 (sizeof (InstanceData)); + data = g_malloc0 (sizeof (InstanceData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (InstanceData)); data->instance.class_size = info->class_size; data->instance.class_init_base = info->base_init; data->instance.class_finalize_base = info->base_finalize; @@ -663,7 +744,9 @@ type_data_make (TypeNode *node, } else if (node->is_classed) /* only classed */ { - data = g_malloc0 (sizeof (ClassData)); + data = g_malloc0 (sizeof (ClassData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (ClassData)); data->class.class_size = info->class_size; data->class.class_init_base = info->base_init; data->class.class_finalize_base = info->base_finalize; @@ -674,16 +757,28 @@ type_data_make (TypeNode *node, } else if (node->is_iface) { - data = g_malloc0 (sizeof (IFaceData)); + data = g_malloc0 (sizeof (IFaceData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (IFaceData)); data->iface.vtable_size = info->class_size; data->iface.vtable_init_base = info->base_init; data->iface.vtable_finalize_base = info->base_finalize; } else - data = g_malloc0 (sizeof (CommonData)); - + { + data = g_malloc0 (sizeof (CommonData) + vtable_size); + if (vtable_size) + vtable = G_STRUCT_MEMBER_P (data, sizeof (CommonData)); + } + node->data = data; node->data->common.ref_count = 1; + + if (vtable_size) + *vtable = *value_table; + node->data->common.value_table = vtable; + + g_assert (node->data->common.value_table != NULL); // FIXME: paranoid } static inline void @@ -692,18 +787,21 @@ type_data_ref (TypeNode *node) if (!node->data) { TypeNode *pnode = LOOKUP_TYPE_NODE (NODE_PARENT_TYPE (node)); - GTypeInfo tmpinfo; + GTypeInfo tmp_info; + GTypeValueTable tmp_value_table; g_assert (node->plugin != NULL); if (pnode) type_data_ref (pnode); - memset (&tmpinfo, 0, sizeof (tmpinfo)); + memset (&tmp_info, 0, sizeof (tmp_info)); + memset (&tmp_value_table, 0, sizeof (tmp_value_table)); g_type_plugin_ref (node->plugin); - g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmpinfo); - check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmpinfo); - type_data_make (node, &tmpinfo); + g_type_plugin_complete_type_info (node->plugin, NODE_TYPE (node), &tmp_info, &tmp_value_table); + check_type_info (pnode, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), NODE_NAME (node), &tmp_info); + type_data_make (node, &tmp_info, + check_value_table (NODE_NAME (node), &tmp_value_table) ? &tmp_value_table : NULL); } else { @@ -714,7 +812,8 @@ type_data_ref (TypeNode *node) } static inline void -type_data_unref (TypeNode *node) +type_data_unref (TypeNode *node, + gboolean uncached) { g_assert (node->data && node->data->common.ref_count); @@ -729,7 +828,7 @@ type_data_unref (TypeNode *node) return; } - type_data_last_unref (NODE_TYPE (node)); + type_data_last_unref (NODE_TYPE (node), uncached); } } @@ -769,8 +868,8 @@ type_add_interface (TypeNode *node, */ g_assert (node->is_instantiatable && iface->is_iface && ((info && !plugin) || (!info && plugin))); - iholder->next = iface->private.iholders; - iface->private.iholders = iholder; + iholder->next = iface->private.iface_conformants; + iface->private.iface_conformants = iholder; iholder->instance_type = NODE_TYPE (node); iholder->info = info ? g_memdup (info, sizeof (*info)) : NULL; iholder->plugin = plugin; @@ -782,7 +881,7 @@ static IFaceHolder* type_iface_retrive_holder_info (TypeNode *iface, GType instance_type) { - IFaceHolder *iholder = iface->private.iholders; + IFaceHolder *iholder = iface->private.iface_conformants; g_assert (iface->is_iface); @@ -791,17 +890,17 @@ type_iface_retrive_holder_info (TypeNode *iface, if (!iholder->info) { - GInterfaceInfo tmpinfo; + GInterfaceInfo tmp_info; g_assert (iholder->plugin != NULL); type_data_ref (iface); - memset (&tmpinfo, 0, sizeof (tmpinfo)); + memset (&tmp_info, 0, sizeof (tmp_info)); g_type_plugin_ref (iholder->plugin); - g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmpinfo); - check_interface_info (iface, instance_type, &tmpinfo); - iholder->info = g_memdup (&tmpinfo, sizeof (tmpinfo)); + g_type_plugin_complete_interface_info (iholder->plugin, NODE_TYPE (iface), instance_type, &tmp_info); + check_interface_info (iface, instance_type, &tmp_info); + iholder->info = g_memdup (&tmp_info, sizeof (tmp_info)); } return iholder; @@ -811,7 +910,7 @@ static void type_iface_blow_holder_info (TypeNode *iface, GType instance_type) { - IFaceHolder *iholder = iface->private.iholders; + IFaceHolder *iholder = iface->private.iface_conformants; g_assert (iface->is_iface); @@ -824,7 +923,7 @@ type_iface_blow_holder_info (TypeNode *iface, iholder->info = NULL; g_type_plugin_unref (iholder->plugin); - type_data_unref (iface); + type_data_unref (iface, FALSE); } } @@ -947,7 +1046,7 @@ type_iface_vtable_finalize (TypeNode *iface, GTypeInterface *vtable) { IFaceEntry *entry = type_lookup_iface_entry (node, iface); - IFaceHolder *iholder = iface->private.iholders; + IFaceHolder *iholder = iface->private.iface_conformants; g_assert (entry && entry->vtable == vtable); @@ -1081,10 +1180,11 @@ type_data_finalize_class (TypeNode *node, } static void -type_data_last_unref (GType type) +type_data_last_unref (GType type, + gboolean uncached) { TypeNode *node = LOOKUP_TYPE_NODE (type); - + g_return_if_fail (node != NULL && node->plugin != NULL); if (!node->data || node->data->common.ref_count == 0) @@ -1093,12 +1193,22 @@ type_data_last_unref (GType type) type_descriptive_name (type)); return; } - + + if (node->is_classed && node->data && node->data->class.class) + { + guint i; + + for (i = 0; i < n_class_cache_funcs; i++) + if (class_cache_funcs[i].cache_func (class_cache_funcs[i].cache_data, node->data->class.class)) + break; + } + if (node->data->common.ref_count > 1) /* may have been re-referenced meanwhile */ node->data->common.ref_count -= 1; else { GType ptype = NODE_PARENT_TYPE (node); + TypeData *tdata; node->data->common.ref_count = 0; @@ -1108,43 +1218,79 @@ type_data_last_unref (GType type) node->data->instance.mem_chunk = NULL; } - if (node->is_classed && node->data->class.class) + tdata = node->data; + if (node->is_classed && tdata->class.class) { - ClassData *cdata = &node->data->class; - if (node->n_ifaces) type_data_finalize_class_ifaces (node); node->data = NULL; - type_data_finalize_class (node, cdata); - g_free (cdata); + type_data_finalize_class (node, &tdata->class); } else - { - g_free (node->data); - node->data = NULL; - } + node->data = NULL; + + g_free (tdata); if (ptype) - type_data_unref (LOOKUP_TYPE_NODE (ptype)); + type_data_unref (LOOKUP_TYPE_NODE (ptype), FALSE); g_type_plugin_unref (node->plugin); } } +void +g_type_add_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func) +{ + guint i; + + g_return_if_fail (cache_func != NULL); + + i = n_class_cache_funcs++; + class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs); + class_cache_funcs[i].cache_data = cache_data; + class_cache_funcs[i].cache_func = cache_func; +} + +void +g_type_remove_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func) +{ + guint i; + + g_return_if_fail (cache_func != NULL); + + for (i = 0; i < n_class_cache_funcs; i++) + if (class_cache_funcs[i].cache_data == cache_data && + class_cache_funcs[i].cache_func == cache_func) + { + n_class_cache_funcs--; + g_memmove (class_cache_funcs + i, + class_cache_funcs + i + 1, + sizeof (class_cache_funcs[0]) * (n_class_cache_funcs - i)); + class_cache_funcs = g_renew (ClassCacheFunc, class_cache_funcs, n_class_cache_funcs); + + return; + } + + g_warning (G_STRLOC ": cannot remove unregistered class cache func %p with data %p", + cache_func, cache_data); +} + /* --- type registration --- */ GType g_type_register_fundamental (GType type_id, const gchar *type_name, - const GTypeFundamentalInfo *finfo, - const GTypeInfo *info) + const GTypeInfo *info, + const GTypeFundamentalInfo *finfo) { GTypeFundamentalInfo *node_finfo; TypeNode *node; g_return_val_if_fail (type_id > 0, 0); g_return_val_if_fail (type_name != NULL, 0); - g_return_val_if_fail (finfo != NULL, 0); g_return_val_if_fail (info != NULL, 0); + g_return_val_if_fail (finfo != NULL, 0); if (!check_type_name (type_name)) return 0; @@ -1172,12 +1318,11 @@ g_type_register_fundamental (GType type_id, node = type_node_fundamental_new (type_id, type_name, finfo->type_flags); node_finfo = type_node_fundamental_info (node); - node_finfo->n_collect_bytes = finfo->n_collect_bytes; // FIXME: check max bytes - node_finfo->param_collector = finfo->param_collector; if (!check_type_info (NULL, G_TYPE_FUNDAMENTAL (NODE_TYPE (node)), type_name, info)) return NODE_TYPE (node); - type_data_make (node, info); + type_data_make (node, info, + check_value_table (type_name, info->value_table) ? info->value_table : NULL); return NODE_TYPE (node); } @@ -1213,7 +1358,8 @@ g_type_register_static (GType parent_type, node = type_node_new (pnode, type_name, NULL); type = NODE_TYPE (node); - type_data_make (node, info); + type_data_make (node, info, + check_value_table (type_name, info->value_table) ? info->value_table : NULL); return type; } @@ -1333,7 +1479,24 @@ g_type_class_unref (gpointer g_class) node = LOOKUP_TYPE_NODE (class->g_type); if (node && node->is_classed && node->data && node->data->class.class == class && node->data->common.ref_count > 0) - type_data_unref (node); + type_data_unref (node, FALSE); + else + g_warning ("cannot unreference class of invalid (unclassed) type `%s'", + type_descriptive_name (class->g_type)); +} + +void +g_type_class_unref_uncached (gpointer g_class) +{ + TypeNode *node; + GTypeClass *class = g_class; + + g_return_if_fail (g_class != NULL); + + node = LOOKUP_TYPE_NODE (class->g_type); + if (node && node->is_classed && node->data && + node->data->class.class == class && node->data->common.ref_count > 0) + type_data_unref (node, TRUE); else g_warning ("cannot unreference class of invalid (unclassed) type `%s'", type_descriptive_name (class->g_type)); @@ -1391,6 +1554,17 @@ g_type_interface_peek (gpointer instance_class, return NULL; } +GTypeValueTable* +g_type_value_table_peek (GType type) +{ + TypeNode *node = LOOKUP_TYPE_NODE (type); + + if (node && node->data && node->data->common.ref_count > 0) + return node->data->common.value_table->value_init ? node->data->common.value_table : NULL; + else + return NULL; +} + gchar* g_type_name (GType type) { @@ -1769,9 +1943,11 @@ g_type_check_class_cast (GTypeClass *type_class, /* --- foreign prototypes --- */ -extern void g_param_types_init (void); /* sync with glib-gparam.c */ -extern void g_enum_types_init (void); /* sync with glib-genums.c */ -extern void g_object_type_init (void); /* sync with glib-gobject.c */ +extern void g_value_types_init (void); /* sync with gvaluetypes.c */ +extern void g_enum_types_init (void); /* sync with genums.c */ +extern void g_param_type_init (void); /* sync with gparam.c */ +extern void g_object_type_init (void); /* sync with gobject.c */ +extern void g_param_spec_types_init (void); /* sync with gparamspecs.c */ /* --- initialization --- */ @@ -1808,18 +1984,26 @@ g_type_init (void) memset (&info, 0, sizeof (info)); node = type_node_fundamental_new (G_TYPE_INTERFACE, "GInterface", G_TYPE_FLAG_DERIVABLE); type = NODE_TYPE (node); - type_data_make (node, &info); + type_data_make (node, &info, NULL); // FIXME g_assert (type == G_TYPE_INTERFACE); + /* G_TYPE_* value types + */ + g_value_types_init (); + /* G_TYPE_ENUM & G_TYPE_FLAGS */ g_enum_types_init (); - + /* G_TYPE_PARAM */ - g_param_types_init (); + g_param_type_init (); /* G_TYPE_OBJECT */ g_object_type_init (); + + /* G_TYPE_PARAM_* pspec types + */ + g_param_spec_types_init (); } diff --git a/gobject/gtype.h b/gobject/gtype.h index 66b8a90..8c60374 100644 --- a/gobject/gtype.h +++ b/gobject/gtype.h @@ -47,36 +47,42 @@ typedef enum /*< skip >*/ G_TYPE_INTERFACE, /* GLib type ids */ + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_BOOLEAN, + G_TYPE_INT, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, G_TYPE_ENUM, G_TYPE_FLAGS, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, G_TYPE_PARAM, G_TYPE_OBJECT, - /* reserved type ids, mail gtk-devel-list@redhat.com for reservations */ - G_TYPE_BSE_PROCEDURE, - G_TYPE_GLE_GOBJECT, - /* the following reserved ids should vanish soon */ - G_TYPE_GTK_CHAR, - G_TYPE_GTK_UCHAR, - G_TYPE_GTK_BOOL, - G_TYPE_GTK_INT, - G_TYPE_GTK_UINT, - G_TYPE_GTK_LONG, - G_TYPE_GTK_ULONG, - G_TYPE_GTK_FLOAT, - G_TYPE_GTK_DOUBLE, - G_TYPE_GTK_STRING, G_TYPE_GTK_BOXED, G_TYPE_GTK_POINTER, G_TYPE_GTK_SIGNAL, + /* reserved fundamental type ids, + * mail gtk-devel-list@redhat.com for reservations + */ + G_TYPE_BSE_PROCEDURE, + G_TYPE_BSE_TIME, + G_TYPE_BSE_NOTE, + G_TYPE_BSE_DOTS, + G_TYPE_GLE_GOBJECT, + G_TYPE_LAST_RESERVED_FUNDAMENTAL, /* derived type ids */ + /* FIXME: G_TYPE_PARAM_INTERFACE */ G_TYPE_PARAM_CHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 1), G_TYPE_PARAM_UCHAR = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 2), - G_TYPE_PARAM_BOOL = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3), + G_TYPE_PARAM_BOOLEAN = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 3), G_TYPE_PARAM_INT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 4), G_TYPE_PARAM_UINT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 5), G_TYPE_PARAM_LONG = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 6), @@ -86,6 +92,7 @@ typedef enum /*< skip >*/ G_TYPE_PARAM_FLOAT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 10), G_TYPE_PARAM_DOUBLE = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 11), G_TYPE_PARAM_STRING = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 12), + /* FIXME: G_TYPE_PARAM_PARAM */ G_TYPE_PARAM_OBJECT = G_TYPE_DERIVE_ID (G_TYPE_PARAM, 13) } GTypeFundamentals; @@ -103,7 +110,8 @@ typedef enum /*< skip >*/ /* Typedefs */ typedef guint32 GType; -typedef struct _GParam GParam; +typedef struct _GValue GValue; +typedef union _GTypeCValue GTypeCValue; typedef struct _GTypePlugin GTypePlugin; typedef struct _GTypePluginVTable GTypePluginVTable; typedef struct _GTypeClass GTypeClass; @@ -112,20 +120,24 @@ typedef struct _GTypeInstance GTypeInstance; typedef struct _GTypeInfo GTypeInfo; typedef struct _GTypeFundamentalInfo GTypeFundamentalInfo; typedef struct _GInterfaceInfo GInterfaceInfo; +typedef struct _GTypeValueTable GTypeValueTable; /* Basic Type Structures */ struct _GTypeClass { + /*< private >*/ GType g_type; }; struct _GTypeInstance { + /*< private >*/ GTypeClass *g_class; }; struct _GTypeInterface { + /*< private >*/ GType g_type; /* iface type */ GType g_instance_type; }; @@ -140,6 +152,7 @@ struct _GTypeInterface #define G_TYPE_INSTANCE_GET_CLASS(instance, g_type, c_type) (_G_TYPE_IGC ((instance), c_type)) #define G_TYPE_FROM_INSTANCE(instance) (G_TYPE_FROM_CLASS (((GTypeInstance*) (instance))->g_class)) #define G_TYPE_FROM_CLASS(g_class) (((GTypeClass*) (g_class))->g_type) +#define G_TYPE_FROM_INTERFACE(g_iface) (((GTypeInterface*) (g_iface))->g_type) /* --- prototypes --- */ @@ -166,7 +179,7 @@ GType* g_type_children (GType type, guint *n_children); GType* g_type_interfaces (GType type, guint *n_interfaces); -/* per-type *static* data */ +/* per-type _static_ data */ void g_type_set_qdata (GType type, GQuark quark, gpointer data); @@ -175,30 +188,30 @@ gpointer g_type_get_qdata (GType type, /* --- type registration --- */ -typedef void (*GBaseInitFunc) (gpointer g_class); -typedef void (*GBaseFinalizeFunc) (gpointer g_class); -typedef void (*GClassInitFunc) (gpointer g_class, - gpointer class_data); -typedef void (*GClassFinalizeFunc) (gpointer g_class, - gpointer class_data); -typedef void (*GInstanceInitFunc) (GTypeInstance *instance, - gpointer g_class); -typedef void (*GInterfaceInitFunc) (gpointer g_iface, - gpointer iface_data); -typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface, - gpointer iface_data); -typedef gchar* (*GTypeParamCollector) (GParam *param, - guint n_bytes, - guint8 *bytes); -typedef void (*GTypePluginRef) (GTypePlugin *plugin); -typedef void (*GTypePluginUnRef) (GTypePlugin *plugin); -typedef void (*GTypePluginFillTypeInfo) (GTypePlugin *plugin, - GType g_type, - GTypeInfo *info); -typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin *plugin, - GType interface_type, - GType instance_type, - GInterfaceInfo *info); +typedef void (*GBaseInitFunc) (gpointer g_class); +typedef void (*GBaseFinalizeFunc) (gpointer g_class); +typedef void (*GClassInitFunc) (gpointer g_class, + gpointer class_data); +typedef void (*GClassFinalizeFunc) (gpointer g_class, + gpointer class_data); +typedef void (*GInstanceInitFunc) (GTypeInstance *instance, + gpointer g_class); +typedef void (*GInterfaceInitFunc) (gpointer g_iface, + gpointer iface_data); +typedef void (*GInterfaceFinalizeFunc) (gpointer g_iface, + gpointer iface_data); +typedef void (*GTypePluginRef) (GTypePlugin *plugin); +typedef void (*GTypePluginUnRef) (GTypePlugin *plugin); +typedef void (*GTypePluginFillTypeInfo) (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table); +typedef void (*GTypePluginFillInterfaceInfo) (GTypePlugin *plugin, + GType interface_type, + GType instance_type, + GInterfaceInfo *info); +typedef gboolean (*GTypeClassCacheFunc) (gpointer cache_data, + GTypeClass *g_class); struct _GTypePlugin { GTypePluginVTable *vtable; @@ -234,12 +247,13 @@ struct _GTypeInfo guint16 instance_size; guint16 n_preallocs; GInstanceInitFunc instance_init; + + /* value handling */ + const GTypeValueTable *value_table; }; struct _GTypeFundamentalInfo { GTypeFlags type_flags; - guint n_collect_bytes; - GTypeParamCollector param_collector; }; struct _GInterfaceInfo { @@ -247,6 +261,24 @@ struct _GInterfaceInfo GInterfaceFinalizeFunc interface_finalize; gpointer interface_data; }; +struct _GTypeValueTable +{ + void (*value_init) (GValue *value); + void (*value_free) (GValue *value); + void (*value_copy) (const GValue *src_value, + GValue *dest_value); + /* varargs functionality (optional) */ + guint collect_type; + gchar* (*collect_value) (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value); + guint lcopy_type; + gchar* (*lcopy_value) (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value); +}; GType g_type_register_static (GType parent_type, const gchar *type_name, const GTypeInfo *info); @@ -255,8 +287,8 @@ GType g_type_register_dynamic (GType parent_type, GTypePlugin *plugin); GType g_type_register_fundamental (GType type_id, const gchar *type_name, - const GTypeFundamentalInfo *finfo, - const GTypeInfo *info); + const GTypeInfo *info, + const GTypeFundamentalInfo *finfo); void g_type_add_interface_static (GType instance_type, GType interface_type, GInterfaceInfo *info); @@ -266,20 +298,27 @@ void g_type_add_interface_dynamic (GType instance_type, /* --- implementation details --- */ -gboolean g_type_class_is_a (GTypeClass *g_class, - GType is_a_type); -GTypeClass* g_type_check_class_cast (GTypeClass *g_class, - GType is_a_type); -GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance, - GType iface_type); -gboolean g_type_instance_conforms_to (GTypeInstance *instance, - GType iface_type); -gboolean g_type_check_flags (GType type, - GTypeFlags flags); -gboolean g_type_is_dynamic (GType type, - GTypeFlags flags); -GTypeInstance* g_type_create_instance (GType type); -void g_type_free_instance (GTypeInstance *instance); +gboolean g_type_class_is_a (GTypeClass *g_class, + GType is_a_type); +GTypeClass* g_type_check_class_cast (GTypeClass *g_class, + GType is_a_type); +GTypeInstance* g_type_check_instance_cast (GTypeInstance *instance, + GType iface_type); +gboolean g_type_instance_conforms_to (GTypeInstance *instance, + GType iface_type); +gboolean g_type_check_flags (GType type, + GTypeFlags flags); +gboolean g_type_is_dynamic (GType type, + GTypeFlags flags); +GTypeInstance* g_type_create_instance (GType type); +void g_type_free_instance (GTypeInstance *instance); +GTypeValueTable* g_type_value_table_peek (GType type); +void g_type_add_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func); +void g_type_remove_class_cache_func (gpointer cache_data, + GTypeClassCacheFunc cache_func); +void g_type_class_unref_uncached (gpointer g_class); + #ifndef G_DISABLE_CAST_CHECKS # define _G_TYPE_CIC(ip, gt, ct) \ diff --git a/gobject/gvalue.c b/gobject/gvalue.c index d85a9f7..7c4cb31 100644 --- a/gobject/gvalue.c +++ b/gobject/gvalue.c @@ -19,10 +19,6 @@ #include "gvalue.h" -/* --- defines --- */ -#define G_PARAM_SPEC_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_PARAM, GParamSpecClass)) - - /* --- typedefs & structures --- */ typedef struct { @@ -42,179 +38,73 @@ void g_value_init (GValue *value, GType g_type) { - GParamSpecClass *pclass; - - g_return_if_fail (value != NULL); - g_return_if_fail (G_VALUE_TYPE (value) == 0); - g_type = g_type_next_base (g_type, G_TYPE_PARAM); - g_return_if_fail (G_TYPE_IS_VALUE (g_type)); - - memset (value, 0, sizeof (*value)); - value->g_type = g_type; - - pclass = g_type_class_ref (G_VALUE_TYPE (value)); - pclass->param_init (value, NULL); - g_type_class_unref (pclass); -} - -void -g_value_init_default (GValue *value, - GParamSpec *pspec) -{ + GTypeValueTable *value_table = g_type_value_table_peek (g_type); + g_return_if_fail (value != NULL); g_return_if_fail (G_VALUE_TYPE (value) == 0); - g_return_if_fail (G_IS_PARAM_SPEC (pspec)); - - memset (value, 0, sizeof (*value)); - value->g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM); - - G_PARAM_SPEC_GET_CLASS (pspec)->param_init (value, pspec); -} - -gboolean -g_value_validate (GValue *value, - GParamSpec *pspec) -{ - g_return_val_if_fail (G_IS_VALUE (value), FALSE); - g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); - g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)), FALSE); - - if (G_PARAM_SPEC_GET_CLASS (pspec)->param_validate) - { - GValue oval = *value; - - if (G_PARAM_SPEC_GET_CLASS (pspec)->param_validate (value, pspec) || - memcmp (&oval.data, &value->data, sizeof (oval.data))) - return TRUE; - } - return FALSE; -} - -gboolean -g_value_defaults (const GValue *value, - GParamSpec *pspec) -{ - GValue dflt_value = { 0, }; - gboolean defaults; - - g_return_val_if_fail (G_IS_VALUE (value), FALSE); - g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), FALSE); - g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value)), FALSE); - dflt_value.g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM); - G_PARAM_SPEC_GET_CLASS (pspec)->param_init (&dflt_value, pspec); - defaults = g_values_cmp (value, &dflt_value, pspec) == 0; - g_value_unset (&dflt_value); - - return defaults; -} - -void -g_value_set_default (GValue *value, - GParamSpec *pspec) -{ - GValue tmp_value = { 0, }; - - g_return_if_fail (G_IS_VALUE (value)); - g_return_if_fail (G_IS_PARAM_SPEC (pspec)); - g_return_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value))); - - /* retrive default value */ - tmp_value.g_type = g_type_next_base (G_PARAM_SPEC_TYPE (pspec), G_TYPE_PARAM); - G_PARAM_SPEC_GET_CLASS (pspec)->param_init (&tmp_value, pspec); - - /* set default value */ - g_values_exchange (&tmp_value, value); - - g_value_unset (&tmp_value); -} - -gint -g_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec) -{ - GParamSpecClass *pclass; - gint cmp; - - /* param_values_cmp() effectively does: value1 - value2 - * so the return values are: - * -1) value1 < value2 - * 0) value1 == value2 - * 1) value1 > value2 - */ - g_return_val_if_fail (G_IS_VALUE (value1), 0); - g_return_val_if_fail (G_IS_VALUE (value2), 0); - g_return_val_if_fail (G_VALUE_TYPE (value1) == G_VALUE_TYPE (value2), 0); - if (pspec) + if (value_table) { - g_return_val_if_fail (G_IS_PARAM_SPEC (pspec), 0); - g_return_val_if_fail (g_type_is_a (G_PARAM_SPEC_TYPE (pspec), G_VALUE_TYPE (value1)), FALSE); + memset (value, 0, sizeof (*value)); + value->g_type = g_type; + value_table->value_init (value); } - - pclass = g_type_class_ref (G_VALUE_TYPE (value1)); - cmp = pclass->param_values_cmp (value1, value2, pspec); - g_type_class_unref (pclass); - - return CLAMP (cmp, -1, 1); + else + g_warning (G_STRLOC ": cannot initialize value of type `%s' which has no GTypeValueTable", + g_type_name (g_type)); } void g_value_copy (const GValue *src_value, GValue *dest_value) { + GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (dest_value)); + g_return_if_fail (G_IS_VALUE (src_value)); g_return_if_fail (G_IS_VALUE (dest_value)); - g_return_if_fail (G_VALUE_TYPE (src_value) == G_VALUE_TYPE (dest_value)); - + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_VALUE_TYPE (dest_value))); + if (!value_table) + g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (dest_value)) != NULL); + if (src_value != dest_value) { - GParamSpecClass *pclass = g_type_class_ref (G_VALUE_TYPE (src_value)); - /* make sure dest_value's value is free()d and zero initialized */ g_value_reset (dest_value); - if (pclass->param_copy_value) - pclass->param_copy_value (src_value, dest_value); - else - memcpy (&dest_value->data, &src_value->data, sizeof (src_value->data)); - g_type_class_unref (pclass); + value_table->value_copy (src_value, dest_value); } } void g_value_unset (GValue *value) { - GParamSpecClass *pclass; - + GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); + g_return_if_fail (G_IS_VALUE (value)); - - pclass = g_type_class_ref (G_VALUE_TYPE (value)); - if (pclass->param_free_value) - pclass->param_free_value (value); + if (!value_table) + g_return_if_fail (g_type_value_table_peek (G_VALUE_TYPE (value)) != NULL); + + if (value_table->value_free) + value_table->value_free (value); memset (value, 0, sizeof (*value)); - g_type_class_unref (pclass); } void g_value_reset (GValue *value) { - GParamSpecClass *pclass; + GTypeValueTable *value_table = g_type_value_table_peek (G_VALUE_TYPE (value)); GType g_type; - + g_return_if_fail (G_IS_VALUE (value)); - + g_type = G_VALUE_TYPE (value); - pclass = g_type_class_ref (g_type); - - if (pclass->param_free_value) - pclass->param_free_value (value); + + if (value_table->value_free) + value_table->value_free (value); memset (value, 0, sizeof (*value)); - - value->g_type = g_type; - pclass->param_init (value, NULL); - g_type_class_unref (pclass); + value->g_type = g_type; + value_table->value_init (value); } static gint @@ -223,7 +113,7 @@ exchange_entries_equal (gconstpointer v1, { const ExchangeEntry *entry1 = v1; const ExchangeEntry *entry2 = v2; - + return (entry1->value_type1 == entry2->value_type1 && entry1->value_type2 == entry2->value_type2); } @@ -232,7 +122,7 @@ static guint exchange_entry_hash (gconstpointer key) { const ExchangeEntry *entry = key; - + return entry->value_type1 ^ entry->value_type2; } @@ -241,7 +131,7 @@ value_exchange_memcpy (GValue *value1, GValue *value2) { GValue tmp_value; - + memcpy (&tmp_value.data, &value1->data, sizeof (value1->data)); memcpy (&value1->data, &value2->data, sizeof (value1->data)); memcpy (&value2->data, &tmp_value.data, sizeof (value2->data)); @@ -256,20 +146,36 @@ exchange_func_lookup (GType value_type1, return value_exchange_memcpy; else { - ExchangeEntry entry, *ret; - - entry.value_type1 = MIN (value_type1, value_type2); - entry.value_type2 = MAX (value_type1, value_type2); + GType type1 = value_type1; - ret = g_hash_table_lookup (param_exchange_ht, &entry); - if (ret) + do { - if (need_swap) - *need_swap = ret->first_type == value_type1; - - return ret->func; + GType type2 = value_type2; + + do + { + ExchangeEntry entry, *ret; + + entry.value_type1 = MIN (type1, type2); + entry.value_type2 = MAX (type1, type2); + ret = g_hash_table_lookup (param_exchange_ht, &entry); + if (ret) + { + if (need_swap) + *need_swap = ret->first_type == type2; + + return ret->func; + } + + type2 = g_type_parent (type2); + } + while (type2); + + type1 = g_type_parent (type1); } + while (type1); } + return NULL; } @@ -278,30 +184,29 @@ g_value_register_exchange_func (GType value_type1, GType value_type2, GValueExchange func) { - GType type1, type2; - + ExchangeEntry entry; + g_return_if_fail (G_TYPE_IS_VALUE (value_type1)); g_return_if_fail (G_TYPE_IS_VALUE (value_type2)); g_return_if_fail (func != NULL); - - type1 = g_type_next_base (value_type1, G_TYPE_PARAM); - type2 = g_type_next_base (value_type2, G_TYPE_PARAM); - - if (param_exchange_ht && exchange_func_lookup (type1, type2, NULL)) + + entry.value_type1 = MIN (value_type1, value_type2); + entry.value_type2 = MAX (value_type1, value_type2); + if (param_exchange_ht && g_hash_table_lookup (param_exchange_ht, &entry)) g_warning (G_STRLOC ": cannot re-register param value exchange function " "for `%s' and `%s'", - g_type_name (type1), - g_type_name (type2)); + g_type_name (value_type1), + g_type_name (value_type2)); else { ExchangeEntry *entry = g_new (ExchangeEntry, 1); - + if (!param_exchange_ht) param_exchange_ht = g_hash_table_new (exchange_entry_hash, exchange_entries_equal); - entry->value_type1 = MIN (type1, type2); - entry->value_type2 = MAX (type1, type2); + entry->value_type1 = MIN (value_type1, value_type2); + entry->value_type2 = MAX (value_type1, value_type2); entry->func = func; - entry->first_type = type1; + entry->first_type = value_type1; g_hash_table_insert (param_exchange_ht, entry, entry); } } @@ -310,15 +215,10 @@ gboolean g_value_types_exchangable (GType value_type1, GType value_type2) { - GType type1, type2; - g_return_val_if_fail (G_TYPE_IS_VALUE (value_type1), FALSE); g_return_val_if_fail (G_TYPE_IS_VALUE (value_type2), FALSE); - - type1 = g_type_next_base (value_type1, G_TYPE_PARAM); - type2 = g_type_next_base (value_type2, G_TYPE_PARAM); - - return exchange_func_lookup (type1, type2, NULL) != NULL; + + return exchange_func_lookup (value_type1, value_type2, NULL) != NULL; } gboolean @@ -327,14 +227,12 @@ g_values_exchange (GValue *value1, { g_return_val_if_fail (G_IS_VALUE (value1), FALSE); g_return_val_if_fail (G_IS_VALUE (value2), FALSE); - + if (value1 != value2) { - GType type1 = g_type_next_base (G_VALUE_TYPE (value1), G_TYPE_PARAM); - GType type2 = g_type_next_base (G_VALUE_TYPE (value2), G_TYPE_PARAM); gboolean need_swap; - GValueExchange value_exchange = exchange_func_lookup (type1, - type2, + GValueExchange value_exchange = exchange_func_lookup (G_VALUE_TYPE (value1), + G_VALUE_TYPE (value2), &need_swap); if (value_exchange) { @@ -343,10 +241,10 @@ g_values_exchange (GValue *value1, else value_exchange (value1, value2); } - + return value_exchange != NULL; } - + return TRUE; } @@ -355,20 +253,20 @@ g_value_convert (const GValue *src_value, GValue *dest_value) { gboolean success = TRUE; - + g_return_val_if_fail (G_IS_VALUE (src_value), FALSE); g_return_val_if_fail (G_IS_VALUE (dest_value), FALSE); - + if (src_value != dest_value) { GValue tmp_value = { 0, }; - + g_value_init (&tmp_value, G_VALUE_TYPE (src_value)); g_value_copy (src_value, &tmp_value); success = g_values_exchange (&tmp_value, dest_value); g_value_unset (&tmp_value); } - + return success; } diff --git a/gobject/gvalue.h b/gobject/gvalue.h index 697e1df..bf58cd4 100644 --- a/gobject/gvalue.h +++ b/gobject/gvalue.h @@ -22,7 +22,7 @@ #define __G_VALUE_H__ -#include +#include #ifdef __cplusplus extern "C" { @@ -30,18 +30,21 @@ extern "C" { /* --- type macros --- */ -#define G_TYPE_IS_VALUE(type) (G_TYPE_FUNDAMENTAL (type) == G_TYPE_PARAM) -#define G_IS_VALUE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_PARAM)) +#define G_TYPE_IS_VALUE(type) (g_type_value_table_peek (type) != NULL) +#define G_IS_VALUE(value) (G_TYPE_IS_VALUE (G_VALUE_TYPE (value))) // FIXME #define G_VALUE_TYPE(value) (G_TYPE_FROM_CLASS (value)) #define G_VALUE_TYPE_NAME(value) (g_type_name (G_VALUE_TYPE (value))) /* --- typedefs & structures --- */ -/* typedef struct _GValue GValue; */ +typedef void (*GValueExchange) (GValue *value1, + GValue *value2); struct _GValue { - GType g_type; /* param value type */ + /*< private >*/ + GType g_type; + /* public for GTypeValueTable methods */ union { gint v_int; guint v_uint; @@ -57,28 +60,17 @@ struct _GValue /* --- prototypes --- */ void g_value_init (GValue *value, GType g_type); -void g_value_init_default (GValue *value, - GParamSpec *pspec); -gboolean g_value_validate (GValue *value, - GParamSpec *pspec); -gboolean g_value_defaults (const GValue *value, - GParamSpec *pspec); -void g_value_set_default (GValue *value, - GParamSpec *pspec); -gint g_values_cmp (const GValue *value1, - const GValue *value2, - GParamSpec *pspec); void g_value_copy (const GValue *src_value, GValue *dest_value); gboolean g_value_convert (const GValue *src_value, GValue *dest_value); -gboolean g_values_exchange (GValue *value1, - GValue *value2); void g_value_reset (GValue *value); void g_value_unset (GValue *value); -/* --- implementation bits --- */ +/* --- implementation details --- */ +gboolean g_values_exchange (GValue *value1, + GValue *value2); gboolean g_value_types_exchangable (GType value_type1, GType value_type2); void g_value_register_exchange_func (GType value_type1, diff --git a/gobject/gvaluecollector.h b/gobject/gvaluecollector.h index b62c262..7bbdfc0 100644 --- a/gobject/gvaluecollector.h +++ b/gobject/gvaluecollector.h @@ -41,7 +41,7 @@ enum /*< skip >*/ G_VALUE_COLLECT_POINTER }; -union _GParamCValue +union _GTypeCValue { gint v_int; glong v_long; @@ -50,33 +50,28 @@ union _GParamCValue }; -/* G_PARAM_COLLECT_VALUE() collects a parameter's variable arguments +/* G_VALUE_COLLECT() collects a variable argument value * from a va_list. we have to implement the varargs collection as a * macro, because on some systems va_list variables cannot be passed * by reference. - * param_value is supposed to be initialized according to the param + * value is supposed to be initialized according to the value * type to be collected. - * the param_spec argument is optional, but probably needed by most - * param class' param_collect_value() implementations. * var_args is the va_list variable and may be evaluated multiple times. * __error is a gchar** variable that will be modified to hold a g_new() * allocated error messages if something fails. */ -#define G_PARAM_COLLECT_VALUE(param_value, param_spec, var_args, __error) \ +#define G_VALUE_COLLECT(value, var_args, __error) \ G_STMT_START { \ - GValue *_value = (param_value); \ - GParamSpecClass *_pclass = g_type_class_ref (_value->g_type); \ - GParamSpec *_pspec = (param_spec); \ + GValue *_value = (value); \ + GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value)); \ gchar *_error_msg = NULL; \ - guint _collect_type = _pclass->collect_type; \ + guint _collect_type = _vtable->collect_type; \ guint _nth_value = 0; \ \ - if (_pspec) \ - g_param_spec_ref (_pspec); \ g_value_reset (_value); \ while (_collect_type && !_error_msg) \ { \ - GParamCValue _cvalue; \ + GTypeCValue _cvalue; \ \ memset (&_cvalue, 0, sizeof (_cvalue)); \ switch (_collect_type) \ @@ -97,39 +92,32 @@ G_STMT_START { \ _error_msg = g_strdup_printf ("%s: invalid collect type (%d) used for %s", \ G_STRLOC, \ _collect_type, \ - "G_PARAM_COLLECT_VALUE()"); \ + "G_VALUE_COLLECT()"); \ continue; \ } \ - _error_msg = _pclass->param_collect_value (_value, \ - _pspec, \ - _nth_value++, \ - &_collect_type, \ - &_cvalue); \ + _error_msg = _vtable->collect_value (_value, \ + _nth_value++, \ + &_collect_type, \ + &_cvalue); \ } \ *(__error) = _error_msg; \ - if (_pspec) \ - g_param_spec_unref (_pspec); \ - g_type_class_unref (_pclass); \ } G_STMT_END -/* G_PARAM_LCOPY_VALUE() collects a parameter's variable argument - * locations from a va_list. usage is analogous to G_PARAM_COLLECT_VALUE(). +/* G_VALUE_LCOPY() collects a value's variable argument + * locations from a va_list. usage is analogous to G_VALUE_COLLECT(). */ -#define G_PARAM_LCOPY_VALUE(param_value, param_spec, var_args, __error) \ +#define G_VALUE_LCOPY(value, var_args, __error) \ G_STMT_START { \ - GValue *_value = (param_value); \ - GParamSpecClass *_pclass = g_type_class_ref (_value->g_type); \ - GParamSpec *_pspec = (param_spec); \ + GValue *_value = (value); \ + GTypeValueTable *_vtable = g_type_value_table_peek (G_VALUE_TYPE (_value)); \ gchar *_error_msg = NULL; \ - guint _lcopy_type = _pclass->lcopy_type; \ + guint _lcopy_type = _vtable->lcopy_type; \ guint _nth_value = 0; \ \ - if (_pspec) \ - g_param_spec_ref (_pspec); \ while (_lcopy_type && !_error_msg) \ { \ - GParamCValue _cvalue; \ + GTypeCValue _cvalue; \ \ memset (&_cvalue, 0, sizeof (_cvalue)); \ switch (_lcopy_type) \ @@ -150,19 +138,15 @@ G_STMT_START { \ _error_msg = g_strdup_printf ("%s: invalid collect type (%d) used for %s", \ G_STRLOC, \ _lcopy_type, \ - "G_PARAM_LCOPY_VALUE()"); \ + "G_VALUE_LCOPY()"); \ continue; \ } \ - _error_msg = _pclass->param_lcopy_value (_value, \ - _pspec, \ - _nth_value++, \ - &_lcopy_type, \ - &_cvalue); \ + _error_msg = _vtable->lcopy_value (_value, \ + _nth_value++, \ + &_lcopy_type, \ + &_cvalue); \ } \ *(__error) = _error_msg; \ - if (_pspec) \ - g_param_spec_unref (_pspec); \ - g_type_class_unref (_pclass); \ } G_STMT_END diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c new file mode 100644 index 0000000..d27171c --- /dev/null +++ b/gobject/gvaluetypes.c @@ -0,0 +1,588 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and 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. + */ +#include "gvaluetypes.h" + +#include "gvaluecollector.h" +#include + + +/* --- value functions --- */ +static void +value_long0_init (GValue *value) +{ + value->data[0].v_long = 0; +} + +static void +value_long0_copy (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_long = src_value->data[0].v_long; +} + +static gchar* +value_char_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gint8 *int8_p = collect_value->v_pointer; + + if (!int8_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *int8_p = value->data[0].v_int; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_boolean_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gboolean *bool_p = collect_value->v_pointer; + + if (!bool_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *bool_p = value->data[0].v_int; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_int_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + value->data[0].v_int = collect_value->v_int; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_int_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gint *int_p = collect_value->v_pointer; + + if (!int_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *int_p = value->data[0].v_int; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_long_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + value->data[0].v_long = collect_value->v_long; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_long_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + glong *long_p = collect_value->v_pointer; + + if (!long_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *long_p = value->data[0].v_long; + + *collect_type = 0; + return NULL; +} + +static void +value_float_init (GValue *value) +{ + value->data[0].v_float = 0.0; +} + +static void +value_float_copy (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_float = src_value->data[0].v_float; +} + +static gchar* +value_float_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + value->data[0].v_float = collect_value->v_double; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_float_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gfloat *float_p = collect_value->v_pointer; + + if (!float_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *float_p = value->data[0].v_float; + + *collect_type = 0; + return NULL; +} + +static void +value_double_init (GValue *value) +{ + value->data[0].v_double = 0.0; +} + +static void +value_double_copy (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_double = src_value->data[0].v_double; +} + +static gchar* +value_double_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + value->data[0].v_double = collect_value->v_double; + + *collect_type = 0; + return NULL; +} + +static gchar* +value_double_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gdouble *double_p = collect_value->v_pointer; + + if (!double_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *double_p = value->data[0].v_double; + + *collect_type = 0; + return NULL; +} + +static void +value_string_init (GValue *value) +{ + value->data[0].v_pointer = NULL; +} + +static void +value_string_free_value (GValue *value) +{ + g_free (value->data[0].v_pointer); +} + +static void +value_string_copy_value (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_pointer = g_strdup (src_value->data[0].v_pointer); +} + +static gchar* +value_string_collect_value (GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + value->data[0].v_pointer = g_strdup (collect_value->v_pointer); + + *collect_type = 0; + return NULL; +} + +static gchar* +value_string_lcopy_value (const GValue *value, + guint nth_value, + GType *collect_type, + GTypeCValue *collect_value) +{ + gchar **string_p = collect_value->v_pointer; + + if (!string_p) + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + + *string_p = g_strdup (value->data[0].v_pointer); + + *collect_type = 0; + return NULL; +} + + +/* --- type initialization --- */ +void +g_value_types_init (void) /* sync with gtype.c */ +{ + GTypeInfo info = { + 0, /* class_size */ + NULL, /* base_init */ + NULL, /* base_destroy */ + NULL, /* class_init */ + NULL, /* class_destroy */ + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + NULL, /* instance_init */ + NULL, /* value_table */ + }; + const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, }; + GType type; + + /* G_TYPE_CHAR / G_TYPE_UCHAR + */ + { + static const GTypeValueTable value_table = { + value_long0_init, /* value_init */ + NULL, /* value_free */ + value_long0_copy, /* value_copy */ + G_VALUE_COLLECT_INT, /* collect_type */ + value_int_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_char_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_CHAR, "gchar", &info, &finfo); + g_assert (type == G_TYPE_CHAR); + type = g_type_register_fundamental (G_TYPE_UCHAR, "guchar", &info, &finfo); + g_assert (type == G_TYPE_UCHAR); + } + + /* G_TYPE_BOOLEAN + */ + { + static const GTypeValueTable value_table = { + value_long0_init, /* value_init */ + NULL, /* value_free */ + value_long0_copy, /* value_copy */ + G_VALUE_COLLECT_INT, /* collect_type */ + value_int_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_boolean_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_BOOLEAN, "gboolean", &info, &finfo); + g_assert (type == G_TYPE_BOOLEAN); + } + + /* G_TYPE_INT / G_TYPE_UINT + */ + { + static const GTypeValueTable value_table = { + value_long0_init, /* value_init */ + NULL, /* value_free */ + value_long0_copy, /* value_copy */ + G_VALUE_COLLECT_INT, /* collect_type */ + value_int_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_int_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_INT, "gint", &info, &finfo); + g_assert (type == G_TYPE_INT); + type = g_type_register_fundamental (G_TYPE_UINT, "guint", &info, &finfo); + g_assert (type == G_TYPE_UINT); + } + + /* G_TYPE_LONG / G_TYPE_ULONG + */ + { + static const GTypeValueTable value_table = { + value_long0_init, /* value_init */ + NULL, /* value_free */ + value_long0_copy, /* value_copy */ + G_VALUE_COLLECT_LONG, /* collect_type */ + value_long_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_long_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_LONG, "glong", &info, &finfo); + g_assert (type == G_TYPE_LONG); + type = g_type_register_fundamental (G_TYPE_ULONG, "gulong", &info, &finfo); + g_assert (type == G_TYPE_ULONG); + } + + /* G_TYPE_FLOAT + */ + { + static const GTypeValueTable value_table = { + value_float_init, /* value_init */ + NULL, /* value_free */ + value_float_copy, /* value_copy */ + G_VALUE_COLLECT_DOUBLE, /* collect_type */ + value_float_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_float_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_FLOAT, "gfloat", &info, &finfo); + g_assert (type == G_TYPE_FLOAT); + } + + /* G_TYPE_DOUBLE + */ + { + static const GTypeValueTable value_table = { + value_double_init, /* value_init */ + NULL, /* value_free */ + value_double_copy, /* value_copy */ + G_VALUE_COLLECT_DOUBLE, /* collect_type */ + value_double_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_double_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_DOUBLE, "gdouble", &info, &finfo); + g_assert (type == G_TYPE_DOUBLE); + } + + /* G_TYPE_STRING + */ + { + static const GTypeValueTable value_table = { + value_string_init, /* value_init */ + value_string_free_value, /* value_free */ + value_string_copy_value, /* value_copy */ + G_VALUE_COLLECT_POINTER, /* collect_type */ + value_string_collect_value, /* collect_value */ + G_VALUE_COLLECT_POINTER, /* lcopy_type */ + value_string_lcopy_value, /* lcopy_value */ + }; + info.value_table = &value_table; + type = g_type_register_fundamental (G_TYPE_STRING, "gstring", &info, &finfo); + g_assert (type == G_TYPE_STRING); + } +} + + +/* --- GValue functions --- */ +void +g_value_set_char (GValue *value, + gint8 v_char) +{ + g_return_if_fail (G_IS_VALUE_CHAR (value)); + + value->data[0].v_int = v_char; +} + +gint8 +g_value_get_char (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_CHAR (value), 0); + + return value->data[0].v_int; +} + +void +g_value_set_uchar (GValue *value, + guint8 v_uchar) +{ + g_return_if_fail (G_IS_VALUE_UCHAR (value)); + + value->data[0].v_uint = v_uchar; +} + +guint8 +g_value_get_uchar (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_UCHAR (value), 0); + + return value->data[0].v_uint; +} + +void +g_value_set_boolean (GValue *value, + gboolean v_boolean) +{ + g_return_if_fail (G_IS_VALUE_BOOLEAN (value)); + + value->data[0].v_int = v_boolean; +} + +gboolean +g_value_get_boolean (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_BOOLEAN (value), 0); + + return value->data[0].v_int; +} + +void +g_value_set_int (GValue *value, + gint v_int) +{ + g_return_if_fail (G_IS_VALUE_INT (value)); + + value->data[0].v_int = v_int; +} + +gint +g_value_get_int (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_INT (value), 0); + + return value->data[0].v_int; +} + +void +g_value_set_uint (GValue *value, + guint v_uint) +{ + g_return_if_fail (G_IS_VALUE_UINT (value)); + + value->data[0].v_uint = v_uint; +} + +guint +g_value_get_uint (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_UINT (value), 0); + + return value->data[0].v_uint; +} + +void +g_value_set_long (GValue *value, + glong v_long) +{ + g_return_if_fail (G_IS_VALUE_LONG (value)); + + value->data[0].v_long = v_long; +} + +glong +g_value_get_long (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_LONG (value), 0); + + return value->data[0].v_long; +} + +void +g_value_set_ulong (GValue *value, + gulong v_ulong) +{ + g_return_if_fail (G_IS_VALUE_ULONG (value)); + + value->data[0].v_ulong = v_ulong; +} + +gulong +g_value_get_ulong (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_ULONG (value), 0); + + return value->data[0].v_ulong; +} + +void +g_value_set_float (GValue *value, + gfloat v_float) +{ + g_return_if_fail (G_IS_VALUE_FLOAT (value)); + + value->data[0].v_float = v_float; +} + +gfloat +g_value_get_float (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_FLOAT (value), 0); + + return value->data[0].v_float; +} + +void +g_value_set_double (GValue *value, + gdouble v_double) +{ + g_return_if_fail (G_IS_VALUE_DOUBLE (value)); + + value->data[0].v_double = v_double; +} + +gdouble +g_value_get_double (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_DOUBLE (value), 0); + + return value->data[0].v_double; +} + +void +g_value_set_string (GValue *value, + const gchar *v_string) +{ + g_return_if_fail (G_IS_VALUE_STRING (value)); + + g_free (value->data[0].v_pointer); + value->data[0].v_pointer = g_strdup (v_string); +} + +gchar* +g_value_get_string (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL); + + return value->data[0].v_pointer; +} + +gchar* +g_value_dup_string (GValue *value) +{ + g_return_val_if_fail (G_IS_VALUE_STRING (value), NULL); + + return g_strdup (value->data[0].v_pointer); +} diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h new file mode 100644 index 0000000..f142967 --- /dev/null +++ b/gobject/gvaluetypes.h @@ -0,0 +1,86 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1997, 1998, 1999, 2000 Tim Janik and 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. + * + * gvaluetypes.h: GLib default values + */ +#ifndef __G_VALUETYPES_H__ +#define __G_VALUETYPES_H__ + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* --- type macros --- */ +#define G_IS_VALUE_CHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_CHAR)) +#define G_IS_VALUE_UCHAR(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_UCHAR)) +#define G_IS_VALUE_BOOLEAN(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_BOOLEAN)) +#define G_IS_VALUE_INT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_INT)) +#define G_IS_VALUE_UINT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_UINT)) +#define G_IS_VALUE_LONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_LONG)) +#define G_IS_VALUE_ULONG(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_ULONG)) +#define G_IS_VALUE_FLOAT(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_FLOAT)) +#define G_IS_VALUE_DOUBLE(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_DOUBLE)) +#define G_IS_VALUE_STRING(value) (G_TYPE_CHECK_CLASS_TYPE ((value), G_TYPE_STRING)) + + +/* --- prototypes --- */ +void g_value_set_char (GValue *value, + gint8 v_char); +gint8 g_value_get_char (GValue *value); +void g_value_set_uchar (GValue *value, + guint8 v_uchar); +guint8 g_value_get_uchar (GValue *value); +void g_value_set_boolean (GValue *value, + gboolean v_boolean); +gboolean g_value_get_boolean (GValue *value); +void g_value_set_int (GValue *value, + gint v_int); +gint g_value_get_int (GValue *value); +void g_value_set_uint (GValue *value, + guint v_uint); +guint g_value_get_uint (GValue *value); +void g_value_set_long (GValue *value, + glong v_long); +glong g_value_get_long (GValue *value); +void g_value_set_ulong (GValue *value, + gulong v_ulong); +gulong g_value_get_ulong (GValue *value); +void g_value_set_float (GValue *value, + gfloat v_float); +gfloat g_value_get_float (GValue *value); +void g_value_set_double (GValue *value, + gdouble v_double); +gdouble g_value_get_double (GValue *value); +void g_value_set_string (GValue *value, + const gchar *v_string); +gchar* g_value_get_string (GValue *value); +gchar* g_value_dup_string (GValue *value); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __G_VALUETYPES_H__ */ -- 2.7.4