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.
This commit is contained in:
parent
c32973158d
commit
028baa99a0
@ -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__ */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -377,35 +377,18 @@ clutter_clone_new (ClutterActor *source)
|
||||
return g_object_new (CLUTTER_TYPE_CLONE, "source", source, NULL);
|
||||
}
|
||||
|
||||
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]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user