1. Apocalypse 7
Back to Clutter/Apocalypses
1.1. Apocalypse
Deprecate ClutterClone.
Introduce the ClutterActorModel interface, which controls what elements should be used as templates:
- preferred width
- preferred height
- paint details
- clip
- effects
- pick region
- allocation
Use a ClutterActorModel to function as a model for another ClutterActor.
ClutterActor will, internally, delegate to the model the details specified inside the ClutterActorModel contract.
ClutterActor implements ClutterActorModel, so that every actor can be used as a model for another one.
1.2. Exegesis
The current mechanism for having the same actor in two parts of the scene graph is to use a Clone; the Clone is a fairly suboptimal approach for a variety of reasons:
- It does not have access to the Actor's internal state, and yet it has to modify it.
This meant adding a whole lot of private escape hatches inside ClutterActor for ClutterClone to use, punching holes through the state tracking, and hoping that both ClutterActor ClutterClone continue to behave correctly.
- It does not define the precise semantics of the cloning.
- What is going to be cloned? the preferred size? the allocation? the paint sequence? how are effects on the source going to be cloned?
- In order to maintain the invariants for the state tracking (size negotiation, mapped state) a Clone can only use actors that are already on the scene graph.
All these issues stem by the fact that what we want to do is for an actor to be a view to a model - i.e. we need to have an object that provides us with the various operations we wish an actor should display.
An ActorModel interface would allow us to have a simple API for representing the state we wish to display when we assign an instance of an object implementing it to a ClutterActor.
ClutterActor itself would provide an implementation of the ActorModel interface, so that we could simply ask a ClutterActor to use another one as a model - regardless of whether the model is effectively part of the scene graph or not.
The ActorModel interface allows us to define the effective parts we wish to control as well, instead of leaving the semantics undefined.
1.3. Synopsis
1.3.1. ClutterActorModel
public interface ClutterActorModel { bool get_preferred_width (float for_height, out float minimum, out float natural); bool get_preferred_height (float for_width, out float minimum, out float natural); bool allocate (ActorBox allocation, AllocationFlags flags); bool paint_node (PaintNode root); bool paint (); bool event (); }
1.3.2. ClutterActor
void clutter_actor_set_model (ClutterActor *self, ClutterActorModel *model); ClutterActorModel *clutter_actor_get_model (ClutterActor *self);