use std::time::{Duration, Instant};
use crate::{
loop_context::EventLoopContext,
test_helper::{get_test_time, is_test_enabled},
};
pub fn get_current_time() -> Instant {
if is_test_enabled() {
get_test_time()
} else {
Instant::now()
}
}
pub struct ClockState {
enable: bool,
offset: Instant,
paused: Duration,
elapsed: Duration,
}
impl Default for ClockState {
fn default() -> Self {
Self {
enable: false,
offset: Instant::now(),
paused: Duration::default(),
elapsed: Duration::default(),
}
}
}
impl ClockState {
pub fn get_virtual_clock(&mut self) -> Duration {
let mut time = self.paused;
if self.enable {
time = self.offset.elapsed() - self.elapsed;
}
time
}
pub fn enable(&mut self) {
self.elapsed = self.offset.elapsed() - self.paused;
self.enable = true;
}
pub fn disable(&mut self) {
self.paused = self.offset.elapsed() - self.elapsed;
self.enable = false;
}
}
impl EventLoopContext {
pub fn get_virtual_clock(&self) -> Duration {
self.clock_state.lock().unwrap().get_virtual_clock()
}
pub fn enable_clock(&self) {
self.clock_state.lock().unwrap().enable();
}
pub fn disable_clock(&self) {
self.clock_state.lock().unwrap().disable();
}
}
#[cfg(test)]
mod test {
use std::{thread, time::Duration};
use super::ClockState;
#[test]
fn test_virtual_clock() {
let mut clock = ClockState::default();
clock.enable();
thread::sleep(Duration::from_secs(5));
let virtual_clock = clock.get_virtual_clock();
assert_eq!(virtual_clock.as_secs(), 5);
clock.disable();
thread::sleep(Duration::from_secs(10));
let virtual_clock = clock.get_virtual_clock();
assert_eq!(virtual_clock.as_secs(), 5);
clock.enable();
thread::sleep(Duration::from_secs(5));
let virtual_clock = clock.get_virtual_clock();
assert_eq!(virtual_clock.as_secs(), 10);
clock.disable();
thread::sleep(Duration::from_secs(10));
let virtual_clock = clock.get_virtual_clock();
assert_eq!(virtual_clock.as_secs(), 10);
clock.enable();
thread::sleep(Duration::from_secs(5));
let virtual_clock = clock.get_virtual_clock();
assert_eq!(virtual_clock.as_secs(), 15);
}
}