mraphics_core/animation/
timeline.rs1use crate::animation::Action;
2use std::time::Instant;
3
4#[derive(Debug)]
5pub enum TimelineState {
6 PLAYING,
7 PAUSED,
8 WAITING,
9}
10
11pub trait Timeline<'res> {
12 fn current_time(&self) -> f32;
13 fn seek(&mut self, time: f32);
14 fn state(&self) -> &TimelineState;
15
16 fn start(&mut self);
17 fn forward(&mut self);
18 fn pause(&mut self);
19
20 fn actions(&self) -> &Vec<Action<'res>>;
21 fn actions_mut(&mut self) -> &mut Vec<Action<'res>>;
22 fn add_action(&mut self, action: Action<'res>);
23
24 fn all_stopped(&self) -> bool {
25 for action in self.actions() {
26 if !action.stopped {
27 return false;
28 }
29 }
30
31 true
32 }
33
34 fn process(&mut self) {
35 let current_time = self.current_time();
36 for action in self.actions_mut() {
37 let elapsed = current_time - action.start_time;
38 let progress = elapsed / action.duration;
39 action.execute(progress, elapsed);
40 }
41 }
42}
43
44pub struct LogicalTimeline<'res> {
45 pub state: TimelineState,
46 pub logical_fps: f32,
47
48 current_frame: i32,
49
50 actions: Vec<Action<'res>>,
51}
52
53impl<'res> LogicalTimeline<'res> {
54 pub fn new() -> Self {
55 Self {
56 state: TimelineState::WAITING,
57 logical_fps: 60.0,
58 current_frame: 0,
59 actions: Vec::new(),
60 }
61 }
62}
63
64impl<'res> Timeline<'res> for LogicalTimeline<'res> {
65 fn current_time(&self) -> f32 {
66 (self.current_frame as f32) * (1.0 / self.logical_fps)
67 }
68
69 fn seek(&mut self, time: f32) {
70 self.current_frame = (self.logical_fps * time) as i32;
71 }
72
73 fn state(&self) -> &TimelineState {
74 &self.state
75 }
76
77 fn start(&mut self) {
78 self.state = TimelineState::PLAYING;
79 self.process();
80 }
81
82 fn forward(&mut self) {
83 match self.state {
84 TimelineState::PLAYING => {
85 self.current_frame += 1;
86 self.process();
87 }
88 _ => {}
89 }
90 }
91
92 fn pause(&mut self) {
93 self.state = TimelineState::PAUSED;
94 }
95
96 fn actions(&self) -> &Vec<Action<'res>> {
97 &self.actions
98 }
99
100 fn actions_mut(&mut self) -> &mut Vec<Action<'res>> {
101 &mut self.actions
102 }
103
104 fn add_action(&mut self, action: Action<'res>) {
105 self.actions.push(action);
106 }
107}
108
109pub struct PhysicalTimeline<'res> {
110 pub state: TimelineState,
111 pub current_time: f32,
112
113 start_instant: Instant,
114 time_at_pause: f32,
115
116 actions: Vec<Action<'res>>,
117}
118
119impl<'res> PhysicalTimeline<'res> {
120 pub fn new() -> Self {
121 Self {
122 state: TimelineState::WAITING,
123 current_time: 0.0,
124 actions: Vec::new(),
125 start_instant: Instant::now(),
126 time_at_pause: 0.0,
127 }
128 }
129}
130
131impl<'res> Timeline<'res> for PhysicalTimeline<'res> {
132 fn current_time(&self) -> f32 {
133 self.current_time
134 }
135
136 fn seek(&mut self, time: f32) {
137 self.current_time = time;
138 }
139
140 fn state(&self) -> &TimelineState {
141 &self.state
142 }
143
144 fn start(&mut self) {
145 match self.state {
146 TimelineState::WAITING => self.time_at_pause = 0.0,
147 TimelineState::PAUSED => {
148 self.time_at_pause = self.current_time;
149 }
150 TimelineState::PLAYING => {}
151 }
152
153 self.start_instant = Instant::now();
154 self.state = TimelineState::PLAYING;
155 self.process();
156 }
157
158 fn forward(&mut self) {
159 match self.state {
160 TimelineState::PLAYING => {
161 self.current_time = self.time_at_pause + self.start_instant.elapsed().as_secs_f32();
162 self.process();
163 }
164 _ => {}
165 }
166 }
167
168 fn pause(&mut self) {
169 self.state = TimelineState::PAUSED;
170 }
171
172 fn actions(&self) -> &Vec<Action<'res>> {
173 &self.actions
174 }
175
176 fn actions_mut(&mut self) -> &mut Vec<Action<'res>> {
177 &mut self.actions
178 }
179
180 fn add_action(&mut self, action: Action<'res>) {
181 self.actions.push(action);
182 }
183}