#![no_std]
use embassy_time::{Duration, Instant, Timer};
pub struct Interval {
interval: Duration,
wake_time: Instant,
missed_tick_behavior: MissedTickBehavior,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MissedTickBehavior {
#[default]
Burst,
#[allow(unused)]
Delay,
#[allow(unused)]
Skip,
}
impl Interval {
pub fn new(interval: Duration, missed_tick_behavior: MissedTickBehavior) -> Self {
let wake_time = Instant::now();
Self {
interval,
wake_time,
missed_tick_behavior,
}
}
pub fn tick(&mut self) -> Timer {
let now = Instant::now();
if now > self.wake_time {
self.wake_time =
self.missed_tick_behavior
.next_timeout(self.wake_time, now, self.interval);
}
let timer = Timer::at(self.wake_time);
self.wake_time += self.interval;
timer
}
}
impl MissedTickBehavior {
fn next_timeout(&self, timeout: Instant, now: Instant, period: Duration) -> Instant {
match self {
Self::Burst => timeout + period,
Self::Delay => now + period,
Self::Skip => {
now + period - Duration::from_ticks((now - timeout).as_ticks() % period.as_ticks())
}
}
}
}