use std::fmt;
use std::sync::Arc;
use std::time::Duration;
use crate::traits::MonotonicClock;
pub const MIN_SAMPLE_PERIOD: Duration = Duration::from_millis(100);
#[derive(Clone, Default)]
pub(super) struct SampleSchedule {
clock: Option<Arc<MonotonicClock>>,
next_due: Option<Duration>,
}
impl fmt::Debug for SampleSchedule {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SampleSchedule")
.field("clock_bound", &self.clock.is_some())
.field("next_due", &self.next_due)
.finish()
}
}
impl SampleSchedule {
pub(super) fn bind(&mut self, clock: Option<Arc<MonotonicClock>>, period: Duration) {
self.clock = clock;
self.restart(period);
}
pub(super) fn restart(&mut self, period: Duration) {
self.next_due = self
.clock
.as_ref()
.map(|clock| clock().saturating_add(period));
}
pub(super) fn next_due(&self) -> Option<Duration> {
self.next_due
}
pub(super) fn take_due(&mut self, now: Duration, period: Duration) -> bool {
match self.next_due {
Some(due) if due <= now => {
let next = due.saturating_add(period);
self.next_due = Some(if next > now {
next
} else {
now.saturating_add(period)
});
true
}
_ => false,
}
}
}