[glib/g-property: 14/14] gproperty: Allow explicit setters to skip notification
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/g-property: 14/14] gproperty: Allow explicit setters to skip notification
- Date: Mon, 4 Jul 2011 14:09:49 +0000 (UTC)
commit 4cf74c3f530c2d04bd3cea6a8e24aaaa8d2663c5
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Thu Jun 9 12:12:11 2011 +0100
gproperty: Allow explicit setters to skip notification
Explicit setter functions passed when creating a new GProperty should be
able to skip automatic notification; we simply ask them to return a
boolean value: TRUE if the value was changed, and FALSE otherwise. This
allows writing an explicit setter function that only has to deal with
setting the value and handle its side effects, instead of a more complex
one that has to acquire and release the property lock and emit the
notification by itself.
gobject/gproperty.c | 102 ++++++++++++++++++++++++++--------------
gobject/gproperty.h | 42 ++++++++--------
gobject/tests/autoproperties.c | 9 ++--
3 files changed, 92 insertions(+), 61 deletions(-)
---
diff --git a/gobject/gproperty.c b/gobject/gproperty.c
index b358990..cea937e 100644
--- a/gobject/gproperty.c
+++ b/gobject/gproperty.c
@@ -317,6 +317,45 @@
* g_object_property_new ("complex", G_PROPERTY_READWRITE, -1,
* test_object_set_complex,
* test_object_get_complex);
+ * g_property_set_prerequisite (G_PROPERTY (test_object_property[PROP_COMPLEX]),
+ * TEST_TYPE_COMPLEX);
+ * ]|
+ *
+ * <para>The accessors can be public or private functions. The implementation
+ * of an explicit setter will be called under the #GProperty lock if the
+ * property is declared using the %G_PROPERTY_ATOMIC flag; the setter should
+ * not notify the property on changes, and should return %TRUE if the value
+ * was modified. An example of a setter is:</para>
+ *
+ * |[
+ * static gboolean
+ * test_object_set_complex (gpointer self_,
+ * gpointer value_)
+ * {
+ * TestObject *self = self_;
+ * TestComplex *value = value_;
+ *
+ * if (self->priv->complex == value)
+ * return FALSE;
+ *
+ * if (self->priv->complex != NULL)
+ * {
+ * test_complex_set_back_pointer (self->priv->complex, NULL);
+ * g_object_unref (self->priv->complex);
+ * }
+ *
+ * self->priv->complex = value;
+ *
+ * if (self->priv->complex != NULL)
+ * {
+ * g_object_ref (self->priv->complex);
+ * test_complex_set_back_pointer (self->priv->complex, self);
+ * }
+ *
+ * test_object_queue_foo (self);
+ *
+ * return TRUE;
+ * }
* ]|
*
* <para>It is also possible to still pass the offset of the structure
@@ -666,13 +705,12 @@ g_##g_t##_property_set_value (GProperty *property, \
{ \
property_lock_internal (property, gobject); \
\
- ((G##G_t##Property *) property)->setter (gobject, value); \
+ retval = ((G##G_t##Property *) property)->setter (gobject, value); \
\
property_unlock_internal (property, gobject); \
\
- g_object_notify_by_pspec (gobject, (GParamSpec *) property); \
-\
- retval = TRUE; \
+ if (retval) \
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property); \
} \
else if (property->field_offset >= 0) \
{ \
@@ -1333,13 +1371,12 @@ g_enum_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GEnumProperty *) property)->setter (gobject, value);
+ retval = ((GEnumProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -1592,13 +1629,12 @@ g_flags_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GFlagsProperty *) property)->setter (gobject, value);
+ retval = ((GFlagsProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -1871,13 +1907,12 @@ g_float_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GFloatProperty *) property)->setter (gobject, value);
+ retval = ((GFloatProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -2150,13 +2185,12 @@ g_double_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GDoubleProperty *) property)->setter (gobject, value);
+ retval = ((GDoubleProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -2356,13 +2390,12 @@ g_string_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GStringProperty *) property)->setter (gobject, value);
+ retval = ((GStringProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -2572,13 +2605,12 @@ g_boxed_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GBoxedProperty *) property)->setter (gobject, value);
+ retval = ((GBoxedProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -2789,13 +2821,12 @@ g_object_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GObjectProperty *) property)->setter (gobject, value);
+ retval = ((GObjectProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
@@ -3010,13 +3041,12 @@ g_pointer_property_set_value (GProperty *property,
{
property_lock_internal (property, gobject);
- ((GPointerProperty *) property)->setter (gobject, value);
+ retval = ((GPointerProperty *) property)->setter (gobject, value);
property_unlock_internal (property, gobject);
- g_object_notify_by_pspec (gobject, (GParamSpec *) property);
-
- retval = TRUE;
+ if (retval)
+ g_object_notify_by_pspec (gobject, (GParamSpec *) property);
}
else if (property->field_offset >= 0)
{
diff --git a/gobject/gproperty.h b/gobject/gproperty.h
index 668f773..3b73106 100644
--- a/gobject/gproperty.h
+++ b/gobject/gproperty.h
@@ -180,87 +180,87 @@ void _g_property_set_installed (GProperty *property,
GType class_gtype);
/* per-type specific accessors */
-typedef void (* GPropertyBooleanSet) (gpointer gobject,
+typedef gboolean (* GPropertyBooleanSet) (gpointer gobject,
gboolean value);
typedef gboolean (* GPropertyBooleanGet) (gpointer gobject);
-typedef void (* GPropertyIntSet) (gpointer gobject,
+typedef gboolean (* GPropertyIntSet) (gpointer gobject,
gint value);
typedef gint (* GPropertyIntGet) (gpointer gobject);
-typedef void (* GPropertyInt8Set) (gpointer gobject,
+typedef gboolean (* GPropertyInt8Set) (gpointer gobject,
gint8 value);
typedef gint8 (* GPropertyInt8Get) (gpointer gobject);
-typedef void (* GPropertyInt16Set) (gpointer gobject,
+typedef gboolean (* GPropertyInt16Set) (gpointer gobject,
gint16 value);
typedef gint16 (* GPropertyInt16Get) (gpointer gobject);
-typedef void (* GPropertyInt32Set) (gpointer gobject,
+typedef gboolean (* GPropertyInt32Set) (gpointer gobject,
gint32 value);
typedef gint32 (* GPropertyInt32Get) (gpointer gobject);
-typedef void (* GPropertyInt64Set) (gpointer gobject,
+typedef gboolean (* GPropertyInt64Set) (gpointer gobject,
gint64 value);
typedef gint64 (* GPropertyInt64Get) (gpointer gobject);
-typedef void (* GPropertyLongSet) (gpointer gobject,
+typedef gboolean (* GPropertyLongSet) (gpointer gobject,
glong value);
typedef glong (* GPropertyLongGet) (gpointer gobject);
-typedef void (* GPropertyUIntSet) (gpointer gobject,
+typedef gboolean (* GPropertyUIntSet) (gpointer gobject,
guint value);
typedef guint (* GPropertyUIntGet) (gpointer gobject);
-typedef void (* GPropertyUInt8Set) (gpointer gobject,
+typedef gboolean (* GPropertyUInt8Set) (gpointer gobject,
guint8 value);
typedef guint8 (* GPropertyUInt8Get) (gpointer gobject);
-typedef void (* GPropertyUInt16Set) (gpointer gobject,
+typedef gboolean (* GPropertyUInt16Set) (gpointer gobject,
guint16 value);
typedef guint16 (* GPropertyUInt16Get) (gpointer gobject);
-typedef void (* GPropertyUInt32Set) (gpointer gobject,
+typedef gboolean (* GPropertyUInt32Set) (gpointer gobject,
guint32 value);
typedef guint32 (* GPropertyUInt32Get) (gpointer gobject);
-typedef void (* GPropertyUInt64Set) (gpointer gobject,
+typedef gboolean (* GPropertyUInt64Set) (gpointer gobject,
guint64 value);
typedef guint64 (* GPropertyUInt64Get) (gpointer gobject);
-typedef void (* GPropertyULongSet) (gpointer gobject,
+typedef gboolean (* GPropertyULongSet) (gpointer gobject,
gulong value);
typedef gulong (* GPropertyULongGet) (gpointer gobject);
-typedef void (* GPropertyEnumSet) (gpointer gobject,
+typedef gboolean (* GPropertyEnumSet) (gpointer gobject,
glong value);
typedef glong (* GPropertyEnumGet) (gpointer gobject);
-typedef void (* GPropertyFlagsSet) (gpointer gobject,
+typedef gboolean (* GPropertyFlagsSet) (gpointer gobject,
glong value);
typedef glong (* GPropertyFlagsGet) (gpointer gobject);
-typedef void (* GPropertyFloatSet) (gpointer gobject,
+typedef gboolean (* GPropertyFloatSet) (gpointer gobject,
gfloat value);
typedef gfloat (* GPropertyFloatGet) (gpointer gobject);
-typedef void (* GPropertyDoubleSet) (gpointer gobject,
+typedef gboolean (* GPropertyDoubleSet) (gpointer gobject,
gdouble value);
typedef gdouble (* GPropertyDoubleGet) (gpointer gobject);
-typedef void (* GPropertyStringSet) (gpointer gobject,
+typedef gboolean (* GPropertyStringSet) (gpointer gobject,
const char *value);
typedef const char * (* GPropertyStringGet) (gpointer gobject);
-typedef void (* GPropertyBoxedSet) (gpointer gobject,
+typedef gboolean (* GPropertyBoxedSet) (gpointer gobject,
gpointer value);
typedef gpointer (* GPropertyBoxedGet) (gpointer gobject);
-typedef void (* GPropertyObjectSet) (gpointer gobject,
+typedef gboolean (* GPropertyObjectSet) (gpointer gobject,
gpointer value);
typedef gpointer (* GPropertyObjectGet) (gpointer gobject);
-typedef void (* GPropertyPointerSet) (gpointer gobject,
+typedef gboolean (* GPropertyPointerSet) (gpointer gobject,
gpointer value);
typedef gpointer (* GPropertyPointerGet) (gpointer gobject);
diff --git a/gobject/tests/autoproperties.c b/gobject/tests/autoproperties.c
index 2f2127b..69522e8 100644
--- a/gobject/tests/autoproperties.c
+++ b/gobject/tests/autoproperties.c
@@ -212,18 +212,18 @@ test_object_get_boxed (TestObject *self,
*value = *boxed;
}
-void
+gboolean
test_object_set_str (TestObject *self,
const gchar *value)
{
TestObjectPrivate *priv;
- g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, test_object_get_type ()));
+ g_return_val_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (self, test_object_get_type ()), FALSE);
priv = self->priv;
if (g_strcmp0 (priv->str, value) == 0)
- return;
+ return FALSE;
g_free (priv->str);
priv->str = g_strdup (value);
@@ -233,8 +233,9 @@ test_object_set_str (TestObject *self,
else
priv->str_set = FALSE;
- g_object_notify_by_pspec (G_OBJECT (self), test_object_properties[PROP_STR]);
g_object_notify_by_pspec (G_OBJECT (self), test_object_properties[PROP_STR_SET]);
+
+ return TRUE;
}
G_DEFINE_PROPERTY_GET (TestObject, test_object, const gchar *, str);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]