use crate::{
scheduler::Duration, Block, InputPort, Message, OutputPort, Port, PortDescriptor, Scheduler,
};
use std::ops::Range;
#[cfg(feature = "std")]
use rand::Rng;
pub struct Delay<T: Message> {
input: InputPort<T>,
output: OutputPort<T>,
delay: DelayType,
}
pub enum DelayType {
Fixed(Duration),
Random(Range<Duration>),
}
impl<T: Message> Block for Delay<T> {
fn inputs(&self) -> Vec<PortDescriptor> {
vec![PortDescriptor::from(&self.input)]
}
fn outputs(&self) -> Vec<PortDescriptor> {
vec![PortDescriptor::from(&self.output)]
}
fn execute(&mut self, scheduler: &dyn Scheduler) -> Result<(), ()> {
while let Some(message) = self.input.receive()? {
if !self.output.is_connected() {
drop(message);
continue;
}
let duration = match self.delay {
DelayType::Fixed(duration) => duration,
DelayType::Random(ref range) => {
#[cfg(feature = "std")]
{
let mut rng = rand::thread_rng();
let low = range.start.as_nanos() as u64;
let high = range.end.as_nanos() as u64;
Duration::from_nanos(rng.gen_range(low, high))
}
#[cfg(not(feature = "std"))]
let mut _rng = todo!();
}
};
scheduler.sleep_for(duration)?;
self.output.send(&message)?;
}
Ok(())
}
}