1use std::time::{
2 Duration,
3 Instant,
4};
5
6use async_io::Timer;
7use freya_core::prelude::*;
8
9#[derive(Clone, Copy, PartialEq)]
10pub struct Timeout {
11 elapsed: State<bool>,
12 instant: State<Instant>,
13}
14
15impl Timeout {
16 pub fn elapsed(&self) -> bool {
18 (self.elapsed)()
19 }
20
21 pub fn reset(&mut self) {
23 self.instant.set_if_modified(Instant::now());
24 self.elapsed.set_if_modified(false);
25 }
26}
27
28pub fn use_timeout(duration: impl FnOnce() -> Duration) -> Timeout {
34 use_hook(|| {
35 let duration = duration();
36 let mut elapsed = State::create(false);
37 let instant = State::create(Instant::now());
38
39 spawn(async move {
40 loop {
41 Timer::after(duration).await;
42 if instant.read().elapsed() >= duration && !elapsed() {
43 elapsed.set(true);
44 }
45 }
46 });
47
48 Timeout { elapsed, instant }
49 })
50}