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
use amethyst_core::specs::prelude::{DispatcherBuilder, Read, System, Write};
use amethyst_core::timing::{duration_to_nanos, Time};
use amethyst_core::{Result, SystemBundle};
use circular_buffer::CircularBuffer;
pub struct FPSCounter {
buf: CircularBuffer<u64>,
sum: u64,
}
impl Default for FPSCounter {
fn default() -> Self {
FPSCounter::new(20)
}
}
impl FPSCounter {
pub fn new(samplesize: usize) -> FPSCounter {
FPSCounter {
buf: CircularBuffer::<u64>::new(samplesize),
sum: 0,
}
}
pub fn push(&mut self, elem: u64) {
self.sum += elem;
if let Some(front) = self.buf.push(elem) {
self.sum -= front;
}
}
pub fn frame_fps(&self) -> f32 {
if let Some(back) = self.buf.queue().back() {
return 1.0e9 / *back as f32;
}
0.0
}
pub fn sampled_fps(&self) -> f32 {
if self.sum == 0 || self.buf.queue().len() == 0 {
return 0.0;
}
1.0e9 * self.buf.queue().len() as f32 / self.sum as f32
}
}
pub struct FPSCounterSystem;
impl<'a> System<'a> for FPSCounterSystem {
type SystemData = (Read<'a, Time>, Write<'a, FPSCounter>);
fn run(&mut self, (time, mut counter): Self::SystemData) {
counter.push(duration_to_nanos(time.delta_real_time()));
}
}
#[derive(Default)]
pub struct FPSCounterBundle;
impl<'a, 'b> SystemBundle<'a, 'b> for FPSCounterBundle {
fn build(self, builder: &mut DispatcherBuilder<'a, 'b>) -> Result<()> {
builder.add(FPSCounterSystem, "fps_counter_system", &[]);
Ok(())
}
}