use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
time::Duration,
};
#[derive(Debug)]
pub struct Interval {
next_tick: Duration,
period: Duration,
time_fn: fn() -> Duration,
}
impl Interval {
pub fn new(period: Duration, time_fn: fn() -> Duration) -> Self {
let now = time_fn();
Self {
next_tick: now,
period,
time_fn,
}
}
pub fn tick(&mut self) -> IntervalTick<'_> {
IntervalTick { interval: self }
}
pub fn reset(&mut self) {
self.next_tick = (self.time_fn)();
}
}
pub struct IntervalTick<'a> {
interval: &'a mut Interval,
}
impl Future for IntervalTick<'_> {
type Output = ();
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.get_mut();
let now = (this.interval.time_fn)();
if now >= this.interval.next_tick {
this.interval.next_tick += this.interval.period;
Poll::Ready(())
} else {
Poll::Pending
}
}
}