1#[cfg(feature = "serde")]
2use serde::{Deserialize, Serialize};
3
4#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
10#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11pub struct UpdateArgs {
12 pub dt: Float,
14}
15
16impl UpdateArgs {
17 pub fn zero_dt() -> UpdateArgs {
19 Self { dt: 0.0 }
20 }
21}
22
23#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub enum Loop {
27 Update(UpdateArgs),
29}
30
31impl From<UpdateArgs> for Event {
32 fn from(args: UpdateArgs) -> Self {
33 Event::Loop(Loop::Update(args))
34 }
35}
36
37#[derive(Clone)]
39pub enum Event {
40 Loop(Loop),
44}
45impl Event {
46 pub fn zero_dt_args() -> Self {
48 UpdateArgs::zero_dt().into()
49 }
50}
51
52pub trait UpdateEvent: Sized {
54 fn from_update_args(args: &UpdateArgs, old_event: &Self) -> Option<Self>;
56 fn from_dt(dt: Float, old_event: &Self) -> Option<Self> {
58 UpdateEvent::from_update_args(&UpdateArgs { dt }, old_event)
59 }
60 fn update<U, F>(&self, f: F) -> Option<U>
62 where
63 F: FnMut(&UpdateArgs) -> U;
64 fn update_args(&self) -> Option<UpdateArgs> {
66 self.update(|args| *args)
67 }
68}
69
70impl UpdateEvent for Event {
71 fn from_update_args(args: &UpdateArgs, _old_event: &Self) -> Option<Self> {
72 Some(Event::Loop(Loop::Update(*args)))
73 }
74
75 fn update<U, F>(&self, mut f: F) -> Option<U>
76 where
77 F: FnMut(&UpdateArgs) -> U,
78 {
79 match *self {
80 Event::Loop(Loop::Update(ref args)) => Some(f(args)),
81 }
82 }
83}
84
85use std::time::Instant;
86
87use crate::Float;
88
89#[derive(Debug, Clone)]
93pub struct Timer {
94 start: Instant,
95 now: Instant,
96}
97
98impl Timer {
99 pub fn init_time() -> Timer {
101 let init = Instant::now();
102 Timer { start: init, now: init }
103 }
104
105 pub fn duration_since_start(&self) -> Float {
107 let new_now: Instant = Instant::now();
108 let duration = new_now.duration_since(self.start);
109 #[cfg(feature = "f32")]
110 return duration.as_secs_f32();
111 #[cfg(not(feature = "f32"))]
112 return duration.as_secs_f64();
113 }
114
115 pub fn get_dt(&mut self) -> Float {
117 let new_now: Instant = Instant::now();
118 let duration = new_now.duration_since(self.now);
119 self.now = new_now;
120 #[cfg(feature = "f32")]
121 return duration.as_secs_f32();
122 #[cfg(not(feature = "f32"))]
123 return duration.as_secs_f64();
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use std::thread::sleep;
131 use std::time::Duration;
132
133 #[test]
134 fn test_update_args() {
135 use Event;
136 use UpdateArgs;
137
138 let e: Event = UpdateArgs { dt: 0.0 }.into();
139 let _: Option<Event> = UpdateEvent::from_update_args(&UpdateArgs { dt: 1.0 }, &e);
140 }
141
142 #[test]
143 fn test_timer() {
144 let mut timer = Timer::init_time();
145 sleep(Duration::new(0, 0.1e+9 as u32));
146 let duration = timer.duration_since_start();
147 let dt = timer.get_dt();
148
149 assert!(duration < 1.0);
150 assert!(dt < 0.2);
151 assert!(dt >= 0.1);
152
153 sleep(Duration::new(0, 0.3e+9 as u32));
154 let duration = timer.duration_since_start();
155 let dt = timer.get_dt();
156
157 assert!(duration < 1.0);
158 assert!(duration > 0.3);
159 assert!(dt > 0.2);
160 assert!(dt < 0.4);
161 }
162}