[glib/wip/gproperty-2: 56/57] property: Remove implicit notify with explicit setters



commit 55941c1e1a87e84af5d2af1fce37ddad43772f8d
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Tue Jun 25 22:50:22 2013 +0100

    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.

 gobject/gobject.c        |   31 ++++++++---------
 gobject/gproperty.c      |   82 +++++++++++++++++-----------------------------
 gobject/gproperty.h      |   53 +++++++++++++++++------------
 gobject/tests/property.c |   22 ++++++++----
 4 files changed, 90 insertions(+), 98 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 8b011c4..42977ef 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 08dac08..acb896f 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 709afef..35aca85 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 477e0a1..9b86142 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);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]