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,11 +1645,23 @@ 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_value_copy (value, &real_value);
goto done;
}
/* are these two type transformable? */
if (g_value_type_transformable (G_VALUE_TYPE (value),
G_VALUE_TYPE (&real_value)))
{
if (g_value_transform (value, &real_value))
goto done;
}
/* if not compatible and not transformable then we can't do much */
g_warning ("%s: Unable to convert from %s to %s for " g_warning ("%s: Unable to convert from %s to %s for "
"the property '%s' of object %s", "the property '%s' of object %s",
G_STRLOC, G_STRLOC,
@@ -1660,20 +1672,10 @@ clutter_animation_setup_property (ClutterAnimation *animation,
g_value_unset (&real_value); g_value_unset (&real_value);
return; return;
} }
if (!g_value_transform (value, &real_value))
{
g_warning ("%s: Unable to transform from %s to %s",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (&real_value)));
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
*/ */