Skip to main content

aura_anim_core/runtime/
motion.rs

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