use crate::integer::Time; #[derive(Debug)] pub struct TimedInstruction<I,T>{ pub time:Time<T>, pub instruction:I, } /// 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, { 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, { 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>>){ match instruction{ Some(unwrap_instruction)=>{ if unwrap_instruction.time<self.time { self.time=unwrap_instruction.time; self.instruction=Some(unwrap_instruction.instruction); } }, None=>(), } } pub fn instruction(self)->Option<TimedInstruction<I,T>>{ //STEAL INSTRUCTION AND DESTROY INSTRUCTIONCOLLECTOR match self.instruction{ Some(instruction)=>Some(TimedInstruction{ time:self.time, instruction }), None=>None, } } }