2008-06-13 Emmanuele Bassi <ebassi@openedhand.com>

* clutter/clutter-actor.c:
	(clutter_actor_dispose), (clutter_actor_destroy),
	(clutter_actor_unparent): Clean up the actor's destruction
	sequence, making sure that every operation is performed
	under the CLUTTER_ACTOR_IN_DESTRUCTION internal flag.
This commit is contained in:
Emmanuele Bassi 2008-06-13 13:59:07 +00:00
parent 778d421c11
commit 23c160886b
2 changed files with 32 additions and 21 deletions

View File

@ -1,3 +1,11 @@
2008-06-13 Emmanuele Bassi <ebassi@openedhand.com>
* clutter/clutter-actor.c:
(clutter_actor_dispose), (clutter_actor_destroy),
(clutter_actor_unparent): Clean up the actor's destruction
sequence, making sure that every operation is performed
under the CLUTTER_ACTOR_IN_DESTRUCTION internal flag.
2008-06-13 Emmanuele Bassi <ebassi@openedhand.com> 2008-06-13 Emmanuele Bassi <ebassi@openedhand.com>
Bug #960 - PangoContext creation code should not be duplicated Bug #960 - PangoContext creation code should not be duplicated

View File

@ -1852,23 +1852,28 @@ static void
clutter_actor_dispose (GObject *object) clutter_actor_dispose (GObject *object)
{ {
ClutterActor *self = CLUTTER_ACTOR (object); ClutterActor *self = CLUTTER_ACTOR (object);
ClutterActorPrivate *priv = self->priv;
CLUTTER_NOTE (MISC, "Disposing of object (id=%d) of type `%s' (ref_count:%d)", CLUTTER_NOTE (MISC, "Disposing of object (id=%d) of type `%s' (ref_count:%d)",
self->priv->id, self->priv->id,
g_type_name (G_OBJECT_TYPE (self)), g_type_name (G_OBJECT_TYPE (self)),
object->ref_count); object->ref_count);
/* avoid recursing when called from clutter_actor_destroy() */
if (priv->parent_actor)
{
ClutterActor *parent = priv->parent_actor;
if (CLUTTER_IS_CONTAINER (parent))
clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self);
else
priv->parent_actor = NULL;
}
destroy_shader_data (self); destroy_shader_data (self);
if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION))
{
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_DESTRUCTION);
g_signal_emit (self, actor_signals[DESTROY], 0); g_signal_emit (self, actor_signals[DESTROY], 0);
CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_DESTRUCTION);
}
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object); G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
} }
@ -2953,19 +2958,16 @@ clutter_actor_destroy (ClutterActor *self)
g_object_ref (self); g_object_ref (self);
if (priv->parent_actor) /* avoid recursion while destroying */
{
ClutterActor *parent = priv->parent_actor;
if (CLUTTER_IS_CONTAINER (parent))
clutter_container_remove_actor (CLUTTER_CONTAINER (parent), self);
else
priv->parent_actor = NULL;
}
if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION)) if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION))
{
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_DESTRUCTION);
g_object_run_dispose (G_OBJECT (self)); g_object_run_dispose (G_OBJECT (self));
CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_DESTRUCTION);
}
g_object_unref (self); g_object_unref (self);
} }
@ -5635,6 +5637,9 @@ clutter_actor_unparent (ClutterActor *self)
if (self->priv->parent_actor == NULL) if (self->priv->parent_actor == NULL)
return; return;
old_parent = self->priv->parent_actor;
self->priv->parent_actor = NULL;
/* just hide the actor if we are reparenting it */ /* just hide the actor if we are reparenting it */
if (CLUTTER_ACTOR_IS_REALIZED (self)) if (CLUTTER_ACTOR_IS_REALIZED (self))
{ {
@ -5644,8 +5649,6 @@ clutter_actor_unparent (ClutterActor *self)
clutter_actor_unrealize (self); clutter_actor_unrealize (self);
} }
old_parent = self->priv->parent_actor;
self->priv->parent_actor = NULL;
g_signal_emit (self, actor_signals[PARENT_SET], 0, old_parent); g_signal_emit (self, actor_signals[PARENT_SET], 0, old_parent);
/* remove the reference we acquired in clutter_actor_set_parent() */ /* remove the reference we acquired in clutter_actor_set_parent() */