ferroui_base/rendering/composition/animations/i_animation_instance.rs
1use crate::rendering::composition::expressions::ExpressionVariant;
2use crate::rendering::composition::server::{CompositionProperty, IServerClockItem, ServerCompositor, ServerObjectId};
3use std::rc::Rc;
4use std::time::Duration;
5
6/// A running animation of one property of a server object.
7///
8/// An instance is created on the UI thread by the animation it belongs to,
9/// crosses to the server in the batch that starts it, and is driven there.
10/// It names its target, and the objects its reference parameters refer to,
11/// by id: the UI thread never holds a server object. The ids are resolved
12/// on the server by [`resolve`](Self::resolve), which the animations of the
13/// target call before [`initialize`](Self::initialize).
14pub trait IAnimationInstance: IServerClockItem + 'static {
15 /// The object whose property is animated.
16 fn target_object(&self) -> ServerObjectId;
17
18 /// Resolves the server objects the instance refers to by id, on the
19 /// compositor that drives it. Called once, on the server, before the
20 /// instance is initialized; an instance that refers to no object needs
21 /// nothing.
22 fn resolve(&self, _compositor: &Rc<ServerCompositor>) {}
23
24 /// The value of the animation at `now`.
25 fn evaluate(&self, now: Duration, current_value: ExpressionVariant) -> ExpressionVariant;
26
27 /// Attaches the instance to the property it animates.
28 fn initialize(&self, started_at: Duration, starting_value: ExpressionVariant, property: &'static CompositionProperty);
29
30 fn activate(&self);
31
32 fn deactivate(&self);
33
34 fn invalidate(&self);
35}
36
37/// An animation instance on its way to the server.
38///
39/// An instance belongs to the server: it resolves server objects and keeps
40/// its state in cells, so it cannot cross threads. What the UI thread
41/// creates and a batch carries is the factory of the instance, which holds
42/// what the instance is made of (all of it `Send`) and is called on the
43/// server.
44pub struct AnimationInstanceFactory(Box<dyn FnOnce() -> Rc<dyn IAnimationInstance> + Send>);
45
46impl AnimationInstanceFactory {
47 pub fn new(create: impl FnOnce() -> Rc<dyn IAnimationInstance> + Send + 'static) -> Self {
48 Self(Box::new(create))
49 }
50
51 /// Creates the instance. Called on the thread that runs it.
52 pub fn create(self) -> Rc<dyn IAnimationInstance> {
53 (self.0)()
54 }
55}