actor: Identify allocation cycles
authorEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 23 Oct 2009 09:17:40 +0000 (10:17 +0100)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Fri, 23 Oct 2009 12:38:40 +0000 (13:38 +0100)
If an actor calls directly or indirectly clutter_actor_queue_relayout()
on itself from within the allocate() implementation it will cause a
relayout cycle. This is usually a condition that should be checked by
ClutterActor and we should emit a warning if it is verified.

clutter/clutter-actor.c

index 7d18da9..dcc14c5 100644 (file)
@@ -4470,6 +4470,17 @@ clutter_actor_queue_relayout (ClutterActor *self)
       priv->needs_allocation)
     return; /* save some cpu cycles */
 
+  if (!(CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IS_TOPLEVEL) &&
+      (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_IN_RELAYOUT))
+    {
+      g_warning ("The actor '%s' is currently inside an allocation "
+                 "cycle; calling clutter_actor_queue_relayout() is "
+                 "not allowed",
+                 priv->name ? priv->name
+                            : G_OBJECT_TYPE_NAME (self));
+      return;
+    }
+
   g_signal_emit (self, actor_signals[QUEUE_RELAYOUT], 0);
 }
 
@@ -4847,8 +4858,12 @@ clutter_actor_allocate (ClutterActor           *self,
   if (child_moved)
     flags |= CLUTTER_ABSOLUTE_ORIGIN_CHANGED;
 
+  CLUTTER_SET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_RELAYOUT);
+
   klass = CLUTTER_ACTOR_GET_CLASS (self);
   klass->allocate (self, box, flags);
+
+  CLUTTER_UNSET_PRIVATE_FLAGS (self, CLUTTER_ACTOR_IN_RELAYOUT);
 }
 
 /**