use std::{
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
thread::{self, JoinHandle},
time::Duration,
};
use winit::event_loop::EventLoopProxy;
#[derive(Debug)]
pub struct RequestNextFrame;
pub struct Animator {
handle: Option<JoinHandle<()>>,
is_running: Arc<AtomicBool>,
}
impl Animator {
pub fn new(proxy: EventLoopProxy<RequestNextFrame>, delays: &[f64]) -> Self {
let is_running = Arc::new(AtomicBool::new(true));
let should_run = Arc::clone(&is_running);
let delays = delays.to_vec();
let handle = thread::spawn(move || {
'outer: while should_run.load(Ordering::SeqCst) {
for delay in &delays {
thread::sleep(Duration::from_secs_f64(*delay));
if proxy.send_event(RequestNextFrame).is_err() {
break 'outer;
}
}
}
});
Self {
is_running,
handle: Some(handle),
}
}
}
impl Drop for Animator {
fn drop(&mut self) {
self.is_running.store(false, Ordering::SeqCst);
self.handle.take().unwrap().join().unwrap();
}
}