actor: Ensure that we remove only implicit transitions
The transitions we create implicitly should be removed from the set of transitions associated to an actor; the transitions explicitly associated to an actor, though, have to survive the emission of their 'stopped' signal.
This commit is contained in:
parent
ee00e37bc4
commit
3f732cdc2b
@ -977,6 +977,7 @@ typedef struct _TransitionClosure
|
|||||||
ClutterTransition *transition;
|
ClutterTransition *transition;
|
||||||
gchar *name;
|
gchar *name;
|
||||||
gulong completed_id;
|
gulong completed_id;
|
||||||
|
guint is_implicit : 1;
|
||||||
} TransitionClosure;
|
} TransitionClosure;
|
||||||
|
|
||||||
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
static void clutter_container_iface_init (ClutterContainerIface *iface);
|
||||||
@ -18252,6 +18253,8 @@ on_transition_stopped (ClutterTransition *transition,
|
|||||||
t_quark = g_quark_from_string (clos->name);
|
t_quark = g_quark_from_string (clos->name);
|
||||||
t_name = g_strdup (clos->name);
|
t_name = g_strdup (clos->name);
|
||||||
|
|
||||||
|
if (clos->is_implicit)
|
||||||
|
{
|
||||||
/* we take a reference here because removing the closure
|
/* we take a reference here because removing the closure
|
||||||
* will release the reference on the transition, and we
|
* will release the reference on the transition, and we
|
||||||
* want the transition to survive the signal emission;
|
* want the transition to survive the signal emission;
|
||||||
@ -18260,6 +18263,7 @@ on_transition_stopped (ClutterTransition *transition,
|
|||||||
*/
|
*/
|
||||||
g_object_ref (transition);
|
g_object_ref (transition);
|
||||||
g_hash_table_remove (info->transitions, clos->name);
|
g_hash_table_remove (info->transitions, clos->name);
|
||||||
|
}
|
||||||
|
|
||||||
/* we emit the ::transition-stopped after removing the
|
/* we emit the ::transition-stopped after removing the
|
||||||
* transition, so that we can chain up new transitions
|
* transition, so that we can chain up new transitions
|
||||||
@ -18284,6 +18288,55 @@ on_transition_stopped (ClutterTransition *transition,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_actor_add_transition_internal (ClutterActor *self,
|
||||||
|
const gchar *name,
|
||||||
|
ClutterTransition *transition,
|
||||||
|
gboolean is_implicit)
|
||||||
|
{
|
||||||
|
ClutterTimeline *timeline;
|
||||||
|
TransitionClosure *clos;
|
||||||
|
ClutterAnimationInfo *info;
|
||||||
|
|
||||||
|
info = _clutter_actor_get_animation_info (self);
|
||||||
|
|
||||||
|
if (info->transitions == NULL)
|
||||||
|
info->transitions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
NULL,
|
||||||
|
transition_closure_free);
|
||||||
|
|
||||||
|
if (g_hash_table_lookup (info->transitions, name) != NULL)
|
||||||
|
{
|
||||||
|
g_warning ("A transition with name '%s' already exists for "
|
||||||
|
"the actor '%s'",
|
||||||
|
name,
|
||||||
|
_clutter_actor_get_debug_name (self));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_transition_set_animatable (transition, CLUTTER_ANIMATABLE (self));
|
||||||
|
|
||||||
|
timeline = CLUTTER_TIMELINE (transition);
|
||||||
|
|
||||||
|
clos = g_slice_new (TransitionClosure);
|
||||||
|
clos->actor = self;
|
||||||
|
clos->transition = g_object_ref (transition);
|
||||||
|
clos->name = g_strdup (name);
|
||||||
|
clos->is_implicit = is_implicit;
|
||||||
|
clos->completed_id = g_signal_connect (timeline, "stopped",
|
||||||
|
G_CALLBACK (on_transition_stopped),
|
||||||
|
clos);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (ANIMATION,
|
||||||
|
"Adding transition '%s' [%p] to actor '%s'",
|
||||||
|
clos->name,
|
||||||
|
clos->transition,
|
||||||
|
_clutter_actor_get_debug_name (self));
|
||||||
|
|
||||||
|
g_hash_table_insert (info->transitions, clos->name, clos);
|
||||||
|
clutter_timeline_start (timeline);
|
||||||
|
}
|
||||||
|
|
||||||
/*< private >*
|
/*< private >*
|
||||||
* _clutter_actor_create_transition:
|
* _clutter_actor_create_transition:
|
||||||
* @actor: a #ClutterActor
|
* @actor: a #ClutterActor
|
||||||
@ -18418,7 +18471,7 @@ _clutter_actor_create_transition (ClutterActor *actor,
|
|||||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||||
|
|
||||||
/* this will start the transition as well */
|
/* this will start the transition as well */
|
||||||
clutter_actor_add_transition (actor, pspec->name, res);
|
clutter_actor_add_transition_internal (actor, pspec->name, res, TRUE);
|
||||||
|
|
||||||
/* the actor now owns the transition */
|
/* the actor now owns the transition */
|
||||||
g_object_unref (res);
|
g_object_unref (res);
|
||||||
@ -18488,50 +18541,11 @@ clutter_actor_add_transition (ClutterActor *self,
|
|||||||
const char *name,
|
const char *name,
|
||||||
ClutterTransition *transition)
|
ClutterTransition *transition)
|
||||||
{
|
{
|
||||||
ClutterTimeline *timeline;
|
|
||||||
TransitionClosure *clos;
|
|
||||||
ClutterAnimationInfo *info;
|
|
||||||
|
|
||||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||||
g_return_if_fail (name != NULL);
|
g_return_if_fail (name != NULL);
|
||||||
g_return_if_fail (CLUTTER_IS_TRANSITION (transition));
|
g_return_if_fail (CLUTTER_IS_TRANSITION (transition));
|
||||||
|
|
||||||
info = _clutter_actor_get_animation_info (self);
|
clutter_actor_add_transition_internal (self, name, transition, FALSE);
|
||||||
|
|
||||||
if (info->transitions == NULL)
|
|
||||||
info->transitions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
|
||||||
NULL,
|
|
||||||
transition_closure_free);
|
|
||||||
|
|
||||||
if (g_hash_table_lookup (info->transitions, name) != NULL)
|
|
||||||
{
|
|
||||||
g_warning ("A transition with name '%s' already exists for "
|
|
||||||
"the actor '%s'",
|
|
||||||
name,
|
|
||||||
_clutter_actor_get_debug_name (self));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_transition_set_animatable (transition, CLUTTER_ANIMATABLE (self));
|
|
||||||
|
|
||||||
timeline = CLUTTER_TIMELINE (transition);
|
|
||||||
|
|
||||||
clos = g_slice_new (TransitionClosure);
|
|
||||||
clos->actor = self;
|
|
||||||
clos->transition = g_object_ref (transition);
|
|
||||||
clos->name = g_strdup (name);
|
|
||||||
clos->completed_id = g_signal_connect (timeline, "stopped",
|
|
||||||
G_CALLBACK (on_transition_stopped),
|
|
||||||
clos);
|
|
||||||
|
|
||||||
CLUTTER_NOTE (ANIMATION,
|
|
||||||
"Adding transition '%s' [%p] to actor '%s'",
|
|
||||||
clos->name,
|
|
||||||
clos->transition,
|
|
||||||
_clutter_actor_get_debug_name (self));
|
|
||||||
|
|
||||||
g_hash_table_insert (info->transitions, clos->name, clos);
|
|
||||||
clutter_timeline_start (timeline);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user