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, }
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}