use crate::clock::{Error, Interval, Target};
use async_std::sync::{Arc, Barrier};
use std::{collections::BTreeMap, time::Duration};
pub struct Clockwork {
clocks: BTreeMap<Target, Clock>,
}
impl Clockwork {
pub fn new() -> Self {
Self {
clocks: Default::default(),
}
}
pub fn clock(&mut self, trgt: Target) -> &mut Clock {
self.clocks.entry(trgt).or_insert(Clock::default())
}
}
#[derive(Default)]
pub struct Clock {
interval: Option<Interval>,
fence: Option<Box<dyn Fn(Arc<Barrier>)>>,
}
impl Clock {
pub fn set(&mut self, iv: Interval) -> &mut Self {
self.interval = Some(iv);
self
}
pub fn fence<F: 'static>(&mut self, f: F) -> &mut Self
where
F: Fn(Arc<Barrier>),
{
self.fence = Some(Box::new(f));
self
}
pub fn ok(&mut self) -> Result<(), Error> {
match self.interval {
Some(Interval::Delay(0.0)) => Err(Error::InvalidTime),
Some(Interval::Timed(dur)) if dur.as_nanos() == 0 => Err(Error::InvalidTime),
Some(Interval::Stepped) if self.fence.is_none() => Err(Error::NoFence),
_ => Ok(()),
}
}
}