[glib] Introduce g_object_notify_by_pspec()



commit f3879a4bdca2ff1cf6c6b016d67a7e5d40c0e86b
Author: Damien Lespiau <damien lespiau gmail com>
Date:   Sat Apr 10 15:50:40 2010 +0100

    Introduce g_object_notify_by_pspec()
    
    g_object_notify_by_pspec() will emit the "notify" signal on the given
    pspec, short-circuiting the hash table lookup needed by
    g_object_notify(). The suggested and documented way of using
    g_object_notify_by_pspec() is similar to the way of emitting signals
    with their ID.
    
    Emission tests (with no handler attached to the notify signal) show a
    10-15% speedup over using g_object_notify().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=615425

 docs/reference/gobject/gobject-sections.txt |    1 +
 gobject/gobject.c                           |   82 ++++++++++++++++++++++++--
 gobject/gobject.h                           |    2 +
 gobject/gobject.symbols                     |    1 +
 4 files changed, 79 insertions(+), 7 deletions(-)
---
diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt
index 942bb0f..6c53448 100644
--- a/docs/reference/gobject/gobject-sections.txt
+++ b/docs/reference/gobject/gobject-sections.txt
@@ -269,6 +269,7 @@ g_object_disconnect
 g_object_set
 g_object_get
 g_object_notify
+g_object_notify_by_pspec
 g_object_freeze_notify
 g_object_thaw_notify
 g_object_get_data
diff --git a/gobject/gobject.c b/gobject/gobject.c
index ddfb47b..1b42070 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -849,12 +849,27 @@ g_object_freeze_notify (GObject *object)
   g_object_unref (object);
 }
 
+static inline void
+g_object_notify_by_spec_internal (GObject    *object,
+				  GParamSpec *pspec)
+{
+  GObjectNotifyQueue *nqueue;
+
+  nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
+  g_object_notify_queue_add (object, nqueue, pspec);
+  g_object_notify_queue_thaw (object, nqueue);
+}
+
 /**
  * g_object_notify:
  * @object: a #GObject
  * @property_name: the name of a property installed on the class of @object.
  *
  * Emits a "notify" signal for the property @property_name on @object.
+ *
+ * When possible, eg. when signaling a property change from within the class
+ * that registered the property, you should use g_object_notify_by_pspec()
+ * instead.
  */
 void
 g_object_notify (GObject     *object,
@@ -883,13 +898,66 @@ g_object_notify (GObject     *object,
 	       G_OBJECT_TYPE_NAME (object),
 	       property_name);
   else
-    {
-      GObjectNotifyQueue *nqueue;
-      
-      nqueue = g_object_notify_queue_freeze (object, &property_notify_context);
-      g_object_notify_queue_add (object, nqueue, pspec);
-      g_object_notify_queue_thaw (object, nqueue);
-    }
+    g_object_notify_by_spec_internal (object, pspec);
+  g_object_unref (object);
+}
+
+/**
+ * g_object_notify_by_pspec:
+ * @object: a #GObject
+ * @pspec: the #GParamSpec of a property installed on the class of @object.
+ *
+ * Emits a "notify" signal for the property specified by @pspec on @object.
+ *
+ * This function omits the property name lookup, hence it is faster than
+ * g_object_notify().
+ *
+ * One way to avoid using g_object_notify() from within the
+ * class that registered the properties, and using g_object_notify_by_pspec()
+ * instead, is to store the GParamSpec used with
+ * g_object_class_install_property() inside a static array, e.g.:
+ *
+ *|[
+ *   enum
+ *   {
+ *     PROP_0,
+ *     PROP_FOO,
+ *     PROP_LAST
+ *   };
+ *
+ *   static GParamSpec *properties[PROP_LAST];
+ *
+ *   static void
+ *   my_object_class_init (MyObjectClass *klass)
+ *   {
+ *     properties[PROP_FOO] = g_param_spec_int ("foo", "Foo", "The foo",
+ *                                              0, 100,
+ *                                              50,
+ *                                              G_PARAM_READWRITE);
+ *     g_object_class_install_property (gobject_class,
+ *                                      PROP_FOO,
+ *                                      properties[PROP_FOO]);
+ *   }
+ * ]|
+ *
+ * and then notify a change on the "foo" property with:
+ *
+ * |[
+ *   g_object_notify_by_pspec (self, properties[PROP_FOO]);
+ * ]|
+ *
+ * Since: 2.26
+ */
+void
+g_object_notify_by_pspec (GObject    *object,
+			  GParamSpec *pspec)
+{
+
+  g_return_if_fail (G_IS_OBJECT (object));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+
+  g_object_ref (object);
+  g_object_notify_by_spec_internal (object, pspec);
   g_object_unref (object);
 }
 
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 751e5f2..6707224 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -435,6 +435,8 @@ void        g_object_get_property             (GObject        *object,
 void        g_object_freeze_notify            (GObject        *object);
 void        g_object_notify                   (GObject        *object,
 					       const gchar    *property_name);
+void        g_object_notify_by_pspec          (GObject        *object,
+					       GParamSpec     *pspec);
 void        g_object_thaw_notify              (GObject        *object);
 gboolean    g_object_is_floating    	      (gpointer        object);
 gpointer    g_object_ref_sink       	      (gpointer	       object);
diff --git a/gobject/gobject.symbols b/gobject/gobject.symbols
index 871e7cd..df9c39b 100644
--- a/gobject/gobject.symbols
+++ b/gobject/gobject.symbols
@@ -141,6 +141,7 @@ g_object_new
 g_object_newv
 g_object_new_valist
 g_object_notify
+g_object_notify_by_pspec
 g_object_is_floating
 g_object_ref_sink
 g_object_force_floating



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