summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuele Bassi <ebassi@gnome.org>2013-06-25 22:50:22 +0100
committerEmmanuele Bassi <ebassi@gnome.org>2013-07-05 18:13:55 +0100
commit55941c1e1a87e84af5d2af1fce37ddad43772f8d (patch)
treef33097396a1421b19a97e1f7fdb68d46c4e26328
parentb4e3aa15c7445c9d26ed7dd53e978d4a4edf39b3 (diff)
downloadglib-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.c31
-rw-r--r--gobject/gproperty.c82
-rw-r--r--gobject/gproperty.h53
-rw-r--r--gobject/tests/property.c22
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, &notify_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, &notify_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_;
*
+ * /&ast; no need to perform any work if the value is the same &ast;/
* 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);
}