argui_animation/
scheduler.rs1use crate::{Duration, Time};
2
3#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
5pub struct AnimationId(u64);
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub struct Frame {
10 pub now: Time,
11 pub elapsed: Duration,
12}
13
14#[derive(Debug, Default)]
16pub struct Scheduler {
17 active: Vec<AnimationId>,
18 next_id: u64,
19 last_frame: Option<Time>,
20}
21
22impl Scheduler {
23 #[must_use]
24 pub fn start(&mut self) -> AnimationId {
25 let id = AnimationId(self.next_id);
26 self.next_id = self.next_id.wrapping_add(1);
27 self.active.push(id);
28 id
29 }
30
31 pub fn stop(&mut self, id: AnimationId) -> bool {
32 let Some(index) = self.active.iter().position(|active| *active == id) else {
33 return false;
34 };
35 self.active.swap_remove(index);
36 if self.active.is_empty() {
37 self.last_frame = None;
38 }
39 true
40 }
41
42 #[must_use]
43 pub fn contains(&self, id: AnimationId) -> bool {
44 self.active.contains(&id)
45 }
46
47 #[must_use]
48 pub fn active(&self) -> &[AnimationId] {
49 &self.active
50 }
51
52 #[must_use]
53 pub fn needs_frame(&self) -> bool {
54 !self.active.is_empty()
55 }
56
57 pub fn frame(&mut self, now: Time) -> Option<Frame> {
58 self.needs_frame().then(|| {
59 let elapsed = self
60 .last_frame
61 .map_or(Duration::ZERO, |last| now.duration_since(last));
62 self.last_frame = Some(now);
63 Frame { now, elapsed }
64 })
65 }
66}