use std::time::{Duration, Instant};
use crate::AdjustmentSettings;
#[derive(Clone)]
pub struct Clock<A: AdjustmentSettings + Clone> {
base: Instant,
offset: Duration,
target: Duration,
adjustment_settings: A,
}
impl<A: AdjustmentSettings + Clone> Clock<A> {
pub fn new(start_time: Instant, adjustment_settings: A) -> Self {
Clock {
base: start_time,
offset: Duration::ZERO,
target: Duration::ZERO,
adjustment_settings,
}
}
pub fn set_target(&mut self, now: Instant, target: Duration) {
self.offset = self.elapsed(now);
self.base = now;
self.target = target;
}
pub fn elapsed(&self, now: Instant) -> Duration {
let time_since_base = now.duration_since(self.base);
let unadjusted = time_since_base + self.offset;
let current_target = time_since_base + self.target;
let max_delta = Duration::from_secs_f64(
time_since_base.as_secs_f64() * self.adjustment_settings.rate(),
);
if current_target >= unadjusted {
Duration::min(current_target, unadjusted + max_delta)
} else {
Duration::max(current_target, unadjusted - max_delta)
}
}
}