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
use std::time::{Instant, Duration};
use std::thread::sleep;
pub struct FPSController {
fps: f64,
frame_time: f64,
frame_count: u64,
time: Instant,
extra_time: f64,
}
impl FPSController {
pub fn new() -> Self {
Self::from_fps(60)
}
pub fn from_fps(fps: u64) -> Self {
let fps = fps as f64;
FPSController {
fps,
frame_time: 1.0 / fps,
frame_count: 0,
time: Instant::now(),
extra_time: 0.0
}
}
pub fn tick(&mut self) -> u64 {
self.frame_count += 1;
self.frame_count
}
pub fn run<F: FnMut(u64)>(&mut self, mut update: F) -> f64 {
let time = self.time.elapsed();
let time_as_millis = time.subsec_millis();
let time_as_secs = time.as_secs();
let current_time = time_as_secs as f64 + time_as_millis as f64 / 1000.0;
let true_time = self.frame_count as f64 / self.fps as f64;
let sleep_time = true_time - current_time;
if sleep_time >= 0.0 {
if sleep_time > self.extra_time {
let sleep_time = sleep_time - self.extra_time;
self.extra_time = 0.0;
sleep(Duration::from_millis((sleep_time * 1000.0) as u64));
} else {
self.extra_time -= sleep_time;
}
} else {
self.extra_time += -sleep_time;
while self.extra_time >= self.frame_time {
self.frame_count += 1;
update(self.frame_count);
self.extra_time -= self.frame_time;
}
}
let time = self.time.elapsed();
let time_as_secs = time.as_secs() as f64 + time.subsec_millis() as f64 / 1000.0;
let fps = self.frame_count as f64 / time_as_secs;
fps
}
}