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_value_type_compatible (G_VALUE_TYPE (value),
G_VALUE_TYPE (&real_value)) &&
!g_value_type_compatible (G_VALUE_TYPE (&real_value),
G_VALUE_TYPE (value)))
/* are these two types compatible (can be directly copied)? */
if (g_value_type_compatible (G_VALUE_TYPE (value),
G_VALUE_TYPE (&real_value)))
{
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;
g_value_copy (value, &real_value);
goto done;
}
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",
G_STRLOC,
g_type_name (G_VALUE_TYPE (value)),
g_type_name (G_VALUE_TYPE (&real_value)));
g_value_unset (&real_value);
return;
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 "
"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
g_value_copy (value, &real_value);
done:
/* create an interval and bind it to the property, in case
* it's not a fixed property, otherwise just set it
*/