summaryrefslogtreecommitdiff
path: root/graphics/src/timer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/src/timer.rs')
-rw-r--r--graphics/src/timer.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/graphics/src/timer.rs b/graphics/src/timer.rs
new file mode 100644
index 0000000..8310776
--- /dev/null
+++ b/graphics/src/timer.rs
@@ -0,0 +1,67 @@
+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 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
+ }
+}