use std::time;
#[derive(Debug)]
pub struct Timer {
target_ticks: u16,
target_delta: time::Duration,
last_tick: time::Instant,
accumulated_delta: time::Duration,
has_ticked: bool,
}
impl Timer {
pub(crate) fn new(ticks_per_second: u16) -> Timer {
let (target_seconds, target_nanos) = match ticks_per_second {
0 => (std::u64::MAX, 0),
1 => (1, 0),
_ => (0, ((1.0 / ticks_per_second as f64) * 1e9) as u32),
};
Timer {
target_ticks: ticks_per_second,
target_delta: time::Duration::new(target_seconds, target_nanos),
last_tick: time::Instant::now(),
accumulated_delta: time::Duration::from_secs(0),
has_ticked: false,
}
}
pub(crate) fn update(&mut self) {
let now = time::Instant::now();
let diff = now - self.last_tick;
self.last_tick = now;
self.accumulated_delta += diff;
self.has_ticked = false;
}
pub(crate) fn tick(&mut self) -> bool {
if self.accumulated_delta >= self.target_delta {
self.accumulated_delta -= self.target_delta;
self.has_ticked = true;
true
} else {
false
}
}
pub fn has_ticked(&self) -> bool {
self.has_ticked
}
pub fn next_tick_proximity(&self) -> f32 {
let delta = self.accumulated_delta;
self.target_ticks as f32
* (delta.as_secs() as f32
+ (delta.subsec_micros() as f32 / 1_000_000.0))
}
}