use crossbeam_channel::{select, tick};
use std::time::Duration;
use crate::mailbox::Mailbox;
use crate::worker_thread::WorkerThread;
pub struct Timer<Message: Clone + Send + 'static> {
worker: Option<WorkerThread>,
message: Message,
interval: Duration,
}
impl<T: Clone + Send + 'static> Timer<T> {
pub fn new(interval: Duration, message: T) -> Self {
Self {
worker: None,
message,
interval,
}
}
pub fn start(&mut self, mailbox: Mailbox<T>) {
if self.worker.is_some() {
return;
}
let interval = self.interval;
let message = self.message.clone();
let worker = WorkerThread::spawn(move |done| {
let ticker = tick(interval);
loop {
let message = message.clone();
select! {
recv(ticker) -> _ => {
if mailbox.send(message).is_err() {
break;
}
}
recv(done) -> _ => {
break;
}
}
}
});
self.worker = Some(worker);
}
pub fn stop(&mut self) {
if let Some(worker) = self.worker.take() {
worker.close();
}
}
}