autd3_driver/firmware/driver/async/
strategy.rs1use std::time::{Duration, Instant};
2
3use crate::firmware::driver::{FixedDelay, FixedSchedule};
4use autd3_core::sleep::r#async::Sleep;
5
6pub trait TimerStrategy<S: Sleep>: Send {
8 fn initial(&self) -> Instant;
10 fn sleep(
13 &self,
14 old: Instant,
15 interval: Duration,
16 ) -> impl std::future::Future<Output = Instant> + Send;
17}
18
19impl<S: Sleep> TimerStrategy<S> for FixedSchedule<S> {
20 fn initial(&self) -> Instant {
21 Instant::now()
22 }
23
24 async fn sleep(&self, old: Instant, interval: Duration) -> Instant {
25 let new = old + interval;
26 self.0
27 .sleep(new.saturating_duration_since(Instant::now()))
28 .await;
29 new
30 }
31}
32
33impl<S: Sleep> TimerStrategy<S> for FixedDelay<S> {
34 fn initial(&self) -> Instant {
35 Instant::now()
36 }
37
38 async fn sleep(&self, old: Instant, interval: Duration) -> Instant {
39 self.0.sleep(interval).await;
40 old
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use std::sync::{Arc, RwLock};
47
48 use super::*;
49
50 #[derive(Debug)]
51 struct DebugSleep {
52 sleep: Arc<RwLock<Vec<Duration>>>,
53 }
54
55 impl Sleep for DebugSleep {
56 async fn sleep(&self, duration: Duration) {
57 self.sleep.write().unwrap().push(duration);
58 }
59 }
60
61 #[tokio::test]
62 async fn fixed_schedule_test() {
63 let sleep = Arc::new(RwLock::new(Vec::new()));
64
65 let strategy = FixedSchedule(DebugSleep { sleep });
66
67 let start = strategy.initial();
68 let interval = Duration::from_millis(1);
69
70 let next = strategy.sleep(start, interval).await;
71 assert_eq!(next, start + interval);
72
73 let next = strategy.sleep(next, interval).await;
74 assert_eq!(next, start + interval * 2);
75 }
76
77 #[tokio::test]
78 async fn fixed_delay_test() {
79 let sleep = Arc::new(RwLock::new(Vec::new()));
80
81 let strategy = FixedDelay(DebugSleep {
82 sleep: sleep.clone(),
83 });
84
85 let start = strategy.initial();
86 let interval = Duration::from_millis(1);
87
88 let next = strategy.sleep(start, interval).await;
89 assert_eq!(next, start);
90
91 let next = strategy.sleep(start, interval).await;
92 assert_eq!(next, start);
93
94 assert_eq!(*sleep.read().unwrap(), vec![interval, interval]);
95 }
96}