diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2013-06-25 22:50:22 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2013-07-05 18:13:55 +0100 |
commit | 55941c1e1a87e84af5d2af1fce37ddad43772f8d (patch) | |
tree | f33097396a1421b19a97e1f7fdb68d46c4e26328 | |
parent | b4e3aa15c7445c9d26ed7dd53e978d4a4edf39b3 (diff) | |
download | glib-55941c1e1a87e84af5d2af1fce37ddad43772f8d.tar.gz |
property: Remove implicit notify with explicit setters
If the user passes an explicit setter function when creating a
GProperty, we assume that a notify signal will be emitted. For direct
access to a structure field, we can emit an implicit notification
ourselves, since we know that if the value has changed.
This changes the signature of the explicit setter functions.
-rw-r--r-- | gobject/gobject.c | 31 | ||||
-rw-r--r-- | gobject/gproperty.c | 82 | ||||
-rw-r--r-- | gobject/gproperty.h | 53 | ||||
-rw-r--r-- | gobject/tests/property.c | 22 |
4 files changed, 90 insertions, 98 deletions
diff --git a/gobject/gobject.c b/gobject/gobject.c index 8b011c427..42977ef3a 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -1215,27 +1215,26 @@ static inline void g_object_notify_by_spec_internal (GObject *object, GParamSpec *pspec) { + GObjectNotifyQueue *nqueue; GParamSpec *notify_pspec; notify_pspec = get_notify_pspec (pspec); + if (notify_pspec == NULL) + return; - if (notify_pspec != NULL) - { - GObjectNotifyQueue *nqueue; - - /* conditional freeze: only increase freeze count if already frozen */ - nqueue = g_object_notify_queue_freeze (object, TRUE); + /* conditional freeze: only increase freeze count if already frozen */ + nqueue = g_object_notify_queue_freeze (object, TRUE); - if (nqueue != NULL) - { - /* we're frozen, so add to the queue and release our freeze */ - g_object_notify_queue_add (object, nqueue, notify_pspec); - g_object_notify_queue_thaw (object, nqueue); - } - else - /* not frozen, so just dispatch the notification directly */ - G_OBJECT_GET_CLASS (object) - ->dispatch_properties_changed (object, 1, ¬ify_pspec); + if (nqueue != NULL) + { + /* we're frozen, so add to the queue and release our freeze */ + g_object_notify_queue_add (object, nqueue, notify_pspec); + g_object_notify_queue_thaw (object, nqueue); + } + else + { + /* not frozen, so just dispatch the notification directly */ + G_OBJECT_GET_CLASS (object)->dispatch_properties_changed (object, 1, ¬ify_pspec); } } diff --git a/gobject/gproperty.c b/gobject/gproperty.c index 08dac08e3..acb896fc3 100644 --- a/gobject/gproperty.c +++ b/gobject/gproperty.c @@ -195,21 +195,20 @@ * ]| * * <para>The accessors can be public or private functions. The implementation - * of the setter function should not explicitly emit a notification when the - * property changes: returning %TRUE if the value was modified will result in - * a #GObject::notify signal being automatically emitted. An example of a - * setter is:</para> + * of the setter function should explicitly emit a notification when the + * property changes. An example of an explicit setter is:</para> * * |[ - * static gboolean + * static void * test_object_set_complex_internal (gpointer self_, * gpointer value_) * { * TestObject *self = self_; * TestComplex *value = value_; * + * /* no need to perform any work if the value is the same */ * if (self->priv->complex == value) - * return FALSE; + * return; * * if (self->priv->complex != NULL) * { @@ -227,7 +226,7 @@ * * test_object_queue_foo (self); * - * return TRUE; + * g_object_notify (self, "complex"); * } * ]| * @@ -590,10 +589,9 @@ g_##g_t##_property_set_value (GProperty *property, \ \ if (((G##G_t##Property *) property)->setter != NULL) \ { \ - retval = ((G##G_t##Property *) property)->setter (gobject, value); \ + ((G##G_t##Property *) property)->setter (gobject, value); \ \ - if (retval) \ - g_object_notify_by_pspec (gobject, (GParamSpec *) property); \ + retval = FALSE; \ } \ else if (property->field_offset != 0) \ { \ @@ -605,8 +603,6 @@ g_##g_t##_property_set_value (GProperty *property, \ { \ (* (c_t *) field_p) = value; \ \ - g_object_notify_by_pspec (gobject, (GParamSpec *) property); \ -\ retval = TRUE; \ } \ } \ @@ -1058,10 +1054,9 @@ g_enum_property_set_value (GProperty *property, if (((GEnumProperty *) property)->setter != NULL) { - retval = ((GEnumProperty *) property)->setter (gobject, value); + ((GEnumProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -1073,8 +1068,6 @@ g_enum_property_set_value (GProperty *property, { (* (gint *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } } @@ -1277,10 +1270,9 @@ g_flags_property_set_value (GProperty *property, if (((GFlagsProperty *) property)->setter != NULL) { - retval = ((GFlagsProperty *) property)->setter (gobject, value); + ((GFlagsProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -1292,8 +1284,6 @@ g_flags_property_set_value (GProperty *property, { (* (guint *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } } @@ -1516,10 +1506,9 @@ g_float_property_set_value (GProperty *property, if (((GFloatProperty *) property)->setter != NULL) { - retval = ((GFloatProperty *) property)->setter (gobject, value); + ((GFloatProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -1531,8 +1520,6 @@ g_float_property_set_value (GProperty *property, { (* (gfloat *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } } @@ -1755,10 +1742,9 @@ g_double_property_set_value (GProperty *property, if (((GDoubleProperty *) property)->setter != NULL) { - retval = ((GDoubleProperty *) property)->setter (gobject, value); + ((GDoubleProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -1770,8 +1756,6 @@ g_double_property_set_value (GProperty *property, { (* (gdouble *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } } @@ -1921,10 +1905,9 @@ g_string_property_set_value (GProperty *property, if (((GStringProperty *) property)->setter != NULL) { - retval = ((GStringProperty *) property)->setter (gobject, value); + ((GStringProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -1946,8 +1929,6 @@ g_string_property_set_value (GProperty *property, else (* (gpointer *) field_p) = (gpointer) value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } else @@ -2109,10 +2090,9 @@ g_boxed_property_set_value (GProperty *property, if (((GBoxedProperty *) property)->setter != NULL) { - retval = ((GBoxedProperty *) property)->setter (gobject, value); + ((GBoxedProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -2136,8 +2116,6 @@ g_boxed_property_set_value (GProperty *property, else (* (gpointer *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } else @@ -2301,10 +2279,9 @@ g_object_property_set_value (GProperty *property, if (((GObjectProperty *) property)->setter != NULL) { - retval = ((GObjectProperty *) property)->setter (gobject, value); + ((GObjectProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -2337,8 +2314,6 @@ g_object_property_set_value (GProperty *property, else (* (gpointer *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } else @@ -2498,10 +2473,9 @@ g_pointer_property_set_value (GProperty *property, if (((GPointerProperty *) property)->setter != NULL) { - retval = ((GPointerProperty *) property)->setter (gobject, value); + ((GPointerProperty *) property)->setter (gobject, value); - if (retval) - g_object_notify_by_pspec (gobject, (GParamSpec *) property); + retval = FALSE; } else if (property->field_offset != 0) { @@ -2513,8 +2487,6 @@ g_pointer_property_set_value (GProperty *property, { (* (gpointer *) field_p) = value; - g_object_notify_by_pspec (gobject, (GParamSpec *) property); - retval = TRUE; } } @@ -3841,6 +3813,9 @@ g_property_set_va (GProperty *property, break; } + if (retval) + g_object_notify_by_pspec (gobject, (GParamSpec *) property); + g_object_unref (gobject); return retval; @@ -4221,6 +4196,9 @@ g_property_set_value_internal (GProperty *property, break; } + if (res) + g_object_notify_by_pspec (gobject, (GParamSpec *) property); + g_object_unref (gobject); return res; diff --git a/gobject/gproperty.h b/gobject/gproperty.h index 709afefac..35aca858c 100644 --- a/gobject/gproperty.h +++ b/gobject/gproperty.h @@ -199,87 +199,87 @@ gboolean g_property_get_va (GProperty *property, va_list *app); /* per-type specific accessors */ -typedef gboolean (* GPropertyBooleanSet) (gpointer gobject, +typedef void (* GPropertyBooleanSet) (gpointer gobject, gboolean value); typedef gboolean (* GPropertyBooleanGet) (gpointer gobject); -typedef gboolean (* GPropertyIntSet) (gpointer gobject, +typedef void (* GPropertyIntSet) (gpointer gobject, gint value); typedef gint (* GPropertyIntGet) (gpointer gobject); -typedef gboolean (* GPropertyInt8Set) (gpointer gobject, +typedef void (* GPropertyInt8Set) (gpointer gobject, gint8 value); typedef gint8 (* GPropertyInt8Get) (gpointer gobject); -typedef gboolean (* GPropertyInt16Set) (gpointer gobject, +typedef void (* GPropertyInt16Set) (gpointer gobject, gint16 value); typedef gint16 (* GPropertyInt16Get) (gpointer gobject); -typedef gboolean (* GPropertyInt32Set) (gpointer gobject, +typedef void (* GPropertyInt32Set) (gpointer gobject, gint32 value); typedef gint32 (* GPropertyInt32Get) (gpointer gobject); -typedef gboolean (* GPropertyInt64Set) (gpointer gobject, +typedef void (* GPropertyInt64Set) (gpointer gobject, gint64 value); typedef gint64 (* GPropertyInt64Get) (gpointer gobject); -typedef gboolean (* GPropertyLongSet) (gpointer gobject, +typedef void (* GPropertyLongSet) (gpointer gobject, glong value); typedef glong (* GPropertyLongGet) (gpointer gobject); -typedef gboolean (* GPropertyUIntSet) (gpointer gobject, +typedef void (* GPropertyUIntSet) (gpointer gobject, guint value); typedef guint (* GPropertyUIntGet) (gpointer gobject); -typedef gboolean (* GPropertyUInt8Set) (gpointer gobject, +typedef void (* GPropertyUInt8Set) (gpointer gobject, guint8 value); typedef guint8 (* GPropertyUInt8Get) (gpointer gobject); -typedef gboolean (* GPropertyUInt16Set) (gpointer gobject, +typedef void (* GPropertyUInt16Set) (gpointer gobject, guint16 value); typedef guint16 (* GPropertyUInt16Get) (gpointer gobject); -typedef gboolean (* GPropertyUInt32Set) (gpointer gobject, +typedef void (* GPropertyUInt32Set) (gpointer gobject, guint32 value); typedef guint32 (* GPropertyUInt32Get) (gpointer gobject); -typedef gboolean (* GPropertyUInt64Set) (gpointer gobject, +typedef void (* GPropertyUInt64Set) (gpointer gobject, guint64 value); typedef guint64 (* GPropertyUInt64Get) (gpointer gobject); -typedef gboolean (* GPropertyULongSet) (gpointer gobject, +typedef void (* GPropertyULongSet) (gpointer gobject, gulong value); typedef gulong (* GPropertyULongGet) (gpointer gobject); -typedef gboolean (* GPropertyEnumSet) (gpointer gobject, +typedef void (* GPropertyEnumSet) (gpointer gobject, gint value); typedef gint (* GPropertyEnumGet) (gpointer gobject); -typedef gboolean (* GPropertyFlagsSet) (gpointer gobject, +typedef void (* GPropertyFlagsSet) (gpointer gobject, guint value); typedef guint (* GPropertyFlagsGet) (gpointer gobject); -typedef gboolean (* GPropertyFloatSet) (gpointer gobject, +typedef void (* GPropertyFloatSet) (gpointer gobject, gfloat value); typedef gfloat (* GPropertyFloatGet) (gpointer gobject); -typedef gboolean (* GPropertyDoubleSet) (gpointer gobject, +typedef void (* GPropertyDoubleSet) (gpointer gobject, gdouble value); typedef gdouble (* GPropertyDoubleGet) (gpointer gobject); -typedef gboolean (* GPropertyStringSet) (gpointer gobject, +typedef void (* GPropertyStringSet) (gpointer gobject, const char *value); typedef const char * (* GPropertyStringGet) (gpointer gobject); -typedef gboolean (* GPropertyBoxedSet) (gpointer gobject, +typedef void (* GPropertyBoxedSet) (gpointer gobject, gpointer value); typedef gpointer (* GPropertyBoxedGet) (gpointer gobject); -typedef gboolean (* GPropertyObjectSet) (gpointer gobject, +typedef void (* GPropertyObjectSet) (gpointer gobject, gpointer value); typedef gpointer (* GPropertyObjectGet) (gpointer gobject); -typedef gboolean (* GPropertyPointerSet) (gpointer gobject, +typedef void (* GPropertyPointerSet) (gpointer gobject, gpointer value); typedef gpointer (* GPropertyPointerGet) (gpointer gobject); @@ -747,6 +747,7 @@ void g_property_init_default (GProperty *property, #define _G_DEFINE_PROPERTY_SETTER_BEGIN(T_n, t_n, f_t, f_n) \ { \ GProperty *g_property = NULL; \ + GObject *g_object; \ \ g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, t_n##_get_type ())); \ \ @@ -771,12 +772,20 @@ void g_property_init_default (GProperty *property, } \ } \ \ + g_object = G_OBJECT (self); \ + g_object_freeze_notify (g_object); \ +\ if (!g_property_set (g_property, self, value)) \ - return; \ + { \ + g_object_thaw_notify (g_object); \ + return; \ + } \ \ { /* custom code follows */ #define _G_DEFINE_PROPERTY_SETTER_END \ }/* following custom code */ \ +\ + g_object_thaw_notify (g_object); \ } /** diff --git a/gobject/tests/property.c b/gobject/tests/property.c index 477e0a106..9b8614299 100644 --- a/gobject/tests/property.c +++ b/gobject/tests/property.c @@ -84,19 +84,20 @@ test_object_finalize (GObject *gobject) G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject); } -static gboolean +static void test_object_set_enum_val_internal (gpointer obj, gint val) { TestObjectPrivate *priv = test_object_get_instance_private (obj); if (priv->enum_val == val) - return FALSE; + return; priv->enum_val = val; priv->enum_val_set = val != TEST_ENUM_UNSET; - return TRUE; + g_object_notify (obj, "enum-val"); + g_object_notify (obj, "enum-val-set"); } static void @@ -303,21 +304,26 @@ static void gproperty_explicit_set (void) { TestObject *obj = g_object_new (test_object_get_type (), NULL); - gboolean did_emit_notify = FALSE; + gboolean did_emit_notify_1 = FALSE; + gboolean did_emit_notify_2 = FALSE; TestEnum enum_val; - g_signal_connect (obj, "notify::enum-val", G_CALLBACK (check_notify_emission), &did_emit_notify); + g_signal_connect (obj, "notify::enum-val", G_CALLBACK (check_notify_emission), &did_emit_notify_1); + g_signal_connect (obj, "notify::enum-val-set", G_CALLBACK (check_notify_emission), &did_emit_notify_2); g_object_set (obj, "enum-val", TEST_ENUM_THREE, NULL); g_assert_cmpint (test_object_get_enum_val (obj), ==, TEST_ENUM_THREE); g_assert (test_object_get_enum_val_set (obj)); - g_assert (did_emit_notify); + g_assert (did_emit_notify_1); + g_assert (did_emit_notify_2); - did_emit_notify = FALSE; + did_emit_notify_1 = FALSE; + did_emit_notify_2 = FALSE; test_object_set_enum_val (obj, TEST_ENUM_THREE); g_object_get (obj, "enum-val", &enum_val, NULL); g_assert_cmpint (enum_val, ==, TEST_ENUM_THREE); - g_assert (!did_emit_notify); + g_assert (!did_emit_notify_1); + g_assert (!did_emit_notify_2); g_object_unref (obj); } |