diff --git a/src/lib.rs b/src/lib.rs index 9796082..ff3601a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod bvh; pub mod map; +pub mod run; pub mod aabb; pub mod model; pub mod timer; diff --git a/src/run.rs b/src/run.rs new file mode 100644 index 0000000..1f6123a --- /dev/null +++ b/src/run.rs @@ -0,0 +1,103 @@ +use crate::timer::{TimerFixed,Realtime,Paused,Unpaused}; +use crate::integer::Time; + +#[derive(Clone,Debug)] +pub enum FlagReason{ + Anticheat, + StyleChange, + Clock, + Pause, + Flying, + Gravity, + Timescale, + TimeTravel, + Teleport, +} +impl ToString for FlagReason{ + fn to_string(&self)->String{ + match self{ + FlagReason::Anticheat=>"Passed through anticheat zone.", + FlagReason::StyleChange=>"Changed style.", + FlagReason::Clock=>"Incorrect clock. (This can be caused by internet hiccups)", + FlagReason::Pause=>"Pausing is not allowed in this style.", + FlagReason::Flying=>"Flying is not allowed in this style.", + FlagReason::Gravity=>"Gravity modification is not allowed in this style.", + FlagReason::Timescale=>"Timescale is not allowed in this style.", + FlagReason::TimeTravel=>"Time travel is not allowed in this style.", + FlagReason::Teleport=>"Illegal teleport.", + }.to_owned() + } +} + +#[derive(Debug)] +pub enum Error{ + NotStarted, + AlreadyStarted, + AlreadyFinished, +} +impl std::fmt::Display for Error{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for Error{} + +#[derive(Clone,Debug)] +enum RunState{ + Created, + Started{timer:TimerFixed}, + Finished{timer:TimerFixed}, +} + +#[derive(Clone,Debug)] +pub struct Run{ + state:RunState, + flagged:Option, +} + +impl Run{ + pub fn new()->Self{ + Self{ + state:RunState::Created, + flagged:None, + } + } + pub fn time(&self,time:Time)->Time{ + match &self.state{ + RunState::Created=>Time::ZERO, + RunState::Started{timer}=>timer.time(time), + RunState::Finished{timer}=>timer.time(time), + } + } + pub fn start(&mut self,time:Time)->Result<(),Error>{ + match &self.state{ + RunState::Created=>{ + self.state=RunState::Started{ + timer:TimerFixed::new(time,Time::ZERO), + }; + Ok(()) + }, + RunState::Started{..}=>Err(Error::AlreadyStarted), + RunState::Finished{..}=>Err(Error::AlreadyFinished), + } + } + pub fn finish(&mut self,time:Time)->Result<(),Error>{ + //this uses Copy + match &self.state{ + RunState::Created=>Err(Error::NotStarted), + RunState::Started{timer}=>{ + self.state=RunState::Finished{ + timer:timer.into_paused(time), + }; + Ok(()) + }, + RunState::Finished{..}=>Err(Error::AlreadyFinished), + } + } + pub fn flag(&mut self,flag_reason:FlagReason){ + //don't replace the first reason the run was flagged + if self.flagged.is_none(){ + self.flagged=Some(flag_reason); + } + } +}