1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use chrono;
use clock::{GameTime, GameClock};
use framerate::counter::FrameCount;
use step::TimeStep;
#[derive(Debug)]
pub struct FrameRunner<C: FrameCount> {
clock: GameClock,
counter: C,
}
impl<C> FrameRunner<C>
where
C: FrameCount,
{
pub fn new(clock: GameClock, counter: C) -> FrameRunner<C> {
FrameRunner { clock, counter }
}
pub fn clock(&self) -> &GameClock {
&self.clock
}
pub fn clock_mut(&mut self) -> &mut GameClock {
&mut self.clock
}
pub fn counter(&self) -> &C {
&self.counter
}
pub fn counter_mut(&mut self) -> &mut C {
&mut self.counter
}
pub fn tick<T: TimeStep>(&mut self, time_step: &T) -> GameTime {
let time = self.clock.tick(time_step);
self.counter.tick(&time);
time
}
pub fn tick_with_wall_time<T: TimeStep>(
&mut self,
time_step: &T,
frame_start: chrono::DateTime<chrono::Local>,
) -> GameTime {
let time = self.clock.tick_with_wall_time(time_step, frame_start);
self.counter.tick(&time);
time
}
pub fn do_frame<T, F>(&mut self, time_step: &T, frame_fn: F)
where
T: TimeStep,
F: FnOnce(GameTime),
{
let time = self.tick(time_step);
frame_fn(time);
self.clock.sleep_remaining(&self.counter);
}
}
#[cfg(test)]
mod tests {
use super::*;
use framerate::{counter, sample};
use step;
use float_duration::FloatDuration;
#[test]
fn test_runner() {
let clock = GameClock::new();
let count =
counter::FrameCounter::new(20.0, sample::RunningAverageSampler::with_max_samples(20));
let mut runner = FrameRunner::new(clock, count);
for i in 0..10 {
runner.do_frame(
&step::ConstantStep::new(FloatDuration::milliseconds(25.0)),
|time| {
assert_eq!(time.elapsed_game_time(), FloatDuration::milliseconds(25.0));
relative_eq!(
time.total_game_time(),
FloatDuration::milliseconds(25.0) * (i + 1) as f64,
epsilon = 1e-8
);
},
);
}
}
}