animation: Transform if necessary

The Animation code does transformation of values between type A and A'
after checking for compatibility using g_value_type_compatible(). This
is incorrect: compatibility means that the two types can be copied. The
correct conversion should follow:

        if (compatible (type (A), type (A')))
          copy (A, A');
        else
          if (transformable (type (A), type (A')))
            transform (A, A');
          else
            error("Unable to trasform type A in A'");

The transformation might still fail, so we need to check for errors
there as well as a fall-through case.
This commit is contained in:
Emmanuele Bassi 2010-01-22 21:36:41 +00:00
parent 94249efff7
commit 7fa7c4a1b6

View File

@ -1645,35 +1645,37 @@ clutter_animation_setup_property (ClutterAnimation *animation,
*/ */
if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (&real_value))) if (!g_type_is_a (G_VALUE_TYPE (value), G_VALUE_TYPE (&real_value)))
{ {
if (!g_value_type_compatible (G_VALUE_TYPE (value), /* are these two types compatible (can be directly copied)? */
G_VALUE_TYPE (&real_value)) && if (g_value_type_compatible (G_VALUE_TYPE (value),
!g_value_type_compatible (G_VALUE_TYPE (&real_value), G_VALUE_TYPE (&real_value)))
G_VALUE_TYPE (value)))
{ {
g_warning ("%s: Unable to convert from %s to %s for " g_value_copy (value, &real_value);
"the property '%s' of object %s", goto done;
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (&real_value)),
property_name,
G_OBJECT_TYPE_NAME (priv->object));
g_value_unset (&real_value);
return;
} }
if (!g_value_transform (value, &real_value)) /* are these two type transformable? */
if (g_value_type_transformable (G_VALUE_TYPE (value),
G_VALUE_TYPE (&real_value)))
{ {
g_warning ("%s: Unable to transform from %s to %s", if (g_value_transform (value, &real_value))
G_STRLOC, goto done;
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (&real_value)));
g_value_unset (&real_value);
return;
} }
/* if not compatible and not transformable then we can't do much */
g_warning ("%s: Unable to convert from %s to %s for "
"the property '%s' of object %s",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (&real_value)),
property_name,
G_OBJECT_TYPE_NAME (priv->object));
g_value_unset (&real_value);
return;
} }
else else
g_value_copy (value, &real_value); g_value_copy (value, &real_value);
done:
/* create an interval and bind it to the property, in case /* create an interval and bind it to the property, in case
* it's not a fixed property, otherwise just set it * it's not a fixed property, otherwise just set it
*/ */