use cranpose_foundation::velocity_tracker::ASSUME_STOPPED_MS;
use web_time::{Duration, Instant};
const HELD_BACK: Duration = Duration::from_micros(250);
const FIRST_GAP_MS: i64 = 8;
const LONGEST_OWN_GAP_MS: i64 = 20;
pub(super) struct ArrivalClock {
last_handled: Option<Instant>,
gap_ms: i64,
}
impl Default for ArrivalClock {
fn default() -> Self {
Self {
last_handled: None,
gap_ms: FIRST_GAP_MS,
}
}
}
impl ArrivalClock {
pub(super) fn sample_ms(&mut self, now: Instant, start: Instant, last_ms: Option<i64>) -> i64 {
let held_back = self
.last_handled
.replace(now)
.is_some_and(|before| now.saturating_duration_since(before) < HELD_BACK);
let elapsed = now.saturating_duration_since(start).as_millis();
let elapsed_ms = i64::try_from(elapsed).unwrap_or(i64::MAX);
let Some(last_ms) = last_ms else {
return elapsed_ms;
};
let gap_ms = elapsed_ms - last_ms;
if held_back || gap_ms <= 0 {
return last_ms + self.gap_ms;
}
if gap_ms <= LONGEST_OWN_GAP_MS {
self.gap_ms = gap_ms;
}
last_ms + gap_ms.min(ASSUME_STOPPED_MS)
}
}