actor: Add checks for IN_DESTRUCTION flag

ClutterActor should check whether the current instance is being
destroyed and avoid performing operations like:

 • queueing redraws
 • queueing relayouts

It should also warn if the actor is being parented to an actor
currently being destroyed.
This commit is contained in:
Emmanuele Bassi 2009-10-23 10:08:02 +01:00
parent 7de47e74bd
commit ca15143d1f

View File

@ -1287,7 +1287,7 @@ clutter_actor_unrealize (ClutterActor *self)
clutter_actor_unrealize_not_hiding (self); clutter_actor_unrealize_not_hiding (self);
} }
/** /*
* clutter_actor_unrealize_not_hiding: * clutter_actor_unrealize_not_hiding:
* @self: A #ClutterActor * @self: A #ClutterActor
* *
@ -1334,7 +1334,7 @@ clutter_actor_unrealize_not_hiding (ClutterActor *self)
g_object_notify (G_OBJECT (self), "realized"); g_object_notify (G_OBJECT (self), "realized");
} }
/** /*
* _clutter_actor_rerealize: * _clutter_actor_rerealize:
* @self: A #ClutterActor * @self: A #ClutterActor
* @callback: Function to call while unrealized * @callback: Function to call while unrealized
@ -1619,6 +1619,10 @@ clutter_actor_real_queue_redraw (ClutterActor *self,
if (self->priv->queued_redraw) if (self->priv->queued_redraw)
return; return;
/* no point in queuing a paint on a destroyed actor */
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION)
return;
CLUTTER_NOTE (PAINT, "Redraw queued on '%s'", CLUTTER_NOTE (PAINT, "Redraw queued on '%s'",
clutter_actor_get_name (self) ? clutter_actor_get_name (self) clutter_actor_get_name (self) ? clutter_actor_get_name (self)
: G_OBJECT_TYPE_NAME (self)); : G_OBJECT_TYPE_NAME (self));
@ -1647,6 +1651,10 @@ clutter_actor_real_queue_relayout (ClutterActor *self)
{ {
ClutterActorPrivate *priv = self->priv; ClutterActorPrivate *priv = self->priv;
/* no point in queueing a redraw on a destroyed actor */
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_DESTRUCTION)
return;
priv->needs_width_request = TRUE; priv->needs_width_request = TRUE;
priv->needs_height_request = TRUE; priv->needs_height_request = TRUE;
priv->needs_allocation = TRUE; priv->needs_allocation = TRUE;
@ -2292,7 +2300,7 @@ _clutter_actor_apply_modelview_transform_recursive (ClutterActor *self,
if (stage == NULL) if (stage == NULL)
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
if (parent) if (parent != NULL)
_clutter_actor_apply_modelview_transform_recursive (parent, ancestor); _clutter_actor_apply_modelview_transform_recursive (parent, ancestor);
else if (self != stage) else if (self != stage)
_clutter_actor_apply_modelview_transform (stage); _clutter_actor_apply_modelview_transform (stage);
@ -6593,6 +6601,12 @@ clutter_actor_set_parent (ClutterActor *self,
return; return;
} }
if (CLUTTER_PRIVATE_FLAGS (parent) & CLUTTER_ACTOR_IN_DESTRUCTION)
{
g_warning ("Cannot set a parent currently being destroyed");
return;
}
g_object_ref_sink (self); g_object_ref_sink (self);
priv->parent_actor = parent; priv->parent_actor = parent;
@ -6749,7 +6763,13 @@ clutter_actor_reparent (ClutterActor *self,
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL) if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL)
{ {
g_warning ("Cannot set a parent on a toplevel actor\n"); g_warning ("Cannot set a parent on a toplevel actor");
return;
}
if (CLUTTER_PRIVATE_FLAGS (new_parent) & CLUTTER_ACTOR_IN_DESTRUCTION)
{
g_warning ("Cannot set a parent currently being destroyed");
return; return;
} }