use crate::ui_state::Clock;
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
#[derive(Clone)]
pub(crate) struct FakeClock {
at: Arc<Mutex<Instant>>,
origin: Instant,
lurch: Duration,
}
impl FakeClock {
pub(crate) fn new() -> Self {
let origin = Instant::now();
Self {
at: Arc::new(Mutex::new(origin)),
origin,
lurch: Duration::ZERO,
}
}
pub(crate) fn lurching(lurch: Duration) -> Self {
Self {
lurch,
..Self::new()
}
}
pub(crate) fn handle(&self) -> Self {
Self {
at: Arc::clone(&self.at),
origin: self.origin,
lurch: self.lurch,
}
}
pub(crate) fn arc(&self) -> Arc<dyn Clock> {
Arc::new(self.handle())
}
pub(crate) fn advance(&self, delta: Duration) {
*self
.at
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner) += delta;
}
}
impl Clock for FakeClock {
fn now(&self) -> Instant {
let mut at = self
.at
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
let read = *at;
*at += self.lurch;
read
}
fn stamp(&self) -> String {
"TS".to_string()
}
fn unix(&self) -> i64 {
let at = *self
.at
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
i64::try_from(at.saturating_duration_since(self.origin).as_secs()).unwrap_or(i64::MAX)
}
}