euv_ui/hook/use_timer/fn.rs
1use super::*;
2
3/// Obtains the [`UseTimer`] registered against the current hook context
4/// slot.
5///
6/// Behaves like `HookContext::use_hook` - the same handle is returned on
7/// every render at the same hook index, so the tick count survives
8/// re-renders.
9///
10/// The interval is created once, on the first render, and is cleared
11/// automatically when the component unmounts. A period of zero is
12/// treated as one millisecond: a zero-delay interval is a busy loop
13/// that would starve the renderer.
14///
15/// # Arguments
16///
17/// - `u32` - The period in milliseconds.
18///
19/// # Returns
20///
21/// - `UseTimer` - The handle, with `get_ticks()` returning the reactive
22/// `Signal<u64>`.
23pub fn use_timer(interval_ms: u32) -> UseTimer {
24 let handle: UseTimer = HookContext::use_hook(|| UseTimer::new(interval_ms));
25 // The interval is a browser timer. `App::use_interval` reaches for
26 // `window` to register it, and `window` does not exist on a host
27 // build — the call would abort the process rather than return. The
28 // timer therefore only runs in a browser, and a host build gets a
29 // handle whose tick count simply never moves.
30 #[cfg(target_arch = "wasm32")]
31 {
32 let ticks: Signal<u64> = handle.get_ticks();
33 App::use_interval(interval_ms.max(1) as i32, move || {
34 let current: u64 = ticks.get();
35 ticks.set(current + 1);
36 });
37 }
38 handle
39}
40
41/// Schedules `callback` to run once, `delay_ms` milliseconds from now.
42///
43/// The callback is dropped if the component unmounts before the delay
44/// elapses, so a timeout cannot fire into a component that is gone.
45///
46/// # Arguments
47///
48/// - `u32` - The delay in milliseconds.
49/// - `F` - The callback to run.
50pub fn use_timeout<F>(delay_ms: u32, callback: F)
51where
52 F: FnOnce() + 'static,
53{
54 let cancelled: Signal<bool> = App::use_signal(|| false);
55 schedule_after(delay_ms, move || {
56 if cancelled.get() {
57 return;
58 }
59 callback();
60 });
61 App::use_cleanup(move || {
62 cancelled.set(true);
63 });
64}