-
Notifications
You must be signed in to change notification settings - Fork 0
/
timer.rs
126 lines (107 loc) · 3.87 KB
/
timer.rs
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
118
119
120
121
122
123
124
125
126
use std::time::{Duration, Instant};
#[cfg(feature = "editor")]
use rust_rocket;
#[cfg(feature = "editor")]
type Rocket = rust_rocket::client::RocketClient;
#[cfg(not(feature = "editor"))]
type Rocket = ();
#[cfg(feature = "editor")]
const BPS: f32 = 10.0;
#[derive(Debug)]
pub struct Timer {
pub t: f32, /// Simulation time (starts from 0 and does not advance while on pause).
pub now: Instant, /// Wall time, use instead of Instant::now() for frame-consistent time.
prev_time: Instant, /// Time of previous frame.
frame: u32, /// Frame count, starts from 0 and does not increment while on pause.
last_report_time: Instant,
last_report_frame: u32,
accum_draw_time: Duration,
accum_idle_time: Duration,
pub pause: bool,
pub rocket: Option<Rocket>,
}
impl Timer {
pub fn new() -> Self {
let now = Instant::now();
Timer {
t: 0.0,
now,
prev_time: now,
frame: 0,
last_report_time: now,
last_report_frame: 0,
accum_draw_time: Duration::default(),
accum_idle_time: Duration::default(),
pause: false,
rocket: Timer::init_rocket(),
}
}
// To be called once per frame, just before rendering
pub fn update(&mut self) {
self.prev_time = self.now;
self.now = Instant::now();
if !self.pause {
// Increment simulation time
let frame_time = self.now - self.prev_time;
self.t += frame_time.as_secs_f32();
self.frame += 1;
}
self.poll_rocket();
self.maybe_report();
}
#[cfg(not(feature = "logging"))]
fn maybe_report(&mut self) {}
#[cfg(feature = "logging")]
fn maybe_report(&mut self) {
if self.now - self.last_report_time > Duration::from_secs(5) {
self.report(self.now);
self.last_report_time = self.now;
self.last_report_frame = self.frame;
self.accum_draw_time = Duration::new(0, 0);
self.accum_idle_time = Duration::new(0, 0);
}
}
#[cfg(feature = "logging")]
fn report(&self, now: Instant) {
fn millis(d : Duration) -> f32 {
d.as_secs() as f32 * 1e3 + d.subsec_nanos() as f32 / 1e6
}
let frames_done = self.frame - self.last_report_frame;
let fps = frames_done as f32 / (now - self.last_report_time).as_secs() as f32;
let avg_draw_time = millis(self.accum_draw_time / frames_done);
let avg_idle_time = millis(self.accum_idle_time / frames_done);
println!("fps={:.1} draw={:.1}ms idle={:.1}ms", fps, avg_draw_time, avg_idle_time);
}
#[cfg(not(feature = "editor"))]
fn init_rocket() -> Option<Rocket> { None }
#[cfg(not(feature = "editor"))]
fn poll_rocket(&mut self) {}
#[cfg(feature = "editor")]
fn init_rocket() -> Option<Rocket> {
Rocket::new().ok()
}
#[cfg(feature = "editor")]
fn poll_rocket(&mut self) {
use rust_rocket::client::Event;
match self.rocket {
Some(ref mut rocket) => {
let current_row = (self.t * BPS) as u32;
if let Some(event) = rocket.poll_events().unwrap() {
match event {
Event::SetRow(row) => {
println!("SetRow (row: {:?})", row);
self.t = row as f32 / BPS;
}
Event::Pause(_) => {
let track1 = rocket.get_track_mut("test").unwrap();
println!("Pause (value: {:?}) (row: {:?})", track1.get_value(current_row as f32), current_row);
}
_ => (),
}
println!("{:?}", event);
}
}
None => ()
}
}
}