use std::sync::Arc;
use web_time::{SystemTime, UNIX_EPOCH};
pub trait Clock: Send + Sync {
fn now_unix_secs(&self) -> u64;
fn now_unix_secs_f64(&self) -> f64;
}
#[derive(Debug, Default, Clone, Copy)]
pub struct SystemClock;
impl SystemClock {
pub fn arc() -> Arc<dyn Clock> {
Arc::new(Self)
}
}
impl Clock for SystemClock {
fn now_unix_secs(&self) -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
}
fn now_unix_secs_f64(&self) -> f64 {
let d = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default();
d.as_secs_f64()
}
}
#[derive(Debug, Default, Clone)]
pub struct ManualClock {
inner: Arc<std::sync::Mutex<f64>>,
}
impl ManualClock {
pub fn new(secs: u64) -> Self {
Self {
inner: Arc::new(std::sync::Mutex::new(secs as f64)),
}
}
pub fn set(&self, secs: u64) {
if let Ok(mut guard) = self.inner.lock() {
*guard = secs as f64;
}
}
pub fn tick(&self, delta: std::time::Duration) {
if let Ok(mut guard) = self.inner.lock() {
*guard += delta.as_secs_f64();
}
}
pub fn arc(&self) -> Arc<dyn Clock> {
Arc::new(self.clone())
}
}
impl Clock for ManualClock {
fn now_unix_secs(&self) -> u64 {
self.inner.lock().map(|v| *v as u64).unwrap_or_default()
}
fn now_unix_secs_f64(&self) -> f64 {
self.inner.lock().map(|v| *v).unwrap_or_default()
}
}