use crate::time::TimeSource;
use std::sync::{Arc, Mutex};
use std::time::{Duration, SystemTime};
#[derive(Debug, Clone)]
pub struct ManualTimeSource {
pub(super) start_time: SystemTime,
pub(super) log: Arc<Mutex<Vec<Duration>>>,
}
impl ManualTimeSource {
pub fn seconds_since_unix_epoch(&self) -> f64 {
self.now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs_f64()
}
pub fn new(start_time: SystemTime) -> ManualTimeSource {
Self {
start_time,
log: Default::default(),
}
}
pub fn advance(&self, duration: Duration) -> SystemTime {
let mut log = self.log.lock().unwrap();
log.push(duration);
self._now(&log)
}
fn _now(&self, log: &[Duration]) -> SystemTime {
self.start_time + log.iter().sum::<Duration>()
}
pub fn set_time(&self, time: SystemTime) {
let mut log = self.log.lock().unwrap();
let now = self._now(&log);
if time < now {
panic!("Cannot move time backwards!");
}
log.push(time.duration_since(now).unwrap());
}
}
impl TimeSource for ManualTimeSource {
fn now(&self) -> SystemTime {
self._now(&self.log.lock().unwrap())
}
}