This commit is contained in:
Quaternions 2025-01-07 21:46:30 -08:00
parent 86cf7e74b1
commit 36ba73a892

View File

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