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
6#[cfg(feature = "async-trait")]
7mod internal {
8 use super::*;
9
10 #[autd3_core::async_trait]
12 pub trait TimerStrategy<S: Sleep>: Send + Sync {
13 fn initial(&self) -> Instant;
15 async fn sleep(&self, old: Instant, interval: Duration) -> Instant;
18 }
19}
20
21#[cfg(not(feature = "async-trait"))]
22mod internal {
23 use super::*;
24
25 pub trait TimerStrategy<S: Sleep>: Send {
27 fn initial(&self) -> Instant;
29 fn sleep(
32 &self,
33 old: Instant,
34 interval: Duration,
35 ) -> impl std::future::Future<Output = Instant> + Send;
36 }
37}
38
39pub use internal::*;
40
41#[cfg_attr(feature = "async-trait", autd3_core::async_trait)]
42impl<S: Sleep> TimerStrategy<S> for FixedSchedule<S> {
43 fn initial(&self) -> Instant {
44 Instant::now()
45 }
46
47 async fn sleep(&self, old: Instant, interval: Duration) -> Instant {
48 let new = old + interval;
49 self.0
50 .sleep(new.saturating_duration_since(Instant::now()))
51 .await;
52 new
53 }
54}
55
56#[cfg_attr(feature = "async-trait", autd3_core::async_trait)]
57impl<S: Sleep> TimerStrategy<S> for FixedDelay<S> {
58 fn initial(&self) -> Instant {
59 Instant::now()
60 }
61
62 async fn sleep(&self, old: Instant, interval: Duration) -> Instant {
63 self.0.sleep(interval).await;
64 old
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use std::sync::{Arc, RwLock};
71
72 use derive_more::Debug;
73
74 use super::*;
75
76 #[derive(Debug)]
77 struct DebugSleep {
78 sleep: Arc<RwLock<Vec<Duration>>>,
79 }
80
81 #[cfg_attr(feature = "async-trait", autd3_core::async_trait)]
82 impl Sleep for DebugSleep {
83 async fn sleep(&self, duration: Duration) {
84 self.sleep.write().unwrap().push(duration);
85 }
86 }
87
88 #[tokio::test]
89 async fn fixed_schedule_test() {
90 let sleep = Arc::new(RwLock::new(Vec::new()));
91
92 let strategy = FixedSchedule(DebugSleep { sleep });
93
94 let start = strategy.initial();
95 let interval = Duration::from_millis(1);
96
97 let next = strategy.sleep(start, interval).await;
98 assert_eq!(next, start + interval);
99
100 let next = strategy.sleep(next, interval).await;
101 assert_eq!(next, start + interval * 2);
102 }
103
104 #[tokio::test]
105 async fn fixed_delay_test() {
106 let sleep = Arc::new(RwLock::new(Vec::new()));
107
108 let strategy = FixedDelay(DebugSleep {
109 sleep: sleep.clone(),
110 });
111
112 let start = strategy.initial();
113 let interval = Duration::from_millis(1);
114
115 let next = strategy.sleep(start, interval).await;
116 assert_eq!(next, start);
117
118 let next = strategy.sleep(start, interval).await;
119 assert_eq!(next, start);
120
121 assert_eq!(*sleep.read().unwrap(), vec![interval, interval]);
122 }
123}