patica/
clock.rs

1use serde::{Deserialize, Serialize};
2use std::{num::NonZeroU8, time::Duration};
3
4#[derive(
5    Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize,
6)]
7pub struct Ticks(u32);
8
9impl Ticks {
10    pub const fn new(n: u32) -> Self {
11        Self(n)
12    }
13
14    pub const fn get(self) -> u32 {
15        self.0
16    }
17
18    pub fn tick_delta(&mut self, delta: i32) {
19        if delta < 0 {
20            self.0 = self.0.saturating_sub(delta.unsigned_abs());
21        } else {
22            self.0 = self.0.saturating_add(delta as u32);
23        }
24    }
25
26    pub fn tick(&mut self) {
27        self.tick_delta(1);
28    }
29}
30
31#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
32pub struct Time {
33    pub ticks: Ticks,
34    pub fps: NonZeroU8, // TODO: Fps
35}
36
37impl Time {
38    pub const DEFAULT_FPS: u8 = 30;
39
40    pub const fn new(ticks: Ticks, fps: NonZeroU8) -> Self {
41        Self { ticks, fps }
42    }
43
44    pub fn duration(self) -> Duration {
45        Duration::from_secs(self.ticks.0 as u64) / self.fps.get() as u32
46    }
47}
48
49impl Default for Time {
50    fn default() -> Self {
51        Self::new(
52            Ticks::new(0),
53            NonZeroU8::new(Self::DEFAULT_FPS).expect("unreachable"),
54        )
55    }
56}