[clutter] actor: Keep track of clones
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter] actor: Keep track of clones
- Date: Wed, 13 Mar 2013 18:37:38 +0000 (UTC)
commit 028baa99a047d780b1215b07caa2523cdf496d20
Author: Emmanuele Bassi <ebassi gnome org>
Date: Thu Mar 7 18:09:33 2013 +0000
actor: Keep track of clones
Instead of using signal notifications, we should be able to keep track
of the clones of an actor from within ClutterActor itself, using private
API. There's no point in pretending that people can actually create a
Clone class out of tree, given the amount of invariants we have to punch
through in order to implement a proper replicator node of the scene
graph, so we can just skip the signal emissions and just do the right
thing at the right time.
clutter/clutter-actor-private.h | 7 +++
clutter/clutter-actor.c | 80 ++++++++++++++++++++++++++++++++++++++-
clutter/clutter-clone.c | 30 ++------------
3 files changed, 91 insertions(+), 26 deletions(-)
---
diff --git a/clutter/clutter-actor-private.h b/clutter/clutter-actor-private.h
index c5319e2..1c6f165 100644
--- a/clutter/clutter-actor-private.h
+++ b/clutter/clutter-actor-private.h
@@ -312,6 +312,13 @@ ClutterActorAlign _clutter_actor_get_effective_x_align
void _clutter_actor_handle_event (ClutterActor
*actor,
const ClutterEvent
*event);
+void _clutter_actor_attach_clone (ClutterActor *actor,
+ ClutterActor
*clone);
+void _clutter_actor_detach_clone (ClutterActor *actor,
+ ClutterActor
*clone);
+void _clutter_actor_queue_redraw_on_clones (ClutterActor
*actor);
+void _clutter_actor_queue_relayout_on_clones (ClutterActor
*actor);
+
G_END_DECLS
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index 186f8a0..b02a106 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -771,7 +771,10 @@ struct _ClutterActorPrivate
gchar *debug_name;
#endif
- /* bitfields */
+ /* a set of clones of the actor */
+ GHashTable *clones;
+
+ /* bitfields: KEEP AT THE END */
/* fixed position and sizes */
guint position_set : 1;
@@ -2548,6 +2551,8 @@ _clutter_actor_signal_queue_redraw (ClutterActor *self,
* receive the signal so it can queue its own redraw.
*/
+ _clutter_actor_queue_redraw_on_clones (self);
+
/* calls klass->queue_redraw in default handler */
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
}
@@ -5805,6 +5810,12 @@ clutter_actor_dispose (GObject *object)
g_clear_object (&priv->content);
}
+ if (priv->clones != NULL)
+ {
+ g_hash_table_unref (priv->clones);
+ priv->clones = NULL;
+ }
+
G_OBJECT_CLASS (clutter_actor_parent_class)->dispose (object);
}
@@ -8791,6 +8802,8 @@ _clutter_actor_queue_only_relayout (ClutterActor *self)
}
#endif /* CLUTTER_ENABLE_DEBUG */
+ _clutter_actor_queue_relayout_on_clones (self);
+
g_signal_emit (self, actor_signals[QUEUE_RELAYOUT], 0);
}
@@ -20128,3 +20141,68 @@ clutter_actor_get_child_transform (ClutterActor *self,
else
clutter_matrix_init_identity (transform);
}
+
+void
+_clutter_actor_attach_clone (ClutterActor *actor,
+ ClutterActor *clone)
+{
+ ClutterActorPrivate *priv = actor->priv;
+
+ g_assert (clone != NULL);
+
+ if (priv->clones == NULL)
+ priv->clones = g_hash_table_new (NULL, NULL);
+
+ g_hash_table_add (priv->clones, clone);
+}
+
+void
+_clutter_actor_detach_clone (ClutterActor *actor,
+ ClutterActor *clone)
+{
+ ClutterActorPrivate *priv = actor->priv;
+
+ g_assert (clone != NULL);
+
+ if (priv->clones == NULL ||
+ g_hash_table_lookup (priv->clones, clone) == NULL)
+ return;
+
+ g_hash_table_remove (priv->clones, clone);
+
+ if (g_hash_table_size (priv->clones) == 0)
+ {
+ g_hash_table_unref (priv->clones);
+ priv->clones = NULL;
+ }
+}
+
+void
+_clutter_actor_queue_redraw_on_clones (ClutterActor *self)
+{
+ ClutterActorPrivate *priv = self->priv;
+ GHashTableIter iter;
+ gpointer key;
+
+ if (priv->clones == NULL)
+ return;
+
+ g_hash_table_iter_init (&iter, priv->clones);
+ while (g_hash_table_iter_next (&iter, &key, NULL))
+ clutter_actor_queue_redraw (key);
+}
+
+void
+_clutter_actor_queue_relayout_on_clones (ClutterActor *self)
+{
+ ClutterActorPrivate *priv = self->priv;
+ GHashTableIter iter;
+ gpointer key;
+
+ if (priv->clones == NULL)
+ return;
+
+ g_hash_table_iter_init (&iter, priv->clones);
+ while (g_hash_table_iter_next (&iter, &key, NULL))
+ clutter_actor_queue_relayout (key);
+}
diff --git a/clutter/clutter-clone.c b/clutter/clutter-clone.c
index 6a82beb..1f94ab2 100644
--- a/clutter/clutter-clone.c
+++ b/clutter/clutter-clone.c
@@ -378,34 +378,17 @@ clutter_clone_new (ClutterActor *source)
}
static void
-clone_source_queue_redraw_cb (ClutterActor *source,
- ClutterActor *origin,
- ClutterClone *self)
-{
- clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
-}
-
-static void
-clone_source_queue_relayout_cb (ClutterActor *source,
- ClutterClone *self)
-{
- clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
-}
-
-static void
clutter_clone_set_source_internal (ClutterClone *self,
ClutterActor *source)
{
ClutterClonePrivate *priv = self->priv;
+ if (priv->clone_source == source)
+ return;
+
if (priv->clone_source != NULL)
{
- g_signal_handlers_disconnect_by_func (priv->clone_source,
- G_CALLBACK (clone_source_queue_redraw_cb),
- self);
- g_signal_handlers_disconnect_by_func (priv->clone_source,
- G_CALLBACK (clone_source_queue_relayout_cb),
- self);
+ _clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
g_object_unref (priv->clone_source);
priv->clone_source = NULL;
}
@@ -413,10 +396,7 @@ clutter_clone_set_source_internal (ClutterClone *self,
if (source != NULL)
{
priv->clone_source = g_object_ref (source);
- g_signal_connect (priv->clone_source, "queue-redraw",
- G_CALLBACK (clone_source_queue_redraw_cb), self);
- g_signal_connect (priv->clone_source, "queue-relayout",
- G_CALLBACK (clone_source_queue_relayout_cb), self);
+ _clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self));
}
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]