use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct SharedClock(Arc<AtomicU64>);
impl Default for SharedClock {
fn default() -> Self {
Self::new()
}
}
impl SharedClock {
pub fn new() -> Self {
Self(Arc::new(AtomicU64::new(0)))
}
pub fn set_ns(&self, ns: u64) {
self.0.store(ns, Ordering::Relaxed);
}
pub fn position_s(&self) -> f64 {
self.0.load(Ordering::Relaxed) as f64 / 1e9
}
}
pub fn highlight_index(word_times: &[f64], position_s: f64) -> Option<usize> {
let mut found = None;
for (i, &t) in word_times.iter().enumerate() {
if t <= position_s {
found = Some(i);
} else {
break;
}
}
found
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn highlight_advances_with_clock() {
let times = [0.0, 0.5, 1.0, 1.5, 2.0]; assert_eq!(highlight_index(×, 0.0), Some(0));
assert_eq!(highlight_index(×, 0.4), Some(0));
assert_eq!(highlight_index(×, 0.5), Some(1));
assert_eq!(highlight_index(×, 1.24), Some(2));
assert_eq!(highlight_index(×, 2.0), Some(4));
assert_eq!(highlight_index(×, 5.0), Some(4)); }
#[test]
fn clock_is_shared_across_clone() {
let player_clock = SharedClock::new();
let ui_clock = player_clock.clone(); assert_eq!(ui_clock.position_s(), 0.0);
player_clock.set_ns(1_500_000_000); assert_eq!(ui_clock.position_s(), 1.5); }
}