autd3_driver/firmware/driver/
strategy.rs1use std::time::{Duration, Instant};
2
3use autd3_core::sleep::Sleep;
4
5pub trait TimerStrategy<S: Sleep> {
7 fn initial(&self) -> Instant;
9 fn sleep(&self, old: Instant, interval: Duration) -> Instant;
12}
13
14pub struct FixedSchedule<S>(pub S);
17
18impl<S: Sleep> TimerStrategy<S> for FixedSchedule<S> {
19 fn initial(&self) -> Instant {
20 Instant::now()
21 }
22
23 fn sleep(&self, old: Instant, interval: Duration) -> Instant {
24 let new = old + interval;
25 self.0.sleep(new.saturating_duration_since(Instant::now()));
26 new
27 }
28}
29
30impl Default for FixedSchedule<autd3_core::sleep::SpinSleeper> {
31 fn default() -> Self {
32 Self(autd3_core::sleep::SpinSleeper::default())
33 }
34}
35
36pub struct FixedDelay<S>(pub S);
38
39impl<S: Sleep> TimerStrategy<S> for FixedDelay<S> {
40 fn initial(&self) -> Instant {
41 Instant::now()
42 }
43
44 fn sleep(&self, old: Instant, interval: Duration) -> Instant {
45 self.0.sleep(interval);
46 old
47 }
48}
49
50impl<S: Sleep> TimerStrategy<S> for Box<dyn TimerStrategy<S>> {
52 fn initial(&self) -> Instant {
53 self.as_ref().initial()
54 }
55
56 fn sleep(&self, old: Instant, interval: Duration) -> Instant {
57 self.as_ref().sleep(old, interval)
58 }
59}
60#[cfg(test)]
63mod tests {
64 use std::{cell::RefCell, rc::Rc};
65
66 use derive_more::Debug;
67
68 use super::*;
69
70 #[derive(Debug)]
71 struct DebugSleep {
72 sleep: Rc<RefCell<Vec<Duration>>>,
73 }
74
75 impl Sleep for DebugSleep {
76 fn sleep(&self, duration: Duration) {
77 self.sleep.borrow_mut().push(duration);
78 }
79 }
80
81 #[test]
82 fn fixed_schedule_test() {
83 let sleep = Rc::new(RefCell::new(Vec::new()));
84
85 let strategy = FixedSchedule(DebugSleep { sleep });
86
87 let start = strategy.initial();
88 let interval = Duration::from_millis(1);
89
90 let next = strategy.sleep(start, interval);
91 assert_eq!(next, start + interval);
92
93 let next = strategy.sleep(next, interval);
94 assert_eq!(next, start + interval * 2);
95 }
96
97 #[test]
98 fn fixed_delay_test() {
99 let sleep = Rc::new(RefCell::new(Vec::new()));
100
101 let strategy = FixedDelay(DebugSleep {
102 sleep: sleep.clone(),
103 });
104
105 let start = strategy.initial();
106 let interval = Duration::from_millis(1);
107
108 let next = strategy.sleep(start, interval);
109 assert_eq!(next, start);
110
111 let next = strategy.sleep(start, interval);
112 assert_eq!(next, start);
113
114 assert_eq!(*sleep.borrow(), vec![interval, interval]);
115 }
116}