use std::thread;
use std::ops::Deref;
use std::time::{Duration, Instant};
use crate::error;
use channel::{self, Receiver, Sender, SendError};
pub struct Timer {
receiver: Receiver<Event>,
refresh: Sender<u64>,
}
#[derive(Debug)]
pub enum Event {
Refresh,
Heartbeat,
Save,
}
#[derive(Copy, Clone, Debug)]
pub struct Settings {
pub save: u64,
pub heartbeat: u64,
}
impl Timer {
pub fn spawn(settings: Settings) -> error::Result<Self> {
let (sender, receiver) = channel::unbounded();
let (refresh, refresher) = channel::unbounded();
{
let sender = sender.clone();
thread::spawn(move || {
while let Ok(value) = refresher.recv() {
thread::sleep(Duration::from_millis(value));
sender.send(Event::Refresh).unwrap();
}
});
}
thread::spawn(move || {
let mut save = Instant::now();
let mut beat = Instant::now();
loop {
thread::sleep(Duration::from_secs(1));
if save.elapsed().as_secs() >= settings.save {
save = Instant::now();
sender.send(Event::Save).unwrap();
}
if beat.elapsed().as_secs() >= settings.heartbeat {
beat = Instant::now();
sender.send(Event::Heartbeat).unwrap();
}
}
});
Ok(Timer { receiver, refresh })
}
pub fn refresh(&self, value: u64) -> Result<(), SendError<u64>> {
self.refresh.send(value)
}
}
impl Deref for Timer {
type Target = Receiver<Event>;
fn deref(&self) -> &Self::Target {
&self.receiver
}
}