Skip to main content

aura_anim_core/runtime/
motion.rs

1use std::marker::PhantomData;
2
3use crate::{
4    Animatable, AnimationCommand, AnimationState, IntoMotionAnimation, MotionError, MotionRuntime,
5};
6
7use super::{MotionId, PlaybackId};
8
9/// A typed handle to an animation stored in a [`MotionRuntime`].
10///
11/// Handles become invalid after their animation is removed.
12#[must_use = "a motion handle is required to access the runtime-managed animation"]
13#[derive(Debug, PartialEq, Eq, Hash)]
14pub struct Motion<T> {
15    id: MotionId,
16    marker: PhantomData<fn() -> T>,
17}
18
19impl<T> Copy for Motion<T> {}
20
21impl<T> Clone for Motion<T> {
22    fn clone(&self) -> Self {
23        *self
24    }
25}
26
27impl<T> Motion<T> {
28    pub(super) fn new(id: MotionId, marker: PhantomData<fn() -> T>) -> Self {
29        Self { id, marker }
30    }
31
32    pub(super) const fn id(self) -> MotionId {
33        self.id
34    }
35
36    /// Returns the untyped ID for this motion lifecycle.
37    #[must_use]
38    pub const fn motion_id(self) -> MotionId {
39        self.id
40    }
41}
42
43impl<T: Animatable> Motion<T> {
44    /// Transitions this motion toward `target`.
45    pub fn transition_to(self, target: T, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
46        runtime.transition_to(self, target)
47    }
48
49    /// Transitions this motion and returns the new playback ID.
50    pub fn transition_to_tracked(
51        self,
52        target: T,
53        runtime: &mut MotionRuntime,
54    ) -> Result<PlaybackId, MotionError> {
55        runtime.transition_to_tracked(self, target)
56    }
57
58    /// Replaces this motion's current animation.
59    pub fn play<P, Kind>(self, playback: P, runtime: &mut MotionRuntime) -> Result<(), MotionError>
60    where
61        P: IntoMotionAnimation<T, Kind>,
62    {
63        runtime.play(self, playback)
64    }
65
66    /// Replaces this motion's current animation and returns its playback ID.
67    pub fn play_tracked<P, Kind>(
68        self,
69        playback: P,
70        runtime: &mut MotionRuntime,
71    ) -> Result<PlaybackId, MotionError>
72    where
73        P: IntoMotionAnimation<T, Kind>,
74    {
75        runtime.play_tracked(self, playback)
76    }
77
78    /// Clones and returns the current value.
79    pub fn value(self, runtime: &MotionRuntime) -> Result<T, MotionError> {
80        runtime.value(self).cloned()
81    }
82
83    /// Borrows the current value.
84    pub fn value_ref(self, runtime: &MotionRuntime) -> Result<&T, MotionError> {
85        runtime.value(self)
86    }
87
88    /// Returns the current lifecycle state.
89    pub fn state(self, runtime: &MotionRuntime) -> Result<AnimationState, MotionError> {
90        runtime.state(self)
91    }
92
93    /// Returns the ID of this motion's current playback.
94    pub fn playback(self, runtime: &MotionRuntime) -> Result<PlaybackId, MotionError> {
95        runtime.playback(self)
96    }
97
98    /// Returns whether the motion is active.
99    pub fn is_active(self, runtime: &MotionRuntime) -> Result<bool, MotionError> {
100        runtime.is_active(self)
101    }
102
103    /// Returns whether the motion completed.
104    pub fn is_completed(self, runtime: &MotionRuntime) -> Result<bool, MotionError> {
105        self.state(runtime)
106            .map(|state| state == AnimationState::Completed)
107    }
108
109    /// Pauses the motion.
110    pub fn pause(self, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
111        runtime.command(self, AnimationCommand::Pause)
112    }
113
114    /// Resumes the motion.
115    pub fn resume(self, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
116        runtime.command(self, AnimationCommand::Resume)
117    }
118
119    /// Cancels the motion.
120    pub fn cancel(self, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
121        runtime.command(self, AnimationCommand::Cancel)
122    }
123
124    /// Seeks the motion to normalized progress.
125    pub fn seek(self, progress: f32, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
126        runtime.command(self, AnimationCommand::Seek(progress))
127    }
128
129    /// Moves the motion to completion.
130    pub fn finish(self, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
131        runtime.command(self, AnimationCommand::Finish)
132    }
133
134    /// Removes the motion from the runtime.
135    pub fn remove(self, runtime: &mut MotionRuntime) -> Result<(), MotionError> {
136        runtime.remove(self)
137    }
138}