+Thu Dec 22 14:59:24 2005 Tim Janik <timj@imendio.com>
+
+ * 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 <mclasen@redhat.com>
* === Released 2.9.1 ===
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);
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
{
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);
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;
}
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 {
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"
#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,
/* --- prototypes --- */
+GType g_unowned_get_type (void);
void g_object_class_install_property (GObjectClass *oclass,
guint property_id,
GParamSpec *pspec);
gpointer gobject,
GConnectFlags connect_flags);
-
/*< protected >*/
void g_object_force_floating (GObject *object);
void g_object_run_dispose (GObject *object);
#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 --- */
g_value_take_object
#ifndef G_DISABLE_DEPRECATED
g_value_set_object_take_ownership
+g_object_compat_control
#endif
g_signal_connect_object
#endif
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);
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);
}
}
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,
const gchar *blurb,
#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 --- */
typedef struct _GParamSpecValueArray GParamSpecValueArray;
typedef struct _GParamSpecObject GParamSpecObject;
typedef struct _GParamSpecOverride GParamSpecOverride;
+typedef struct _GParamSpecGType GParamSpecGType;
struct _GParamSpecChar
{
GParamSpec parent_instance;
GParamSpec *overridden;
};
+struct _GParamSpecGType
+{
+ GParamSpec parent_instance;
+ GType is_a_type;
+};
/* --- GParamSpec prototypes --- */
GParamSpec* g_param_spec_char (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
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"
#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 --- */
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 */