mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-23 22:16:16 +01:00
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:
parent
513be6bbae
commit
6f01d0c34f
@ -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 ===
|
||||
|
@ -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"
|
||||
|
@ -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 --- */
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user