Skip to main content

euv_ui/hook/debounced_value/
struct.rs

1use super::*;
2
3/// A value that only emits after a quiet period of
4/// `delay` since its most recent `set`.
5///
6/// Constructed via `DebouncedValue::new(delay_ms)`
7/// (Lombok `New`); the emitted value starts at
8/// `T::default()` and the throttle state starts at
9/// `Idle`. Use [`DebouncedValue::set`] (or
10/// [`DebouncedValue::tick`] with a backdated timestamp)
11/// to seed the emitted value.
12///
13/// Typical use: pair with `App::use_interval` — the
14/// interval callback calls `tick(now_ms)` every
15/// N milliseconds, where `now_ms` comes from
16/// `performance.now()` on the web. After `delay_ms`
17/// without a fresh `set`, the pending value is committed.
18///
19/// This shape keeps the hook free of any browser /
20/// timer dependency so the same code runs in
21/// `cargo test` and in `wasm32-unknown-unknown` — the
22/// caller supplies the time source as plain milliseconds
23/// (`std::time::Instant::now()` panics on wasm, so the
24/// hook API deliberately takes `u64` millis).
25#[derive(Clone, Data, Debug, New)]
26pub struct DebouncedValue<T: Clone + PartialEq + Default + 'static> {
27    /// The emitted value signal. Defaults to
28    /// `Signal::create(T::default())` via
29    /// `#[new(skip)]`.
30    ///
31    /// Public because `example/src/page/hooks_timing/view/fn.rs`
32    /// reads it through `get_value()`.
33    #[new(skip)]
34    #[get(type(copy))]
35    pub value: Signal<T>,
36    /// The internal pending/empty state. Defaults to
37    /// `Signal::create(DebounceState::Idle)` via
38    /// `#[new(skip)]`.
39    ///
40    /// `get_state()` is only called by `impl.rs`, so the three
41    /// generated accessors are all `pub(crate)`.
42    #[get(pub(crate))]
43    #[get_mut(pub(crate))]
44    #[set(pub(crate))]
45    #[new(skip)]
46    pub(crate) state: Signal<DebounceState<T>>,
47    /// The quiet period in milliseconds.
48    ///
49    /// `get_delay_ms()` is only called by `impl.rs`, so the
50    /// three generated accessors are all `pub(crate)`.
51    #[get(type(copy), pub(crate))]
52    #[get_mut(pub(crate))]
53    #[set(pub(crate))]
54    pub(crate) delay_ms: u32,
55}
56
57/// `DebouncedValue<T>` is `Copy` when `T` is — every field
58/// (`Signal<T>`, `Signal<DebounceState<T>>`, `u32`) is itself
59/// `Copy`, so the blanket impl is sound.
60impl<T> Copy for DebouncedValue<T> where T: Clone + PartialEq + Default + 'static {}