[clutter] interval: Transform values on set, if needed



commit a0c620b1576a9d72a4f5dc517169778fadec7fa9
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Jun 18 11:07:39 2012 +0100

    interval: Transform values on set, if needed
    
    It's possible that GValues passed to a ClutterInterval setter are not
    of the same type as the interval - for instance, if they come from
    language bindings, or from untrusted sources; we can use the same
    transformation functions we already use inside ClutterTransition to
    ensure that the ClutterInterval always stores values of the same type
    used to create the interval itself.

 clutter/clutter-interval.c |   35 ++++++++++++++++++++++++++++++++++-
 1 files changed, 34 insertions(+), 1 deletions(-)
---
diff --git a/clutter/clutter-interval.c b/clutter/clutter-interval.c
index 00db42f..16dd4be 100644
--- a/clutter/clutter-interval.c
+++ b/clutter/clutter-interval.c
@@ -463,6 +463,7 @@ clutter_interval_set_value_internal (ClutterInterval *interval,
                                      const GValue    *value)
 {
   ClutterIntervalPrivate *priv = interval->priv;
+  GType value_type;
 
   g_assert (index_ >= INITIAL && index_ <= RESULT);
 
@@ -470,7 +471,39 @@ clutter_interval_set_value_internal (ClutterInterval *interval,
     g_value_unset (&priv->values[index_]);
 
   g_value_init (&priv->values[index_], priv->value_type);
-  g_value_copy (value, &priv->values[index_]);
+
+  value_type = G_VALUE_TYPE (value);
+  if (value_type != priv->value_type ||
+      !g_type_is_a (value_type, priv->value_type))
+    {
+      if (g_value_type_compatible (value_type, priv->value_type))
+        {
+          g_value_copy (value, &priv->values[index_]);
+          return;
+        }
+
+      if (g_value_type_transformable (value_type, priv->value_type))
+        {
+          GValue transform = G_VALUE_INIT;
+
+          g_value_init (&transform, priv->value_type);
+
+          if (g_value_transform (value, &transform))
+            g_value_copy (&transform, &priv->values[index_]);
+          else
+            {
+              g_warning ("%s: Unable to convert a value of type '%s' into "
+                         "the value type '%s' of the interval.",
+                         G_STRLOC,
+                         g_type_name (value_type),
+                         g_type_name (priv->value_type));
+            }
+
+          g_value_unset (&transform);
+        }
+    }
+  else
+    g_value_copy (value, &priv->values[index_]);
 }
 
 static inline void



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