animato_timeline/
sequence.rs1use crate::timeline::{At, Timeline};
4use alloc::boxed::Box;
5use alloc::string::String;
6use animato_core::Playable;
7
8#[derive(Debug)]
10pub struct Sequence {
11 inner: Timeline,
12 cursor: f32,
13}
14
15impl Default for Sequence {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl Sequence {
22 pub fn new() -> Self {
24 Self {
25 inner: Timeline::new(),
26 cursor: 0.0,
27 }
28 }
29
30 pub fn then<A>(mut self, label: impl Into<String>, animation: A) -> Self
32 where
33 A: Playable + Send + 'static,
34 {
35 let duration = animation.duration().max(0.0);
36 self.inner = self.inner.add(label, animation, At::Absolute(self.cursor));
37 self.cursor += duration;
38 self
39 }
40
41 pub fn then_for<A>(mut self, label: impl Into<String>, animation: A, duration: f32) -> Self
46 where
47 A: Playable + Send + 'static,
48 {
49 let duration = duration.max(0.0);
50 self.inner = self.inner.add_boxed_with_duration(
51 label,
52 Box::new(animation),
53 At::Absolute(self.cursor),
54 duration,
55 );
56 self.cursor += duration;
57 self
58 }
59
60 pub fn gap(mut self, seconds: f32) -> Self {
62 self.cursor += seconds.max(0.0);
63 self
64 }
65
66 pub fn build(self) -> Timeline {
68 self.inner
69 }
70
71 pub fn cursor(&self) -> f32 {
73 self.cursor
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use animato_core::Update;
81 use animato_tween::Tween;
82
83 #[test]
84 fn sequence_places_entries_back_to_back() {
85 let mut timeline = Sequence::new()
86 .then("first", Tween::new(0.0_f32, 10.0).duration(1.0).build())
87 .then("second", Tween::new(0.0_f32, 20.0).duration(1.0).build())
88 .build();
89
90 timeline.play();
91 timeline.update(1.5);
92
93 assert_eq!(timeline.get::<Tween<f32>>("first").unwrap().value(), 10.0);
94 assert_eq!(timeline.get::<Tween<f32>>("second").unwrap().value(), 10.0);
95 }
96
97 #[test]
98 fn gap_delays_next_entry() {
99 let mut timeline = Sequence::new()
100 .then("first", Tween::new(0.0_f32, 10.0).duration(1.0).build())
101 .gap(0.5)
102 .then("second", Tween::new(0.0_f32, 20.0).duration(1.0).build())
103 .build();
104
105 timeline.play();
106 timeline.update(1.25);
107
108 assert_eq!(timeline.get::<Tween<f32>>("first").unwrap().value(), 10.0);
109 assert_eq!(timeline.get::<Tween<f32>>("second").unwrap().value(), 0.0);
110 }
111}