[glib/wip/gobjectnew: 1/4] GParamSpec: add g_param_spec_get_default_value()



commit e83b08d6573ccec790e2e5f80e8f2357d6cb3521
Author: Ryan Lortie <desrt desrt ca>
Date:   Wed Mar 27 18:33:45 2013 -0400

    GParamSpec: add g_param_spec_get_default_value()
    
    The way of getting the default value out of a GParamSpec is to allocate
    a GValue, initialise it, then call g_param_spec_set_default() to set the
    default value into that GValue.
    
    This is exactly how we handle setting the default value for all of the
    construct properties that were not explicitly passed to g_object_new().
    
    Instead of doing the alloc/init/store on all construct properties on
    every call to g_object_new(), we can cache those GValue structs as qdata
    on the GParamSpec itself and reuse them.
    
    This patch does not actually make that change to g_object_new() yet, but
    it adds the API to GParamSpec so that a future patch to GObject can make
    the change.

 gobject/gparam.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gobject/gparam.h |  3 ++-
 2 files changed, 59 insertions(+), 1 deletion(-)
---
diff --git a/gobject/gparam.c b/gobject/gparam.c
index b5c3024..b2958ac 100644
--- a/gobject/gparam.c
+++ b/gobject/gparam.c
@@ -1506,3 +1506,60 @@ g_value_dup_param (const GValue *value)
 
   return value->data[0].v_pointer ? g_param_spec_ref (value->data[0].v_pointer) : NULL;
 }
+
+static void
+g_param_spec_free_default (gpointer data)
+{
+  GValue *value = data;
+
+  g_value_unset (value);
+  g_slice_free (GValue, value);
+}
+
+/**
+ * g_param_get_default_value:
+ * @param: a #GParamSpec
+ *
+ * Gets the default value of @param as a pointer to a #GValue.
+ *
+ * The #GValue will remain value for the life of @param.
+ *
+ * Returns: a pointer to a #GValue which must not be modified
+ *
+ * Since: 2.38
+ **/
+const GValue *
+g_param_spec_get_default_value (GParamSpec *pspec)
+{
+  static gsize default_value_quark;
+  const GValue *result;
+
+  if (g_once_init_enter (&default_value_quark))
+    g_once_init_leave (&default_value_quark, g_quark_from_static_string ("GParamSpec default value qdata"));
+
+  result = g_param_spec_get_qdata (pspec, default_value_quark);
+
+  if (!result)
+    {
+      GValue *value;
+
+      value = g_slice_new0 (GValue);
+      g_value_init (value, pspec->value_type);
+      g_param_value_set_default (pspec, value);
+      if (!g_datalist_id_replace_data (&pspec->qdata, default_value_quark,
+                                       NULL, value, g_param_spec_free_default, NULL))
+        {
+          /* Atomic replace of NULL with the value didn't work which
+           * means that someone beat us to it.  Free our value and use
+           * theirs.
+           */
+          g_param_spec_free_default (value);
+          result = g_param_spec_get_qdata (pspec, default_value_quark);
+          g_assert (result != NULL);
+        }
+      else
+        result = value;
+    }
+
+  return result;
+}
diff --git a/gobject/gparam.h b/gobject/gparam.h
index ebdc91e..b35ad51 100644
--- a/gobject/gparam.h
+++ b/gobject/gparam.h
@@ -336,6 +336,8 @@ void           g_value_take_param               (GValue        *value,
 GLIB_DEPRECATED_FOR(g_value_take_param)
 void           g_value_set_param_take_ownership (GValue        *value,
                                                  GParamSpec    *param);
+GLIB_AVAILABLE_IN_2_36
+const GValue *  g_param_spec_get_default_value  (GParamSpec     *param);
 
 /* --- convenience functions --- */
 typedef struct _GParamSpecTypeInfo GParamSpecTypeInfo;
@@ -421,7 +423,6 @@ GParamSpec**        g_param_spec_pool_list          (GParamSpecPool *pool,
                                                 guint          *n_pspecs_p);
 
 
-
 /* contracts:
  *
  * gboolean value_validate (GParamSpec *pspec,


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