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
use amethyst_core::{
    ecs::prelude::{DispatcherBuilder, Read, System, World, Write},
    timing::{duration_to_nanos, Time},
    SystemBundle,
};
use amethyst_error::Error;
use crate::circular_buffer::CircularBuffer;
#[cfg(feature = "profiler")]
use thread_profiler::profile_scope;
#[derive(Debug)]
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().is_empty() {
            return 0.0;
        }
        1.0e9 * self.buf.queue().len() as f32 / self.sum as f32
    }
}
#[derive(Debug)]
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) {
        #[cfg(feature = "profiler")]
        profile_scope!("fps_counter_system");
        counter.push(duration_to_nanos(time.delta_real_time()));
        
        log::debug!(
            "Cur FPS: {}, Sampled: {}",
            counter.frame_fps(),
            counter.sampled_fps()
        );
    }
}
#[derive(Default, Debug)]
pub struct FpsCounterBundle;
impl<'a, 'b> SystemBundle<'a, 'b> for FpsCounterBundle {
    fn build(
        self,
        _world: &mut World,
        builder: &mut DispatcherBuilder<'a, 'b>,
    ) -> Result<(), Error> {
        builder.add(FpsCounterSystem, "fps_counter_system", &[]);
        Ok(())
    }
}