use std::{thread, time::Duration};
use rayon::prelude::*;
pub use std::time::Instant;
pub fn spawn_delayed(delay: Duration, f: impl FnOnce() + Send + 'static) {
thread::spawn(move || {
thread::sleep(delay);
f();
});
}
pub fn spawn_interval(
period: Duration,
precise: bool,
mut tick: impl FnMut(u64) -> bool + Send + 'static,
) {
thread::spawn(move || {
let mut count: u64 = 0;
let mut next_tick = Instant::now() + period;
loop {
if precise {
let now = Instant::now();
if next_tick > now {
spin_sleep::sleep(next_tick - now);
}
} else {
thread::sleep(period);
}
count += 1;
if !tick(count) {
break;
}
if precise {
next_tick += period;
let now = Instant::now();
if next_tick < now {
let missed = ((now - next_tick).as_nanos() / period.as_nanos()) as u64;
count += missed;
next_tick = now + period;
}
}
}
});
}
pub fn par_for_each<T: Sync>(items: &[T], f: impl Fn(&T) + Send + Sync) {
items.par_iter().for_each(f);
}