actor: Adds private _clutter_actor_traverse API

This adds two internal functions relating to explicit traversal of the
scenegraph:
_clutter_actor_foreach_child
_clutter_actor_traverse

_clutter_actor_foreach_child just iterates the immediate children of an
actor, and with a new ClutterForeachCallback type it allows the
callbacks to break iteration early.

_clutter_actor_traverse traverses the given actor and all of its
decendants. Again traversal can be stopped early if a callback returns
FALSE.

The first intended use for _clutter_actor_traverse is to maintain a
cache pointer to the stage for all actors. In this case we will need to
update the pointer for all descendants of an actor when an actor is
reparented in any way.
This commit is contained in:
Robert Bragg 2010-09-13 00:33:23 +01:00
parent 9a1abbc713
commit 51fca9d968
2 changed files with 96 additions and 0 deletions

View File

@ -12122,4 +12122,68 @@ _clutter_actor_get_n_children (ClutterActor *self)
return self->priv->n_children; return self->priv->n_children;
} }
/* _clutter_actor_foreach_child:
* @actor: The actor whos children you want to iterate
* @callback: The function to call for each child
* @user_data: Private data to pass to @callback
*
* Calls a given @callback once for each child of the specified @actor and
* passing the @user_data pointer each time.
*
* Return value: returns %TRUE if all children were iterated, else
* %FALSE if a callback broke out of iteration early.
*/
gboolean
_clutter_actor_foreach_child (ClutterActor *self,
ClutterForeachCallback callback,
void *user_data)
{
ClutterActorPrivate *priv = self->priv;
gboolean cont;
GList *l;
for (cont = TRUE, l = priv->children; cont && l; l = l->next)
cont = callback (l->data, user_data);
return cont;
}
/* _clutter_actor_traverse:
* @actor: The actor to start traversing the graph from
* @flags: These flags may affect how the traversal is done
* @callback: The function to call for each actor traversed
* @user_data: The private data to pass to the @callback
*
* Traverses the scenegraph starting at the specified @actor and
* descending through all its children and its children's children.
* For each actor traversed @callback is called with the specified
* @user_data.
*
* If @callback ever returns %FALSE then no more actors will be
* traversed.
*
* Return value: %TRUE if @actor and all its descendants were
* traversed or %FALSE if the @callback returned %FALSE to stop
* traversal early.
*/
gboolean
_clutter_actor_traverse (ClutterActor *actor,
ClutterActorTraverseFlags flags,
ClutterForeachCallback callback,
gpointer user_data)
{
ClutterActorPrivate *priv;
GList *l;
gboolean cont;
if (!callback (actor, user_data))
return FALSE;
priv = actor->priv;
for (cont = TRUE, l = priv->children; cont && l; l = l->next)
cont = _clutter_actor_traverse (l->data, flags, callback, user_data);
return cont;
}

View File

@ -275,6 +275,31 @@ struct _ClutterPaintVolume
*/ */
}; };
/* ClutterActorTraverseFlags:
*
* Controls some options for how clutter_actor_traverse() iterates
* through the graph.
*/
typedef enum _ClutterActorTraverseFlags
{
CLUTTER_ACTOR_TRAVERSE_PLACE_HOLDER = 1L<<0
} ClutterActorTraverseFlags;
/* ClutterForeachCallback:
* @actor: The actor being iterated
* @user_data: The private data specified when starting the iteration
*
* A generic callback for iterating over actor, such as with
* _clutter_actor_foreach_child. The difference when compared to
* #ClutterCallback is that it returns a boolean so it is possible to break
* out of an iteration early.
*
* Return value: %TRUE to continue iterating or %FALSE to break iteration
* early.
*/
typedef gboolean (*ClutterForeachCallback) (ClutterActor *actor,
void *user_data);
typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry; typedef struct _ClutterStageQueueRedrawEntry ClutterStageQueueRedrawEntry;
#define CLUTTER_CONTEXT() (_clutter_context_get_default ()) #define CLUTTER_CONTEXT() (_clutter_context_get_default ())
@ -453,6 +478,13 @@ gboolean _clutter_boolean_handled_accumulator (GSignalInvocationHint *ihint,
gpointer dummy); gpointer dummy);
gint _clutter_actor_get_n_children (ClutterActor *self); gint _clutter_actor_get_n_children (ClutterActor *self);
gboolean _clutter_actor_foreach_child (ClutterActor *self,
ClutterForeachCallback callback,
void *user_data);
gboolean _clutter_actor_traverse (ClutterActor *actor,
ClutterActorTraverseFlags flags,
ClutterForeachCallback callback,
void *user_data);
ClutterActor *_clutter_actor_get_stage_internal (ClutterActor *actor); ClutterActor *_clutter_actor_get_stage_internal (ClutterActor *actor);
void _clutter_actor_apply_modelview_transform (ClutterActor *self, void _clutter_actor_apply_modelview_transform (ClutterActor *self,