implemented G_TYPE_GTPYE. applied patch from matthias which implements

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.
This commit is contained in:
Tim Janik 2005-12-22 15:07:03 +00:00 committed by Tim Janik
parent 513be6bbae
commit 6f01d0c34f
8 changed files with 221 additions and 20 deletions

View File

@ -1,3 +1,16 @@
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 ===

View File

@ -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"

View File

@ -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 --- */

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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"

View File

@ -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 */