#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct UpdateArgs {
pub dt: Float,
}
impl UpdateArgs {
pub fn zero_dt() -> UpdateArgs {
Self { dt: 0.0 }
}
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Loop {
Update(UpdateArgs),
}
impl From<UpdateArgs> for Event {
fn from(args: UpdateArgs) -> Self {
Event::Loop(Loop::Update(args))
}
}
#[derive(Clone)]
pub enum Event {
Loop(Loop),
}
impl Event {
pub fn zero_dt_args() -> Self {
UpdateArgs::zero_dt().into()
}
}
pub trait UpdateEvent: Sized {
fn from_update_args(args: &UpdateArgs, old_event: &Self) -> Option<Self>;
fn from_dt(dt: Float, old_event: &Self) -> Option<Self> {
UpdateEvent::from_update_args(&UpdateArgs { dt }, old_event)
}
fn update<U, F>(&self, f: F) -> Option<U>
where
F: FnMut(&UpdateArgs) -> U;
fn update_args(&self) -> Option<UpdateArgs> {
self.update(|args| *args)
}
}
impl UpdateEvent for Event {
fn from_update_args(args: &UpdateArgs, _old_event: &Self) -> Option<Self> {
Some(Event::Loop(Loop::Update(*args)))
}
fn update<U, F>(&self, mut f: F) -> Option<U>
where
F: FnMut(&UpdateArgs) -> U,
{
match *self {
Event::Loop(Loop::Update(ref args)) => Some(f(args)),
}
}
}
use std::time::Instant;
use crate::Float;
#[derive(Debug, Clone)]
pub struct Timer {
start: Instant,
now: Instant,
}
impl Timer {
pub fn init_time() -> Timer {
let init = Instant::now();
Timer { start: init, now: init }
}
pub fn duration_since_start(&self) -> Float {
let new_now: Instant = Instant::now();
let duration = new_now.duration_since(self.start);
#[cfg(feature = "f32")]
return duration.as_secs_f32();
#[cfg(not(feature = "f32"))]
return duration.as_secs_f64();
}
pub fn get_dt(&mut self) -> Float {
let new_now: Instant = Instant::now();
let duration = new_now.duration_since(self.now);
self.now = new_now;
#[cfg(feature = "f32")]
return duration.as_secs_f32();
#[cfg(not(feature = "f32"))]
return duration.as_secs_f64();
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::thread::sleep;
use std::time::Duration;
#[test]
fn test_update_args() {
use Event;
use UpdateArgs;
let e: Event = UpdateArgs { dt: 0.0 }.into();
let _: Option<Event> = UpdateEvent::from_update_args(&UpdateArgs { dt: 1.0 }, &e);
}
#[test]
fn test_timer() {
let mut timer = Timer::init_time();
sleep(Duration::new(0, 0.1e+9 as u32));
let duration = timer.duration_since_start();
let dt = timer.get_dt();
assert!(duration < 1.0);
assert!(dt < 0.2);
assert!(dt >= 0.1);
sleep(Duration::new(0, 0.3e+9 as u32));
let duration = timer.duration_since_start();
let dt = timer.get_dt();
assert!(duration < 1.0);
assert!(duration > 0.3);
assert!(dt > 0.2);
assert!(dt < 0.4);
}
}