use std::collections::VecDeque;
use std::time::Instant;
pub struct FpsCounter {
frame_times: VecDeque<Instant>,
window_size: usize,
}
impl FpsCounter {
pub fn new() -> Self {
Self::with_window_size(30) }
pub fn with_window_size(window_size: usize) -> Self {
Self {
frame_times: VecDeque::with_capacity(window_size + 1),
window_size,
}
}
pub fn update(&mut self) {
let now = Instant::now();
self.frame_times.push_back(now);
if self.frame_times.len() > self.window_size {
self.frame_times.pop_front();
}
}
pub fn fps(&self) -> f32 {
if self.frame_times.len() < 2 {
return 0.0;
}
if let (Some(first), Some(last)) = (self.frame_times.front(), self.frame_times.back()) {
let duration = last.duration_since(*first);
if duration.as_secs_f32() > 0.0 {
return (self.frame_times.len() - 1) as f32 / duration.as_secs_f32();
}
}
0.0
}
}
impl Default for FpsCounter {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_fps_counter() {
let mut fps_counter = super::FpsCounter::new();
fps_counter.update();
fps_counter.update();
fps_counter.update();
}
}