use std::time::{
Duration,
Instant,
};
use async_io::Timer;
use freya_core::prelude::*;
#[derive(Clone, Copy, PartialEq)]
pub struct Timeout {
elapsed: State<bool>,
instant: State<Instant>,
}
impl Timeout {
pub fn create(duration: Duration) -> Self {
let mut elapsed = State::create(false);
let instant = State::create(Instant::now());
spawn(async move {
loop {
Timer::after(duration).await;
if instant.read().elapsed() >= duration && !elapsed() {
elapsed.set(true);
}
}
});
Timeout { elapsed, instant }
}
pub fn elapsed(&self) -> bool {
(self.elapsed)()
}
pub fn reset(&mut self) {
self.instant.set_if_modified(Instant::now());
self.elapsed.set_if_modified(false);
}
}
pub fn use_timeout(duration: impl FnOnce() -> Duration) -> Timeout {
use_hook(|| Timeout::create(duration()))
}