actor: Use flags to control add/remove child

The internal versions of add_child() and remove_child() currently use
boolean arguments to control things like the ChildMeta instances and
the emissions of signals; using more than one boolean argument is an
indication that you need flags to avoid readability issues, as well as
providing a way to add new behaviours without a combinatorial explosion
of arguments, later on.
This commit is contained in:
Emmanuele Bassi 2011-12-27 11:28:36 +00:00
parent 72fa75c034
commit fa1792c394

View File

@ -9487,16 +9487,19 @@ typedef void (* ClutterActorAddChildFunc) (ClutterActor *parent,
ClutterActor *child, ClutterActor *child,
gpointer data); gpointer data);
typedef enum {
ADD_CHILD_CREATE_META = 1 << 0,
ADD_CHILD_EMIT_PARENT_SET = 1 << 1,
ADD_CHILD_EMIT_ACTOR_ADDED = 1 << 2
} ClutterActorAddChildFlags;
/*< private > /*< private >
* clutter_actor_add_child_internal: * clutter_actor_add_child_internal:
* @self: a #ClutterActor * @self: a #ClutterActor
* @child: a #ClutterActor * @child: a #ClutterActor
* @flags: control flags for actions
* @add_func: delegate function * @add_func: delegate function
* @data: (closure): data to pass to @add_func * @data: (closure): data to pass to @add_func
* @create_meta: whether this function should create a #ClutterChildMeta
* instance through the #ClutterContainer interface
* @emit_signal: whether this function should emit the
* #ClutterContainer::actor-added signal
* *
* Adds @child to the list of children of @self. * Adds @child to the list of children of @self.
* *
@ -9504,19 +9507,17 @@ typedef void (* ClutterActorAddChildFunc) (ClutterActor *parent,
* function will just set up the state, perform basic checks, and emit * function will just set up the state, perform basic checks, and emit
* signals. * signals.
* *
* For backward compatibility with #ClutterContainer and the old * The @flags argument is used to perform additional operations.
* #ClutterActor API, this function can optionally emit the Container
* signals and create #ClutterChildMeta instances.
*/ */
static void static inline void
clutter_actor_add_child_internal (ClutterActor *self, clutter_actor_add_child_internal (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
ClutterActorAddChildFlags flags,
ClutterActorAddChildFunc add_func, ClutterActorAddChildFunc add_func,
gpointer data, gpointer data)
gboolean create_meta,
gboolean emit_signal)
{ {
ClutterTextDirection text_dir; ClutterTextDirection text_dir;
gboolean create_meta, emit_parent_set, emit_actor_added;
if (child->priv->parent != NULL) if (child->priv->parent != NULL)
{ {
@ -9537,6 +9538,10 @@ clutter_actor_add_child_internal (ClutterActor *self,
return; return;
} }
create_meta = (flags & ADD_CHILD_CREATE_META) != 0;
emit_parent_set = (flags & ADD_CHILD_EMIT_PARENT_SET) != 0;
emit_actor_added = (flags & ADD_CHILD_EMIT_ACTOR_ADDED) != 0;
if (create_meta) if (create_meta)
clutter_container_create_child_meta (CLUTTER_CONTAINER (self), child); clutter_container_create_child_meta (CLUTTER_CONTAINER (self), child);
@ -9555,7 +9560,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
CLUTTER_SET_PRIVATE_FLAGS (child, CLUTTER_INTERNAL_CHILD); CLUTTER_SET_PRIVATE_FLAGS (child, CLUTTER_INTERNAL_CHILD);
/* clutter_actor_reparent() will emit ::parent-set for us */ /* clutter_actor_reparent() will emit ::parent-set for us */
if (!CLUTTER_ACTOR_IN_REPARENT (child)) if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL); g_signal_emit (child, actor_signals[PARENT_SET], 0, NULL);
/* If parent is mapped or realized, we need to also be mapped or /* If parent is mapped or realized, we need to also be mapped or
@ -9591,7 +9596,7 @@ clutter_actor_add_child_internal (ClutterActor *self,
clutter_actor_queue_relayout (child->priv->parent); clutter_actor_queue_relayout (child->priv->parent);
} }
if (emit_signal) if (emit_actor_added)
g_signal_emit_by_name (self, "actor-added", child); g_signal_emit_by_name (self, "actor-added", child);
} }
@ -9623,10 +9628,11 @@ clutter_actor_add_child (ClutterActor *self,
g_return_if_fail (child->priv->parent == NULL); g_return_if_fail (child->priv->parent == NULL);
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META |
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_at_depth, insert_child_at_depth,
NULL, NULL);
TRUE, /* create_meta */
TRUE /* emit_signals */);
} }
/** /**
@ -9660,10 +9666,11 @@ clutter_actor_insert_child_at_index (ClutterActor *self,
g_return_if_fail (child->priv->parent == NULL); g_return_if_fail (child->priv->parent == NULL);
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META |
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_at_index, insert_child_at_index,
GINT_TO_POINTER (index_), GINT_TO_POINTER (index_));
TRUE,
TRUE);
} }
/** /**
@ -9702,10 +9709,11 @@ clutter_actor_insert_child_above (ClutterActor *self,
sibling->priv->parent == self)); sibling->priv->parent == self));
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META |
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_above, insert_child_above,
sibling, sibling);
TRUE,
TRUE);
} }
/** /**
@ -9744,10 +9752,11 @@ clutter_actor_insert_child_below (ClutterActor *self,
sibling->priv->parent == self)); sibling->priv->parent == self));
clutter_actor_add_child_internal (self, child, clutter_actor_add_child_internal (self, child,
ADD_CHILD_CREATE_META |
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_below, insert_child_below,
sibling, sibling);
TRUE,
TRUE);
} }
/** /**
@ -9782,10 +9791,9 @@ clutter_actor_set_parent (ClutterActor *self,
* emissions * emissions
*/ */
clutter_actor_add_child_internal (parent, self, clutter_actor_add_child_internal (parent, self,
ADD_CHILD_EMIT_PARENT_SET,
insert_child_at_depth, insert_child_at_depth,
NULL, NULL);
FALSE,
FALSE);
} }
/** /**
@ -9864,14 +9872,32 @@ remove_child (ClutterActor *self,
self->priv->last_child = prev_sibling; self->priv->last_child = prev_sibling;
} }
typedef enum {
REMOVE_CHILD_DESTROY_META = 1 << 0,
REMOVE_CHILD_EMIT_PARENT_SET = 1 << 1,
REMOVE_CHILD_EMIT_ACTOR_REMOVED = 1 << 2
} ClutterActorRemoveChildFlags;
/*< private >
* clutter_actor_remove_child_internal:
* @self: a #ClutterActor
* @child: the child of @self that has to be removed
* @flags: control the removal operations
*
* Removes @child from the list of children of @self.
*/
static void static void
clutter_actor_remove_child_internal (ClutterActor *self, clutter_actor_remove_child_internal (ClutterActor *self,
ClutterActor *child, ClutterActor *child,
gboolean destroy_meta, ClutterActorRemoveChildFlags flags)
gboolean emit_signal)
{ {
gboolean destroy_meta, emit_parent_set, emit_actor_removed;
gboolean was_mapped; gboolean was_mapped;
destroy_meta = (flags & REMOVE_CHILD_DESTROY_META) != 0;
emit_parent_set = (flags & REMOVE_CHILD_EMIT_PARENT_SET) != 0;
emit_actor_removed = (flags & REMOVE_CHILD_EMIT_ACTOR_REMOVED) != 0;
if (destroy_meta) if (destroy_meta)
clutter_container_destroy_child_meta (CLUTTER_CONTAINER (self), child); clutter_container_destroy_child_meta (CLUTTER_CONTAINER (self), child);
@ -9907,7 +9933,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
child->priv->parent = NULL; child->priv->parent = NULL;
/* clutter_actor_reparent() will emit ::parent-set for us */ /* clutter_actor_reparent() will emit ::parent-set for us */
if (!CLUTTER_ACTOR_IN_REPARENT (child)) if (emit_parent_set && !CLUTTER_ACTOR_IN_REPARENT (child))
g_signal_emit (child, actor_signals[PARENT_SET], 0, self); g_signal_emit (child, actor_signals[PARENT_SET], 0, self);
remove_child (self, child); remove_child (self, child);
@ -9921,7 +9947,7 @@ clutter_actor_remove_child_internal (ClutterActor *self,
clutter_actor_queue_relayout (self); clutter_actor_queue_relayout (self);
/* we need to emit the signal before dropping the reference */ /* we need to emit the signal before dropping the reference */
if (emit_signal) if (emit_actor_removed)
g_signal_emit_by_name (self, "actor-removed", child); g_signal_emit_by_name (self, "actor-removed", child);
/* remove the reference we acquired in clutter_actor_add_child() */ /* remove the reference we acquired in clutter_actor_add_child() */
@ -9955,7 +9981,10 @@ clutter_actor_remove_child (ClutterActor *self,
g_return_if_fail (child->priv->parent != NULL); g_return_if_fail (child->priv->parent != NULL);
g_return_if_fail (child->priv->parent == self); g_return_if_fail (child->priv->parent == self);
clutter_actor_remove_child_internal (self, child, TRUE, TRUE); clutter_actor_remove_child_internal (self, child,
REMOVE_CHILD_DESTROY_META |
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED);
} }
/** /**
@ -9984,7 +10013,10 @@ clutter_actor_remove_all_children (ClutterActor *self)
{ {
ClutterActor *next = iter->priv->next_sibling; ClutterActor *next = iter->priv->next_sibling;
clutter_actor_remove_child_internal (self, iter, TRUE, TRUE); clutter_actor_remove_child_internal (self, iter,
REMOVE_CHILD_DESTROY_META |
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED);
iter = next; iter = next;
} }
@ -10053,14 +10085,19 @@ clutter_actor_replace_child (ClutterActor *self,
prev_sibling = old_child->priv->prev_sibling; prev_sibling = old_child->priv->prev_sibling;
next_sibling = old_child->priv->next_sibling; next_sibling = old_child->priv->next_sibling;
clutter_actor_remove_child_internal (self, old_child, TRUE, TRUE); clutter_actor_remove_child_internal (self, old_child,
REMOVE_CHILD_DESTROY_META |
REMOVE_CHILD_EMIT_PARENT_SET |
REMOVE_CHILD_EMIT_ACTOR_REMOVED);
clos.prev_sibling = prev_sibling; clos.prev_sibling = prev_sibling;
clos.next_sibling = next_sibling; clos.next_sibling = next_sibling;
clutter_actor_add_child_internal (self, new_child, clutter_actor_add_child_internal (self, new_child,
ADD_CHILD_CREATE_META |
ADD_CHILD_EMIT_PARENT_SET |
ADD_CHILD_EMIT_ACTOR_ADDED,
insert_child_between, insert_child_between,
&clos, &clos);
TRUE, TRUE);
} }
/** /**
@ -10090,8 +10127,7 @@ clutter_actor_unparent (ClutterActor *self)
return; return;
clutter_actor_remove_child_internal (self->priv->parent, self, clutter_actor_remove_child_internal (self->priv->parent, self,
FALSE, REMOVE_CHILD_EMIT_PARENT_SET);
FALSE);
} }
/** /**