[glib/wip/gproperty-2: 3/8] gobject: Use GProperty varargs API when accessing properties



commit 822168b1328ddc964d5a35a806947cba4bef92bc
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Apr 24 16:04:21 2013 -0400

    gobject: Use GProperty varargs API when accessing properties
    
    Instead of using GValue, let's take advantage of the fast paths with no
    boxing/unboxing inside GProperty.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=648526

 gobject/gobject.c |  185 +++++++++++++++++++++++++++++++++-------------------
 1 files changed, 117 insertions(+), 68 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 4fe86d8..e923e15 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -2076,35 +2076,22 @@ g_object_constructed (GObject *object)
   /* empty default impl to allow unconditional upchaining */
 }
 
-/**
- * g_object_set_valist: (skip)
- * @object: a #GObject
- * @first_property_name: name of the first property to set
- * @var_args: value for the first property, followed optionally by more
- *  name/value pairs, followed by %NULL
- *
- * Sets properties on an object.
- */
-void
-g_object_set_valist (GObject    *object,
-                    const gchar *first_property_name,
-                    va_list      var_args)
+static inline void
+object_set_valist_internal (GObject    *object,
+                            const char *first_property_name,
+                            va_list    *var_args)
 {
   GObjectNotifyQueue *nqueue;
   const gchar *name;
-  
-  g_return_if_fail (G_IS_OBJECT (object));
-  
+
   g_object_ref (object);
   nqueue = g_object_notify_queue_freeze (object, FALSE);
-  
+
   name = first_property_name;
   while (name)
     {
-      GValue value = G_VALUE_INIT;
       GParamSpec *pspec;
-      gchar *error = NULL;
-      
+
       pspec = g_param_spec_pool_lookup (pspec_pool,
                                        name,
                                        G_OBJECT_TYPE (object),
@@ -2132,19 +2119,34 @@ g_object_set_valist (GObject     *object,
           break;
         }
 
-      G_VALUE_COLLECT_INIT (&value, pspec->value_type, var_args,
-                           0, &error);
-      if (error)
-       {
-         g_warning ("%s: %s", G_STRFUNC, error);
-         g_free (error);
+      if (G_IS_PROPERTY (pspec))
+        {
+          gboolean res;
+
+          res = g_property_set_va ((GProperty *) pspec, object,
+                                   G_PROPERTY_COLLECT_COPY | G_PROPERTY_COLLECT_REF,
+                                   var_args);
+          if (!res)
+            break;
+        }
+      else
+        {
+          GValue value = G_VALUE_INIT;
+          gchar *error = NULL;
+
+          G_VALUE_COLLECT_INIT (&value, pspec->value_type, *var_args, 0, &error);
+          if (error)
+            {
+              g_warning ("%s: %s", G_STRFUNC, error);
+              g_free (error);
+              g_value_unset (&value);
+              break;
+            }
+
+          object_set_property (object, pspec, &value, nqueue);
           g_value_unset (&value);
-         break;
-       }
-      
-      object_set_property (object, pspec, &value, nqueue);
-      g_value_unset (&value);
-      
+        }
+
       name = va_arg (var_args, gchar*);
     }
 
@@ -2153,39 +2155,41 @@ g_object_set_valist (GObject     *object,
 }
 
 /**
- * g_object_get_valist: (skip)
+ * g_object_set_valist: (skip)
  * @object: a #GObject
- * @first_property_name: name of the first property to get
- * @var_args: return location for the first property, followed optionally by more
- *  name/return location pairs, followed by %NULL
- *
- * Gets properties of an object.
- *
- * In general, a copy is made of the property contents and the caller
- * is responsible for freeing the memory in the appropriate manner for
- * the type, for instance by calling g_free() or g_object_unref().
+ * @first_property_name: name of the first property to set
+ * @var_args: value for the first property, followed optionally by more
+ *  name/value pairs, followed by %NULL
  *
- * See g_object_get().
+ * Sets properties on an object.
  */
 void
-g_object_get_valist (GObject    *object,
+g_object_set_valist (GObject    *object,
                     const gchar *first_property_name,
                     va_list      var_args)
 {
-  const gchar *name;
-  
+  va_list va_copy;
+
   g_return_if_fail (G_IS_OBJECT (object));
-  
+
+  G_VA_COPY (va_copy, var_args);
+  object_set_valist_internal (object, first_property_name, &va_copy);
+  va_end (va_copy);
+}
+
+static inline void
+object_get_valist_internal (GObject    *object,
+                            const char *first_property_name,
+                            va_list    *var_args)
+{
+  const char *name = first_property_name;
+
   g_object_ref (object);
-  
-  name = first_property_name;
-  
-  while (name)
+
+  while (name != NULL)
     {
-      GValue value = G_VALUE_INIT;
       GParamSpec *pspec;
-      gchar *error;
-      
+
       pspec = g_param_spec_pool_lookup (pspec_pool,
                                        name,
                                        G_OBJECT_TYPE (object),
@@ -2206,29 +2210,74 @@ g_object_get_valist (GObject     *object,
                     G_OBJECT_TYPE_NAME (object));
          break;
        }
+
+      if (G_IS_PROPERTY (pspec))
+        {
+          gboolean res;
+
+          res = g_property_get_va ((GProperty *) pspec, object,
+                                   G_PROPERTY_COLLECT_COPY | G_PROPERTY_COLLECT_REF,
+                                   var_args);
+          if (!res)
+            break;
+        }
+      else
+        {
+          GValue value = G_VALUE_INIT;
+          gchar *error;
       
-      g_value_init (&value, pspec->value_type);
+          g_value_init (&value, pspec->value_type);
       
-      object_get_property (object, pspec, &value);
+          object_get_property (object, pspec, &value);
       
-      G_VALUE_LCOPY (&value, var_args, 0, &error);
-      if (error)
-       {
-         g_warning ("%s: %s", G_STRFUNC, error);
-         g_free (error);
-         g_value_unset (&value);
-         break;
-       }
+          G_VALUE_LCOPY (&value, *var_args, 0, &error);
+          if (error)
+            {
+              g_warning ("%s: %s", G_STRFUNC, error);
+              g_free (error);
+              g_value_unset (&value);
+              break;
+            }
       
-      g_value_unset (&value);
+          g_value_unset (&value);
+        }
       
-      name = va_arg (var_args, gchar*);
+      name = va_arg (*var_args, gchar*);
     }
   
   g_object_unref (object);
 }
 
 /**
+ * g_object_get_valist: (skip)
+ * @object: a #GObject
+ * @first_property_name: name of the first property to get
+ * @var_args: return location for the first property, followed optionally by more
+ *  name/return location pairs, followed by %NULL
+ *
+ * Gets properties of an object.
+ *
+ * In general, a copy is made of the property contents and the caller
+ * is responsible for freeing the memory in the appropriate manner for
+ * the type, for instance by calling g_free() or g_object_unref().
+ *
+ * See g_object_get().
+ */
+void
+g_object_get_valist (GObject    *object,
+                    const gchar *first_property_name,
+                    va_list      var_args)
+{
+  va_list va_copy;
+
+  g_return_if_fail (G_IS_OBJECT (object));
+
+  G_VA_COPY (va_copy, var_args);
+  object_get_valist_internal (object, first_property_name, &va_copy);
+  va_end (va_copy);
+}
+
+/**
  * g_object_set: (skip)
  * @object: a #GObject
  * @first_property_name: name of the first property to set
@@ -2248,7 +2297,7 @@ g_object_set (gpointer     _object,
   g_return_if_fail (G_IS_OBJECT (object));
   
   va_start (var_args, first_property_name);
-  g_object_set_valist (object, first_property_name, var_args);
+  object_set_valist_internal (object, first_property_name, &var_args);
   va_end (var_args);
 }
 
@@ -2299,7 +2348,7 @@ g_object_get (gpointer     _object,
   g_return_if_fail (G_IS_OBJECT (object));
   
   va_start (var_args, first_property_name);
-  g_object_get_valist (object, first_property_name, var_args);
+  object_get_valist_internal (object, first_property_name, &var_args);
   va_end (var_args);
 }
 


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