use super::global::{CallBackState, EventHandle};
use super::GLOBAL;
use std::sync::Arc;
use std::time::{Duration, Instant};
pub struct Timer<T>
where
T: Fn() -> Duration + 'static,
{
event_handle: EventHandle,
tick: Arc<T>,
}
impl<T> Timer<T>
where
T: Fn() -> Duration + 'static,
{
pub fn start<F>(delay: Duration, tick: T, func: F) -> Timer<T>
where
F: Fn() -> () + 'static,
{
let tick = Arc::new(tick);
let tick_cloned = Arc::clone(&tick);
let callback = Box::new(move || {
func();
CallBackState::Recall(tick_cloned())
});
let handle = GLOBAL.register(Instant::now() + delay, callback);
Timer {
event_handle: handle,
tick: tick,
}
}
pub fn reset(&self) {
match GLOBAL.reset(&self.event_handle, (self.tick)()) {
Ok(_) => {}
Err(_) => unreachable!(),
}
}
pub fn stop(&self) {
GLOBAL.remove(&self.event_handle)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::thread;
use std::time::Duration;
use std::time::Instant;
#[test]
fn test_timer() {
let timer = Timer::start(
Duration::from_secs(3),
|| Duration::from_secs(3),
|| {
println!("print every two second, {:?}", Instant::now());
},
);
let timer = Arc::new(timer);
let timer_1 = timer.clone();
thread::spawn(move || {
thread::sleep(Duration::from_secs(5));
timer_1.reset();
});
let timer_2 = timer.clone();
thread::spawn(move || {
thread::sleep(Duration::from_secs(15));
println!("stop the timer");
timer_2.stop();
});
thread::sleep(Duration::from_secs(30));
}
}