Skip to main content

oxihuman_core/
clock_source.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5/// A deterministic clock source for simulation and testing.
6#[allow(dead_code)]
7#[derive(Debug, Clone, Copy)]
8pub struct ClockSource {
9    current_time: f64,
10    delta: f64,
11    frame: u64,
12    paused: bool,
13    speed: f64,
14}
15
16#[allow(dead_code)]
17impl ClockSource {
18    pub fn new() -> Self {
19        Self {
20            current_time: 0.0,
21            delta: 1.0 / 60.0,
22            frame: 0,
23            paused: false,
24            speed: 1.0,
25        }
26    }
27
28    pub fn with_delta(delta: f64) -> Self {
29        Self {
30            delta,
31            ..Self::new()
32        }
33    }
34
35    pub fn advance(&mut self) {
36        if !self.paused {
37            self.current_time += self.delta * self.speed;
38            self.frame += 1;
39        }
40    }
41
42    pub fn advance_by(&mut self, dt: f64) {
43        if !self.paused {
44            self.current_time += dt * self.speed;
45            self.frame += 1;
46        }
47    }
48
49    pub fn time(&self) -> f64 {
50        self.current_time
51    }
52
53    pub fn delta(&self) -> f64 {
54        self.delta
55    }
56
57    pub fn frame(&self) -> u64 {
58        self.frame
59    }
60
61    pub fn set_speed(&mut self, speed: f64) {
62        self.speed = speed;
63    }
64
65    pub fn speed(&self) -> f64 {
66        self.speed
67    }
68
69    pub fn pause(&mut self) {
70        self.paused = true;
71    }
72
73    pub fn resume(&mut self) {
74        self.paused = false;
75    }
76
77    pub fn is_paused(&self) -> bool {
78        self.paused
79    }
80
81    pub fn reset(&mut self) {
82        self.current_time = 0.0;
83        self.frame = 0;
84    }
85}
86
87impl Default for ClockSource {
88    fn default() -> Self {
89        Self::new()
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96
97    #[test]
98    fn test_new() {
99        let c = ClockSource::new();
100        assert!((c.time()).abs() < 1e-12);
101        assert_eq!(c.frame(), 0);
102    }
103
104    #[test]
105    fn test_advance() {
106        let mut c = ClockSource::with_delta(0.5);
107        c.advance();
108        assert!((c.time() - 0.5).abs() < 1e-12);
109        assert_eq!(c.frame(), 1);
110    }
111
112    #[test]
113    fn test_advance_by() {
114        let mut c = ClockSource::new();
115        c.advance_by(2.0);
116        assert!((c.time() - 2.0).abs() < 1e-12);
117    }
118
119    #[test]
120    fn test_paused() {
121        let mut c = ClockSource::with_delta(1.0);
122        c.pause();
123        c.advance();
124        assert!((c.time()).abs() < 1e-12);
125        assert_eq!(c.frame(), 0);
126    }
127
128    #[test]
129    fn test_resume() {
130        let mut c = ClockSource::with_delta(1.0);
131        c.pause();
132        c.resume();
133        c.advance();
134        assert!((c.time() - 1.0).abs() < 1e-12);
135    }
136
137    #[test]
138    fn test_speed() {
139        let mut c = ClockSource::with_delta(1.0);
140        c.set_speed(2.0);
141        c.advance();
142        assert!((c.time() - 2.0).abs() < 1e-12);
143    }
144
145    #[test]
146    fn test_reset() {
147        let mut c = ClockSource::with_delta(1.0);
148        c.advance();
149        c.advance();
150        c.reset();
151        assert!((c.time()).abs() < 1e-12);
152        assert_eq!(c.frame(), 0);
153    }
154
155    #[test]
156    fn test_delta() {
157        let c = ClockSource::with_delta(0.01);
158        assert!((c.delta() - 0.01).abs() < 1e-12);
159    }
160
161    #[test]
162    fn test_multiple_advances() {
163        let mut c = ClockSource::with_delta(0.25);
164        for _ in 0..4 {
165            c.advance();
166        }
167        assert!((c.time() - 1.0).abs() < 1e-12);
168        assert_eq!(c.frame(), 4);
169    }
170
171    #[test]
172    fn test_default() {
173        let c = ClockSource::default();
174        assert!(!c.is_paused());
175        assert!((c.speed() - 1.0).abs() < 1e-12);
176    }
177}