use crate::integer::Time; #[derive(Clone,Debug)] pub struct TimedInstruction<I,T>{ pub time:Time<T>, pub instruction:I, } impl<I,T> TimedInstruction<I,T>{ #[inline] pub fn set_time<TimeInner>(self,new_time:Time<TimeInner>)->TimedInstruction<I,TimeInner>{ TimedInstruction{ time:new_time, instruction:self.instruction, } } } /// Ensure all emitted instructions are processed before consuming external instructions pub trait InstructionEmitter<I>{ type TimeInner; fn next_instruction(&self,time_limit:Time<Self::TimeInner>)->Option<TimedInstruction<I,Self::TimeInner>>; } /// Apply an atomic state update pub trait InstructionConsumer<I>{ type TimeInner; fn process_instruction(&mut self,instruction:TimedInstruction<I,Self::TimeInner>); } /// If the object produces its own instructions, allow exhaustively feeding them back in pub trait InstructionFeedback<I,T>:InstructionEmitter<I,TimeInner=T>+InstructionConsumer<I,TimeInner=T> where Time<T>:Copy, { #[inline] fn process_exhaustive(&mut self,time_limit:Time<T>){ while let Some(instruction)=self.next_instruction(time_limit){ self.process_instruction(instruction); } } } impl<I,T,X> InstructionFeedback<I,T> for X where Time<T>:Copy, X:InstructionEmitter<I,TimeInner=T>+InstructionConsumer<I,TimeInner=T>, {} //PROPER PRIVATE FIELDS!!! pub struct InstructionCollector<I,T>{ time:Time<T>, instruction:Option<I>, } impl<I,T> InstructionCollector<I,T> where Time<T>:Copy+PartialOrd, { #[inline] pub const fn new(time:Time<T>)->Self{ Self{ time, instruction:None } } #[inline] pub const fn time(&self)->Time<T>{ self.time } pub fn collect(&mut self,instruction:Option<TimedInstruction<I,T>>){ if let Some(ins)=instruction{ if ins.time<self.time{ self.time=ins.time; self.instruction=Some(ins.instruction); } } } pub fn instruction(self)->Option<TimedInstruction<I,T>>{ //STEAL INSTRUCTION AND DESTROY INSTRUCTIONCOLLECTOR self.instruction.map(|instruction|TimedInstruction{ time:self.time, instruction }) } }