use std::{ ops::{Add, Div, Mul}, time::{Duration, Instant}, }; /// How often to update the fps interval on screen const FPS_INTERVAL: Duration = Duration::from_millis(250); /// How much to smooth he `delta_avg` amount (`AVG_RATIO`:1) const AVG_RATIO: u32 = 10; /// Keeps track of frame intervals and FPS pub struct Timer { /// Last time updated previous: Instant, /// Current time now: Instant, /// Rolling delta time average delta_avg: Duration, /// Computed fps fps: f64, /// Last time the fps was updated fps_time: Instant, /// Frame count count: u32, } impl Timer { pub fn new() -> Self { let now = Instant::now(); Self { previous: now, now, delta_avg: Duration::ZERO, fps: 0.0, fps_time: now, count: 0, } } pub fn update(&mut self) { self.previous = self.now; self.now = Instant::now(); self.delta_avg = self .delta_avg .mul(AVG_RATIO) .add(self.delta_time()) .div(AVG_RATIO + 1); if (self.now - self.fps_time) > FPS_INTERVAL { self.fps = 1.0 / self.delta_avg.as_secs_f64(); self.fps_time = self.now; } self.count += 1; } pub const fn get_frame(&self) -> u32 { self.count } #[expect(clippy::cast_possible_truncation)] pub fn get_fps(&self) -> u32 { self.fps.ceil() as u32 } pub fn delta_time(&self) -> Duration { self.now - self.previous } }