diff --git a/lib/common/src/timer.rs b/lib/common/src/timer.rs index 59e558d..b75c68b 100644 --- a/lib/common/src/timer.rs +++ b/lib/common/src/timer.rs @@ -22,79 +22,106 @@ impl PauseState for Unpaused{ } } +#[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)] +enum Inner{} +type InnerTime=Time<Inner>; + #[derive(Clone,Copy,Debug)] -pub struct Realtime{ - offset:Time, +pub struct Realtime<In,Out>{ + offset:InnerTime, + _in:core::marker::PhantomData<In>, + _out:core::marker::PhantomData<Out>, } -impl Realtime{ - pub const fn new(offset:Time)->Self{ - Self{offset} +impl<In,Out> Realtime<In,Out>{ + pub const fn new(offset:InnerTime)->Self{ + Self{ + offset, + _in:core::marker::PhantomData, + _out:core::marker::PhantomData, + } } } #[derive(Clone,Copy,Debug)] -pub struct Scaled{ +pub struct Scaled<In,Out>{ scale:Ratio64, - offset:Time, + offset:InnerTime, + _in:core::marker::PhantomData<In>, + _out:core::marker::PhantomData<Out>, } -impl Scaled{ - pub const fn new(scale:Ratio64,offset:Time)->Self{ - Self{scale,offset} +impl<In,Out> Scaled<In,Out> + where Time<In>:Copy, +{ + pub const fn new(scale:Ratio64,offset:InnerTime)->Self{ + Self{ + scale, + offset, + _in:core::marker::PhantomData, + _out:core::marker::PhantomData, + } } const fn with_scale(scale:Ratio64)->Self{ - Self{scale,offset:Time::ZERO} + Self::new(scale,InnerTime::ZERO) } - const fn scale(&self,time:Time)->Time{ - Time::raw(self.scale.mul_int(time.get())) + const fn scale(&self,time:Time<In>)->InnerTime{ + InnerTime::raw(self.scale.mul_int(time.get())) } const fn get_scale(&self)->Ratio64{ self.scale } - fn set_scale(&mut self,time:Time,new_scale:Ratio64){ + fn set_scale(&mut self,time:Time<In>,new_scale:Ratio64){ let new_time=self.get_time(time); self.scale=new_scale; self.set_time(time,new_time); } } -pub trait TimerState:Copy+std::fmt::Debug{ +pub trait TimerState{ + type In; + type Out; fn identity()->Self; - fn get_time(&self,time:Time)->Time; - fn set_time(&mut self,time:Time,new_time:Time); - fn get_offset(&self)->Time; - fn set_offset(&mut self,offset:Time); + fn get_time(&self,time:Time<Self::In>)->Time<Self::Out>; + fn set_time(&mut self,time:Time<Self::In>,new_time:Time<Self::Out>); + fn get_offset(&self)->InnerTime; + fn set_offset(&mut self,offset:InnerTime); } -impl TimerState for Realtime{ +impl<In,Out> TimerState for Realtime<In,Out>{ + type In=In; + type Out=Out; fn identity()->Self{ - Self{offset:Time::ZERO} + Self::new(InnerTime::ZERO) } - fn get_time(&self,time:Time)->Time{ - time+self.offset + fn get_time(&self,time:Time<In>)->Time<Out>{ + time.coerce()+self.offset.coerce() } - fn set_time(&mut self,time:Time,new_time:Time){ - self.offset=new_time-time; + fn set_time(&mut self,time:Time<In>,new_time:Time<Out>){ + self.offset=new_time.coerce()-time.coerce(); } - fn get_offset(&self)->Time{ + fn get_offset(&self)->InnerTime{ self.offset } - fn set_offset(&mut self,offset:Time){ + fn set_offset(&mut self,offset:InnerTime){ self.offset=offset; } } -impl TimerState for Scaled{ +impl<In,Out> TimerState for Scaled<In,Out> + where Time<In>:Copy, +{ + type In=In; + type Out=Out; fn identity()->Self{ - Self{scale:Ratio64::ONE,offset:Time::ZERO} + Self::new(Ratio64::ONE,InnerTime::ZERO) } - fn get_time(&self,time:Time)->Time{ - self.scale(time)+self.offset + fn get_time(&self,time:Time<In>)->Time<Out>{ + (self.scale(time)+self.offset).coerce() } - fn set_time(&mut self,time:Time,new_time:Time){ - self.offset=new_time-self.scale(time); + fn set_time(&mut self,time:Time<In>,new_time:Time<Out>){ + self.offset=new_time.coerce()-self.scale(time); } - fn get_offset(&self)->Time{ + fn get_offset(&self)->InnerTime{ self.offset } - fn set_offset(&mut self,offset:Time){ + fn set_offset(&mut self,offset:InnerTime){ self.offset=offset; } } @@ -106,8 +133,10 @@ pub struct TimerFixed<T:TimerState,P:PauseState>{ } //scaled timer methods are generic across PauseState -impl<P:PauseState> TimerFixed<Scaled,P>{ - pub fn scaled(time:Time,new_time:Time,scale:Ratio64)->Self{ +impl<P:PauseState,In,Out> TimerFixed<Scaled<In,Out>,P> + where Time<In>:Copy, +{ + pub fn scaled(time:Time<In>,new_time:Time<Out>,scale:Ratio64)->Self{ let mut timer=Self{ state:Scaled::with_scale(scale), _paused:P::new(), @@ -118,14 +147,16 @@ impl<P:PauseState> TimerFixed<Scaled,P>{ pub const fn get_scale(&self)->Ratio64{ self.state.get_scale() } - pub fn set_scale(&mut self,time:Time,new_scale:Ratio64){ + pub fn set_scale(&mut self,time:Time<In>,new_scale:Ratio64){ self.state.set_scale(time,new_scale) } } //pause and unpause is generic across TimerState -impl<T:TimerState> TimerFixed<T,Paused>{ - pub fn into_unpaused(self,time:Time)->TimerFixed<T,Unpaused>{ +impl<T:TimerState> TimerFixed<T,Paused> + where Time<T::In>:Copy, +{ + pub fn into_unpaused(self,time:Time<T::In>)->TimerFixed<T,Unpaused>{ let new_time=self.time(time); let mut timer=TimerFixed{ state:self.state, @@ -135,8 +166,10 @@ impl<T:TimerState> TimerFixed<T,Paused>{ timer } } -impl<T:TimerState> TimerFixed<T,Unpaused>{ - pub fn into_paused(self,time:Time)->TimerFixed<T,Paused>{ +impl<T:TimerState> TimerFixed<T,Unpaused> + where Time<T::In>:Copy, +{ + pub fn into_paused(self,time:Time<T::In>)->TimerFixed<T,Paused>{ let new_time=self.time(time); let mut timer=TimerFixed{ state:self.state, @@ -149,7 +182,7 @@ impl<T:TimerState> TimerFixed<T,Unpaused>{ //the new constructor and time queries are generic across both impl<T:TimerState,P:PauseState> TimerFixed<T,P>{ - pub fn new(time:Time,new_time:Time)->Self{ + pub fn new(time:Time<T::In>,new_time:Time<T::Out>)->Self{ let mut timer=Self{ state:T::identity(), _paused:P::new(), @@ -166,15 +199,15 @@ impl<T:TimerState,P:PauseState> TimerFixed<T,P>{ pub fn into_state(self)->T{ self.state } - pub fn time(&self,time:Time)->Time{ + pub fn time(&self,time:Time<T::In>)->Time<T::Out>{ match P::IS_PAUSED{ - true=>self.state.get_offset(), + true=>self.state.get_offset().coerce(), false=>self.state.get_time(time), } } - pub fn set_time(&mut self,time:Time,new_time:Time){ + pub fn set_time(&mut self,time:Time<T::In>,new_time:Time<T::Out>){ match P::IS_PAUSED{ - true=>self.state.set_offset(new_time), + true=>self.state.set_offset(new_time.coerce()), false=>self.state.set_time(time,new_time), } } @@ -198,7 +231,11 @@ pub enum Timer<T:TimerState>{ Paused(TimerFixed<T,Paused>), Unpaused(TimerFixed<T,Unpaused>), } -impl<T:TimerState> Timer<T>{ +impl<T:TimerState> Timer<T> + where + T:Copy, + Time<T::In>:Copy, +{ pub fn from_state(state:T,paused:bool)->Self{ match paused{ true=>Self::Paused(TimerFixed::from_state(state)), @@ -211,32 +248,32 @@ impl<T:TimerState> Timer<T>{ Self::Unpaused(timer)=>(timer.into_state(),false), } } - pub fn paused(time:Time,new_time:Time)->Self{ + pub fn paused(time:Time<T::In>,new_time:Time<T::Out>)->Self{ Self::Paused(TimerFixed::new(time,new_time)) } - pub fn unpaused(time:Time,new_time:Time)->Self{ + pub fn unpaused(time:Time<T::In>,new_time:Time<T::Out>)->Self{ Self::Unpaused(TimerFixed::new(time,new_time)) } - pub fn time(&self,time:Time)->Time{ + pub fn time(&self,time:Time<T::In>)->Time<T::Out>{ match self{ Self::Paused(timer)=>timer.time(time), Self::Unpaused(timer)=>timer.time(time), } } - pub fn set_time(&mut self,time:Time,new_time:Time){ + pub fn set_time(&mut self,time:Time<T::In>,new_time:Time<T::Out>){ match self{ Self::Paused(timer)=>timer.set_time(time,new_time), Self::Unpaused(timer)=>timer.set_time(time,new_time), } } - pub fn pause(&mut self,time:Time)->Result<(),Error>{ + pub fn pause(&mut self,time:Time<T::In>)->Result<(),Error>{ *self=match *self{ Self::Paused(_)=>return Err(Error::AlreadyPaused), Self::Unpaused(timer)=>Self::Paused(timer.into_paused(time)), }; Ok(()) } - pub fn unpause(&mut self,time:Time)->Result<(),Error>{ + pub fn unpause(&mut self,time:Time<T::In>)->Result<(),Error>{ *self=match *self{ Self::Paused(timer)=>Self::Unpaused(timer.into_unpaused(time)), Self::Unpaused(_)=>return Err(Error::AlreadyUnpaused), @@ -249,7 +286,7 @@ impl<T:TimerState> Timer<T>{ Self::Unpaused(_)=>false, } } - pub fn set_paused(&mut self,time:Time,paused:bool)->Result<(),Error>{ + pub fn set_paused(&mut self,time:Time<T::In>,paused:bool)->Result<(),Error>{ match paused{ true=>self.pause(time), false=>self.unpause(time), @@ -257,14 +294,16 @@ impl<T:TimerState> Timer<T>{ } } //scaled timer methods are generic across PauseState -impl Timer<Scaled>{ +impl<In,Out> Timer<Scaled<In,Out>> + where Time<In>:Copy, +{ pub const fn get_scale(&self)->Ratio64{ match self{ Self::Paused(timer)=>timer.get_scale(), Self::Unpaused(timer)=>timer.get_scale(), } } - pub fn set_scale(&mut self,time:Time,new_scale:Ratio64){ + pub fn set_scale(&mut self,time:Time<In>,new_scale:Ratio64){ match self{ Self::Paused(timer)=>timer.set_scale(time,new_scale), Self::Unpaused(timer)=>timer.set_scale(time,new_scale), @@ -280,10 +319,15 @@ mod test{ Time::from_secs($s) }; } + + #[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)] + enum Parent{} + #[derive(Clone,Copy,Hash,Eq,PartialEq,PartialOrd,Debug)] + enum Calculated{} #[test] fn test_timerfixed_scaled(){ //create a paused timer that reads 0s - let timer=TimerFixed::<Scaled,Paused>::from_state(Scaled{scale:0.5f32.try_into().unwrap(),offset:sec!(0)}); + let timer=TimerFixed::<Scaled<Parent,Calculated>,Paused>::from_state(Scaled::new(0.5f32.try_into().unwrap(),sec!(0))); //the paused timer at 1 second should read 0s assert_eq!(timer.time(sec!(1)),sec!(0)); @@ -300,7 +344,7 @@ mod test{ #[test] fn test_timer()->Result<(),Error>{ //create a paused timer that reads 0s - let mut timer=Timer::<Realtime>::paused(sec!(0),sec!(0)); + let mut timer=Timer::<Realtime<Parent,Calculated>>::paused(sec!(0),sec!(0)); //the paused timer at 1 second should read 0s assert_eq!(timer.time(sec!(1)),sec!(0));