Skip to main content

mraphics_core/animation/
timeline.rs

1use 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}