1use core::time::Duration;
2
3use super::{time_since_start, GenericSleep, Instant, Selectable, Task};
4
5pub struct Loop {
7 delta: Duration,
8 next: Instant,
9 cycle: usize,
10}
11
12impl Loop {
13 #[inline]
14 pub fn new(delta: Duration) -> Self {
16 Loop {
17 delta,
18 next: time_since_start() + delta,
19 cycle: 0,
20 }
21 }
22
23 pub fn delay(&mut self) {
25 if let Some(d) = self.next.checked_sub_instant(time_since_start()) {
26 Task::delay(d);
27 }
28 self.next += self.delta;
29 self.cycle += 1;
30 }
31
32 #[inline]
33 pub fn cycle(&self) -> usize {
39 self.cycle
40 }
41
42 #[inline]
43 pub fn is_mod(&self, modulus: usize) -> bool {
46 self.cycle % modulus == 0
47 }
48
49 #[inline]
50 pub fn select(&'_ mut self) -> impl Selectable + '_ {
52 struct LoopSelect<'a>(&'a mut Loop);
53
54 impl<'a> Selectable for LoopSelect<'a> {
55 fn poll(self) -> Result<(), Self> {
56 if time_since_start() >= self.0.next {
57 self.0.next += self.0.delta;
58 self.0.cycle += 1;
59 Ok(())
60 } else {
61 Err(self)
62 }
63 }
64 fn sleep(&self) -> GenericSleep {
65 GenericSleep::Timestamp(self.0.next)
66 }
67 }
68
69 LoopSelect(self)
70 }
71}