diff options
Diffstat (limited to 'gobject/gproperty.c')
-rw-r--r-- | gobject/gproperty.c | 153 |
1 files changed, 118 insertions, 35 deletions
diff --git a/gobject/gproperty.c b/gobject/gproperty.c index b94b62b3e..89ff1d5f7 100644 --- a/gobject/gproperty.c +++ b/gobject/gproperty.c @@ -156,11 +156,18 @@ * ]| * <para>Note that calling g_property_set() for a property holding a * complex type (e.g. #GObject or #GBoxed) without a specific setter - * function will result in the value being copied in the private data - * structure's field. In contrast, calling g_property_get() will return - * a pointer to the private data structure's field: it is up to the - * getter function to decide whether to return a copy of the internal - * data or the pointer itself.</para> + * function will, by default, result in the pointer to the new value + * being copied in the private data structure's field; if you need to + * copy a boxed type, or take a reference on an object type, you will + * need to set the %G_PROPERTY_COPY_SET flag when creating the + * property.</para> + * + * <para>Calling g_property_get() will return a pointer to the private + * data structure's field, unless %G_PROPERTY_COPY_GET is set when + * creating the property, in which case the returned value will either + * be a copy of the private data structure field if it is a boxed type + * or the instance with its reference count increased if it is an object + * type.</para> * </refsect3> * * <refsect3> @@ -363,7 +370,7 @@ * * |[ * test_object_property[PROP_WIDTH] = - * g_int_property_new ("width", G_PROPERTY_READWRITE, + * g_int_property_new ("width", G_PROPERTY_READWRITE | G_PROPERTY_COPY_SET, * G_STRUCT_OFFSET (TestObjectPrivate, width), * test_object_set_width, /* explicit setter */ * NULL /* implicit getter */); @@ -432,7 +439,7 @@ * |[ * G_DEFINE_PROPERTY_GET (TestObject, test_object, int, width) * G_DEFINE_PROPERTY_SET_WITH_CODE (Test_object, test_object, int, width, - * test_object_queue_resize (self)) + * test_object_queue_action (self)) * ]| * * <para>The WITH_CODE variant of the setter will define the "self" and @@ -2405,8 +2412,13 @@ g_string_property_set_value (GProperty *property, return FALSE; } - g_free (str); - (* (gpointer *) field_p) = g_strdup (value); + if (property->flags & G_PROPERTY_COPY_SET) + { + g_free (str); + (* (gpointer *) field_p) = g_strdup (value); + } + else + (* (gpointer *) field_p) = (gpointer) value; property_unlock_internal (property, gobject); @@ -2446,7 +2458,10 @@ g_string_property_get_value (GProperty *property, priv_p = get_private_pointer (gobject, property->priv_offset); field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); - retval = (* (gpointer *) field_p); + if (property->flags & G_PROPERTY_COPY_GET) + retval = g_strdup ((* (gpointer *) field_p)); + else + retval = (* (gpointer *) field_p); return retval; } @@ -2612,15 +2627,20 @@ g_boxed_property_set_value (GProperty *property, priv_p = get_private_pointer (gobject, property->priv_offset); field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); - old_value = (* (gpointer *) field_p); + if (property->flags & G_PROPERTY_COPY_SET) + { + old_value = (* (gpointer *) field_p); - if (value != NULL) - (* (gpointer *) field_p) = g_boxed_copy (((GParamSpec *) property)->value_type, value); - else - (* (gpointer *) field_p) = NULL; + if (value != NULL) + (* (gpointer *) field_p) = g_boxed_copy (((GParamSpec *) property)->value_type, value); + else + (* (gpointer *) field_p) = NULL; - if (old_value != NULL) - g_boxed_free (((GParamSpec *) property)->value_type, old_value); + if (old_value != NULL) + g_boxed_free (((GParamSpec *) property)->value_type, old_value); + } + else + (* (gpointer *) field_p) = value; property_unlock_internal (property, gobject); @@ -2659,7 +2679,11 @@ g_boxed_property_get_value (GProperty *property, priv_p = get_private_pointer (gobject, property->priv_offset); field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); - value = (* (gpointer *) field_p); + + if (property->flags & G_PROPERTY_COPY_GET) + value = g_boxed_copy (((GParamSpec *) property)->value_type, (* (gpointer *) field_p)); + else + value = (* (gpointer *) field_p); return value; } @@ -2836,19 +2860,24 @@ g_object_property_set_value (GProperty *property, return FALSE; } - obj = (* (gpointer *) field_p); - if (obj != NULL) - g_object_unref (obj); - - (* (gpointer *) field_p) = obj = value; - - if (obj != NULL) + if (property->flags & G_PROPERTY_COPY_SET) { - if (G_IS_INITIALLY_UNOWNED (obj)) - g_object_ref_sink (obj); - else - g_object_ref (obj); + obj = (* (gpointer *) field_p); + if (obj != NULL) + g_object_unref (obj); + + (* (gpointer *) field_p) = obj = value; + + if (obj != NULL) + { + if (G_IS_INITIALLY_UNOWNED (obj)) + g_object_ref_sink (obj); + else + g_object_ref (obj); + } } + else + (* (gpointer *) field_p) = value; property_unlock_internal (property, gobject); @@ -2887,7 +2916,17 @@ g_object_property_get_value (GProperty *property, priv_p = g_type_instance_get_private (gobject, G_OBJECT_TYPE (gobject)); field_p = G_STRUCT_MEMBER_P (priv_p, property->field_offset); - return (* (gpointer *) field_p); + if (property->flags & G_PROPERTY_COPY_GET) + { + gpointer value = (* (gpointer *) field_p); + + if (value != NULL) + return g_object_ref (value); + else + return NULL; + } + else + return (* (gpointer *) field_p); } else { @@ -4558,8 +4597,11 @@ g_property_get_valist (GProperty *property, value = g_string_property_get_value (property, gobject); - if ((flags & G_PROPERTY_COLLECT_COPY) != 0) - (* (gchar **) ret_p) = g_strdup (value); + if (((flags & G_PROPERTY_COLLECT_COPY) != 0) && + (property->flags & G_PROPERTY_COPY_GET) == 0) + { + (* (gchar **) ret_p) = g_strdup (value); + } else (* (gconstpointer *) ret_p) = value; } @@ -4571,7 +4613,8 @@ g_property_get_valist (GProperty *property, boxed = g_boxed_property_get_value (property, gobject); - if ((flags & G_PROPERTY_COLLECT_COPY) != 0) + if (((flags & G_PROPERTY_COLLECT_COPY) != 0) && + (property->flags & G_PROPERTY_COPY_GET) == 0) { if (boxed != NULL) (* (gpointer *) ret_p) = g_boxed_copy (gtype, boxed); @@ -4587,8 +4630,12 @@ g_property_get_valist (GProperty *property, { gpointer obj = g_object_property_get_value (property, gobject); - if (((flags & G_PROPERTY_COLLECT_REF) != 0) && obj != NULL) - (* (gpointer *) ret_p) = g_object_ref (obj); + if ((((flags & G_PROPERTY_COLLECT_REF) != 0) && + (property->flags & G_PROPERTY_COPY_GET) == 0) && + (obj != NULL)) + { + (* (gpointer *) ret_p) = g_object_ref (obj); + } else (* (gpointer *) ret_p) = obj; } @@ -5349,6 +5396,42 @@ g_property_is_atomic (GProperty *property) } /** + * g_property_is_copy_set: + * @property: a #GProperty + * + * Checks whether the @property has the %G_PROPERTY_COPY_SET flag set. + * + * Return value: %TRUE if the flag is set, and %FALSE otherwise + * + * Since: 2.30 + */ +gboolean +g_property_is_copy_set (GProperty *property) +{ + g_return_val_if_fail (G_IS_PROPERTY (property), FALSE); + + return (property->flags & G_PROPERTY_COPY_SET) != 0; +} + +/** + * g_property_is_copy_get: + * @property: a #GProperty + * + * Checks whether the @property has the %G_PROPERTY_COPY_GET flag set. + * + * Return value: %TRUE if the flag is set, and %FALSE otherwise + * + * Since: 2.30 + */ +gboolean +g_property_is_copy_get (GProperty *property) +{ + g_return_val_if_fail (G_IS_PROPERTY (property), FALSE); + + return (property->flags & G_PROPERTY_COPY_GET) != 0; +} + +/** * g_property_lock: * @property: a #GProperty * @gobject: a #GObject |