diff options
Diffstat (limited to 'gobject/gobject.c')
-rw-r--r-- | gobject/gobject.c | 127 |
1 files changed, 122 insertions, 5 deletions
diff --git a/gobject/gobject.c b/gobject/gobject.c index df27c36f7..07752cf25 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -162,6 +162,29 @@ enum { PROP_NONE }; +#define OPTIONAL_FLAG_IN_CONSTRUCTION 1<<0 +#define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER 1<<1 /* Set if object ever had a signal handler */ + +#if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P == 8 +#define HAVE_OPTIONAL_FLAGS +#endif + +typedef struct +{ + GTypeInstance g_type_instance; + + /*< private >*/ + volatile guint ref_count; +#ifdef HAVE_OPTIONAL_FLAGS + volatile guint optional_flags; +#endif + GData *qdata; +} GObjectReal; + +G_STATIC_ASSERT(sizeof(GObject) == sizeof(GObjectReal)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, ref_count) == G_STRUCT_OFFSET(GObjectReal, ref_count)); +G_STATIC_ASSERT(G_STRUCT_OFFSET(GObject, qdata) == G_STRUCT_OFFSET(GObjectReal, qdata)); + /* --- prototypes --- */ static void g_object_base_class_init (GObjectClass *class); @@ -1008,10 +1031,83 @@ g_object_interface_list_properties (gpointer g_iface, return pspecs; } +static inline guint +object_get_optional_flags (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + GObjectReal *real = (GObjectReal *)object; + return (guint)g_atomic_int_get (&real->optional_flags); +#else + return 0; +#endif +} + +static inline void +object_set_optional_flags (GObject *object, + guint flags) +{ +#ifdef HAVE_OPTIONAL_FLAGS + GObjectReal *real = (GObjectReal *)object; + g_atomic_int_or (&real->optional_flags, flags); +#endif +} + +static inline void +object_unset_optional_flags (GObject *object, + guint flags) +{ +#ifdef HAVE_OPTIONAL_FLAGS + GObjectReal *real = (GObjectReal *)object; + g_atomic_int_and (&real->optional_flags, ~flags); +#endif +} + +gboolean +_g_object_has_signal_handler (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + return (object_get_optional_flags (object) & OPTIONAL_FLAG_HAS_SIGNAL_HANDLER) != 0; +#else + return TRUE; +#endif +} + +void +_g_object_set_has_signal_handler (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + object_set_optional_flags (object, OPTIONAL_FLAG_HAS_SIGNAL_HANDLER); +#endif +} + static inline gboolean object_in_construction (GObject *object) { +#ifdef HAVE_OPTIONAL_FLAGS + return (object_get_optional_flags (object) & OPTIONAL_FLAG_IN_CONSTRUCTION) != 0; +#else return g_datalist_id_get_data (&object->qdata, quark_in_construction) != NULL; +#endif +} + +static inline void +set_object_in_construction (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + object_set_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION); +#else + g_datalist_id_set_data (&object->qdata, quark_in_construction, object); +#endif +} + +static inline void +unset_object_in_construction (GObject *object) +{ +#ifdef HAVE_OPTIONAL_FLAGS + object_unset_optional_flags (object, OPTIONAL_FLAG_IN_CONSTRUCTION); +#else + g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL); +#endif } static void @@ -1030,7 +1126,7 @@ g_object_init (GObject *object, if (CLASS_HAS_CUSTOM_CONSTRUCTOR (class)) { /* mark object in-construction for notify_queue_thaw() and to allow construct-only properties */ - g_datalist_id_set_data (&object->qdata, quark_in_construction, object); + set_object_in_construction (object); } GOBJECT_IF_DEBUG (OBJECTS, @@ -1521,7 +1617,7 @@ object_interface_check_properties (gpointer check_data, /* We do a number of checks on the properties of an interface to * make sure that all classes implementing the interface are - * overriding the properties in a sane way. + * overriding the properties correctly. * * We do the checks in order of importance so that we can give * more useful error messages first. @@ -1651,6 +1747,20 @@ g_object_get_type (void) * Construction parameters (see #G_PARAM_CONSTRUCT, #G_PARAM_CONSTRUCT_ONLY) * which are not explicitly specified are set to their default values. * + * Note that in C, small integer types in variable argument lists are promoted + * up to #gint or #guint as appropriate, and read back accordingly. #gint is 32 + * bits on every platform on which GLib is currently supported. This means that + * you can use C expressions of type #gint with g_object_new() and properties of + * type #gint or #guint or smaller. Specifically, you can use integer literals + * with these property types. + * + * When using property types of #gint64 or #guint64, you must ensure that the + * value that you provide is 64 bit. This means that you should use a cast or + * make use of the %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros. + * + * Similarly, #gfloat is promoted to #gdouble, so you must ensure that the value + * you provide is a #gdouble, even for a property of type #gfloat. + * * Returns: (transfer full) (type GObject.Object): a new instance of * @object_type */ @@ -1766,7 +1876,7 @@ g_object_new_with_custom_constructor (GObjectClass *class, */ newly_constructed = object_in_construction (object); if (newly_constructed) - g_datalist_id_set_data (&object->qdata, quark_in_construction, NULL); + unset_object_in_construction (object); if (CLASS_HAS_PROPS (class)) { @@ -2479,6 +2589,11 @@ g_object_get_valist (GObject *object, * * Sets properties on an object. * + * The same caveats about passing integer literals as varargs apply as with + * g_object_new(). In particular, any integer literals set as the values for + * properties of type #gint64 or #guint64 must be 64 bits wide, using the + * %G_GINT64_CONSTANT or %G_GUINT64_CONSTANT macros. + * * Note that the "notify" signals are queued and only emitted (in * reverse order) after all properties have been set. See * g_object_freeze_notify(). @@ -2515,20 +2630,22 @@ g_object_set (gpointer _object, * of three properties: an integer, a string and an object: * |[<!-- language="C" --> * gint intval; + * guint64 uint64val; * gchar *strval; * GObject *objval; * * g_object_get (my_object, * "int-property", &intval, + * "uint64-property", &uint64val, * "str-property", &strval, * "obj-property", &objval, * NULL); * - * // Do something with intval, strval, objval + * // Do something with intval, uint64val, strval, objval * * g_free (strval); * g_object_unref (objval); - * ]| + * ]| */ void g_object_get (gpointer _object, |