From: Tim Janik Date: Thu, 22 Dec 2005 15:07:03 +0000 (+0000) Subject: implemented G_TYPE_GTPYE. applied patch from matthias which implements X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=6f01d0c34f0d217b91a55ef1ec1b04d007259993;p=dana%2Fcg-glib.git implemented G_TYPE_GTPYE. applied patch from matthias which implements Thu Dec 22 14:59:24 2005 Tim Janik * gvaluetypes.[hc]: implemented G_TYPE_GTPYE. applied patch from matthias which implements GType accessors for GValue. * gparamspecs.[hc]: applied patch from matthias which implements G_TYPE_PARAM_GTYPE. * gobject.[hc]: GUnowned: introduced a new object type that has an initially floating reference. g_object_compat_control(): allow setting of a floating flag handler. --- diff --git a/gobject/ChangeLog b/gobject/ChangeLog index ece8c6b8..95724673 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,16 @@ +Thu Dec 22 14:59:24 2005 Tim Janik + + * gvaluetypes.[hc]: implemented G_TYPE_GTPYE. applied patch + from matthias which implements GType accessors for GValue. + + * gparamspecs.[hc]: applied patch from matthias which + implements G_TYPE_PARAM_GTYPE. + + * gobject.[hc]: + GUnowned: introduced a new object type that has an initially + floating reference. + g_object_compat_control(): allow setting of a floating flag handler. + 2005-12-09 Matthias Clasen * === Released 2.9.1 === diff --git a/gobject/gobject.c b/gobject/gobject.c index 85ed73df..91d39a82 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -102,6 +102,8 @@ static inline void object_set_property (GObject *object, GParamSpec *pspec, const GValue *value, GObjectNotifyQueue *nqueue); +static guint object_floating_flag_handler (GObject *object, + gint job); static void object_interface_check_properties (gpointer func_data, gpointer g_iface); @@ -116,6 +118,7 @@ static GObjectNotifyContext property_notify_context = { 0, }; static gulong gobject_signals[LAST_SIGNAL] = { 0, }; G_LOCK_DEFINE_STATIC (construct_objects_lock); static GSList *construct_objects = NULL; +static guint (*floating_flag_handler) (GObject*, gint) = object_floating_flag_handler; /* --- functions --- */ #ifdef G_ENABLE_DEBUG @@ -473,7 +476,6 @@ g_object_init (GObject *object) { object->ref_count = 1; g_datalist_init (&object->qdata); - g_object_force_floating (object); /* freeze object's notification queue, g_object_newv() preserves pairedness */ g_object_notify_queue_freeze (object, &property_notify_context); @@ -1520,29 +1522,48 @@ g_object_remove_weak_pointer (GObject *object, weak_pointer_location); } +static guint +object_floating_flag_handler (GObject *object, + gint job) +{ + switch (job) + { + gpointer oldvalue; + case +1: /* force floating if possible */ + do + oldvalue = g_atomic_pointer_get (&object->qdata); + while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, + (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG))); + return (gsize) oldvalue & OBJECT_FLOATING_FLAG; + case -1: /* sink if possible */ + do + oldvalue = g_atomic_pointer_get (&object->qdata); + while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, + (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG))); + return (gsize) oldvalue & OBJECT_FLOATING_FLAG; + default: /* check floating */ + return 0 != ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG); + } +} + gboolean g_object_is_floating (gpointer _object) { GObject *object = _object; g_return_val_if_fail (G_IS_OBJECT (object), FALSE); - return ((gsize) g_atomic_pointer_get (&object->qdata) & OBJECT_FLOATING_FLAG) != 0; + return floating_flag_handler (object, 0); } gpointer g_object_ref_sink (gpointer _object) { GObject *object = _object; - gpointer oldvalue; + gboolean was_floating; g_return_val_if_fail (G_IS_OBJECT (object), object); g_return_val_if_fail (object->ref_count >= 1, object); g_object_ref (object); - do - { - oldvalue = g_atomic_pointer_get (&object->qdata); - } - while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, - (gpointer) ((gsize) oldvalue & ~(gsize) OBJECT_FLOATING_FLAG))); - if ((gsize) oldvalue & OBJECT_FLOATING_FLAG) + was_floating = floating_flag_handler (object, -1); + if (was_floating) g_object_unref (object); return object; } @@ -1550,15 +1571,11 @@ g_object_ref_sink (gpointer _object) void g_object_force_floating (GObject *object) { - gpointer oldvalue; + gboolean was_floating; g_return_if_fail (G_IS_OBJECT (object)); g_return_if_fail (object->ref_count >= 1); - do - { - oldvalue = g_atomic_pointer_get (&object->qdata); - } - while (!g_atomic_pointer_compare_and_exchange ((void**) &object->qdata, oldvalue, - (gpointer) ((gsize) oldvalue | OBJECT_FLOATING_FLAG))); + + was_floating = floating_flag_handler (object, +1); } typedef struct { @@ -2181,5 +2198,34 @@ g_cclosure_new_object_swap (GCallback callback_func, return closure; } +gsize +g_object_compat_control (gsize what, + gpointer data) +{ + switch (what) + { + case 1: /* floating base type */ + return G_TYPE_UNOWNED; + case 2: /* FIXME: remove this once GLib/Gtk+ break ABI again */ + floating_flag_handler = (guint(*)(GObject*,gint)) data; + return 1; + default: + return 0; + } +} + +G_DEFINE_TYPE (GUnowned, g_unowned, G_TYPE_OBJECT); + +static void +g_unowned_init (GUnowned *object) +{ + g_object_force_floating (object); +} + +static void +g_unowned_class_init (GUnownedClass *klass) +{ +} + #define __G_OBJECT_C__ #include "gobjectaliasdef.c" diff --git a/gobject/gobject.h b/gobject/gobject.h index bb684f44..71ba6d56 100644 --- a/gobject/gobject.h +++ b/gobject/gobject.h @@ -44,10 +44,21 @@ G_BEGIN_DECLS #define G_OBJECT_CLASS_NAME(class) (g_type_name (G_OBJECT_CLASS_TYPE (class))) #define G_VALUE_HOLDS_OBJECT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_OBJECT)) +/* --- type macros --- */ +#define G_TYPE_UNOWNED (g_unowned_get_type()) +#define G_UNOWNED(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_UNOWNED, GUnowned)) +#define G_UNOWNED_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_UNOWNED, GUnownedClass)) +#define G_IS_UNOWNED(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_UNOWNED)) +#define G_IS_UNOWNED_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_UNOWNED)) +#define G_UNOWNED_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), G_TYPE_UNOWNED, GUnownedClass)) +/* GUnowned ia a GObject with initially floating reference count */ + /* --- typedefs & structures --- */ typedef struct _GObject GObject; typedef struct _GObjectClass GObjectClass; +typedef struct _GObject GUnowned; +typedef struct _GObjectClass GUnownedClass; typedef struct _GObjectConstructParam GObjectConstructParam; typedef void (*GObjectGetPropertyFunc) (GObject *object, guint property_id, @@ -111,6 +122,7 @@ struct _GObjectConstructParam /* --- prototypes --- */ +GType g_unowned_get_type (void); void g_object_class_install_property (GObjectClass *oclass, guint property_id, GParamSpec *pspec); @@ -232,7 +244,6 @@ gulong g_signal_connect_object (gpointer instance, gpointer gobject, GConnectFlags connect_flags); - /*< protected >*/ void g_object_force_floating (GObject *object); void g_object_run_dispose (GObject *object); @@ -243,6 +254,8 @@ void g_value_take_object (GValue *value, #ifndef G_DISABLE_DEPRECATED void g_value_set_object_take_ownership (GValue *value, gpointer v_object); +gsize g_object_compat_control (gsize what, + gpointer data); #endif /* --- implementation macros --- */ diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols index bf23e6f7..79f12b4c 100644 --- a/gobject/gobject.symbols +++ b/gobject/gobject.symbols @@ -160,6 +160,7 @@ g_value_dup_object g_value_take_object #ifndef G_DISABLE_DEPRECATED g_value_set_object_take_ownership +g_object_compat_control #endif g_signal_connect_object #endif diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c index f9700749..953bb8d0 100644 --- a/gobject/gparamspecs.c +++ b/gobject/gparamspecs.c @@ -1016,13 +1016,55 @@ param_override_values_cmp (GParamSpec *pspec, return g_param_values_cmp (ospec->overridden, value1, value2); } +static void +param_gtype_init (GParamSpec *pspec) +{ +} + +static void +param_gtype_set_default (GParamSpec *pspec, + GValue *value) +{ + value->data[0].v_long = G_TYPE_NONE; +} + +static gboolean +param_gtype_validate (GParamSpec *pspec, + GValue *value) +{ + GParamSpecGType *tspec = G_PARAM_SPEC_GTYPE (pspec); + GType gtype = value->data[0].v_long; + guint changed = 0; + + if (tspec->is_a_type != G_TYPE_NONE && !g_type_is_a (gtype, tspec->is_a_type)) + { + value->data[0].v_long = G_TYPE_NONE; + changed++; + } + + return changed; +} + +static gint +param_gtype_values_cmp (GParamSpec *pspec, + const GValue *value1, + const GValue *value2) +{ + GType p1 = value1->data[0].v_long; + GType p2 = value2->data[0].v_long; + + /* not much to compare here, try to at least provide stable lesser/greater result */ + + return p1 < p2 ? -1 : p1 > p2; +} + /* --- type initialization --- */ GType *g_param_spec_types = NULL; void g_param_spec_types_init (void) { - const guint n_types = 21; + const guint n_types = 22; GType type, *spec_types, *spec_types_bound; g_param_spec_types = g_new0 (GType, n_types); @@ -1408,6 +1450,24 @@ g_param_spec_types_init (void) g_assert (type == G_TYPE_PARAM_OVERRIDE); } + /* G_TYPE_PARAM_GTYPE + */ + { + GParamSpecTypeInfo pspec_info = { + sizeof (GParamSpecGType), /* instance_size */ + 0, /* n_preallocs */ + param_gtype_init, /* instance_init */ + G_TYPE_GTYPE, /* value_type */ + NULL, /* finalize */ + param_gtype_set_default, /* value_set_default */ + param_gtype_validate, /* value_validate */ + param_gtype_values_cmp, /* values_cmp */ + }; + type = g_param_type_register_static (g_intern_static_string ("GParamGType"), &pspec_info); + *spec_types++ = type; + g_assert (type == G_TYPE_PARAM_GTYPE); + } + g_assert (spec_types == spec_types_bound); } @@ -1852,6 +1912,26 @@ g_param_spec_pointer (const gchar *name, return G_PARAM_SPEC (pspec); } +GParamSpec* +g_param_spec_gtype (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType is_a_type, + GParamFlags flags) +{ + GParamSpecGType *tspec; + + tspec = g_param_spec_internal (G_TYPE_PARAM_GTYPE, + name, + nick, + blurb, + flags); + + tspec->is_a_type = is_a_type; + + return G_PARAM_SPEC (tspec); +} + GParamSpec* g_param_spec_value_array (const gchar *name, const gchar *nick, diff --git a/gobject/gparamspecs.h b/gobject/gparamspecs.h index 137e1d0b..b6add1cb 100644 --- a/gobject/gparamspecs.h +++ b/gobject/gparamspecs.h @@ -96,6 +96,9 @@ G_BEGIN_DECLS #define G_TYPE_PARAM_OVERRIDE (g_param_spec_types[20]) #define G_IS_PARAM_SPEC_OVERRIDE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_OVERRIDE)) #define G_PARAM_SPEC_OVERRIDE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_OVERRIDE, GParamSpecOverride)) +#define G_TYPE_PARAM_GTYPE (g_param_spec_types[21]) +#define G_IS_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), G_TYPE_PARAM_GTYPE)) +#define G_PARAM_SPEC_GTYPE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), G_TYPE_PARAM_GTYPE, GParamSpecGType)) /* --- typedefs & structures --- */ @@ -120,6 +123,7 @@ typedef struct _GParamSpecPointer GParamSpecPointer; typedef struct _GParamSpecValueArray GParamSpecValueArray; typedef struct _GParamSpecObject GParamSpecObject; typedef struct _GParamSpecOverride GParamSpecOverride; +typedef struct _GParamSpecGType GParamSpecGType; struct _GParamSpecChar { @@ -268,6 +272,11 @@ struct _GParamSpecOverride GParamSpec parent_instance; GParamSpec *overridden; }; +struct _GParamSpecGType +{ + GParamSpec parent_instance; + GType is_a_type; +}; /* --- GParamSpec prototypes --- */ GParamSpec* g_param_spec_char (const gchar *name, @@ -391,9 +400,13 @@ GParamSpec* g_param_spec_object (const gchar *name, const gchar *blurb, GType object_type, GParamFlags flags); - GParamSpec* g_param_spec_override (const gchar *name, GParamSpec *overridden); +GParamSpec* g_param_spec_gtype (const gchar *name, + const gchar *nick, + const gchar *blurb, + GType is_a_type, + GParamFlags flags); /* --- internal --- */ /* We prefix variable declarations so they can diff --git a/gobject/gvaluetypes.c b/gobject/gvaluetypes.c index cb3de7eb..7bfc9f6c 100644 --- a/gobject/gvaluetypes.c +++ b/gobject/gvaluetypes.c @@ -818,6 +818,35 @@ g_value_get_pointer (const GValue *value) return value->data[0].v_pointer; } +GType +g_gtype_get_type (void) +{ + static const GTypeInfo type_info = { 0, }; + static GType type; + if (!type) + type = g_type_register_static (G_TYPE_POINTER, g_intern_static_string ("GType"), &type_info, 0); + return type; +} + +void +g_value_set_gtype (GValue *value, + GType v_gtype) +{ + g_return_if_fail (G_VALUE_HOLDS_GTYPE (value)); + + value->data[0].v_long = v_gtype; + +} + +GType +g_value_get_gtype (const GValue *value) +{ + g_return_val_if_fail (G_VALUE_HOLDS_GTYPE (value), 0); + + return value->data[0].v_long; +} + + /* need extra includes for g_strdup_value_contents() ;( */ #include "gobject.h" #include "gparam.h" diff --git a/gobject/gvaluetypes.h b/gobject/gvaluetypes.h index dfe9ce3d..2931cdaa 100644 --- a/gobject/gvaluetypes.h +++ b/gobject/gvaluetypes.h @@ -43,6 +43,8 @@ G_BEGIN_DECLS #define G_VALUE_HOLDS_DOUBLE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_DOUBLE)) #define G_VALUE_HOLDS_STRING(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_STRING)) #define G_VALUE_HOLDS_POINTER(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_POINTER)) +#define G_TYPE_GTYPE (g_gtype_get_type()) +#define G_VALUE_HOLDS_GTYPE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_GTYPE)) /* --- prototypes --- */ @@ -88,6 +90,10 @@ gchar* g_value_dup_string (const GValue *value); void g_value_set_pointer (GValue *value, gpointer v_pointer); gpointer g_value_get_pointer (const GValue *value); +GType g_gtype_get_type (void); +void g_value_set_gtype (GValue *value, + GType v_gtype); +GType g_value_get_gtype (const GValue *value); /* Convenience for registering new pointer types */