euv_ui/hook/throttled_value/struct.rs
1use super::*;
2
3/// A value that emits the most recent input at most once
4/// per `interval_ms`.
5///
6/// Constructed via `ThrottledValue::new(interval_ms)`
7/// (Lombok `New`); the emitted value starts at
8/// `T::default()` and the throttle state starts at
9/// `Idle`. Use [`ThrottledValue::set`] to seed the
10/// emitted value.
11///
12/// Unlike [`DebouncedValue`], which waits for a quiet
13/// period, a throttled value commits a snapshot every
14/// `interval_ms` regardless of how often `set` was called.
15///
16/// Pair with `App::use_interval` — the interval callback
17/// calls `tick(now_ms)` every `interval_ms`, where
18/// `now_ms` comes from `performance.now()` on the web.
19/// The caller picks the time source (plain `u64` millis)
20/// so the hook stays free of browser / timer dependencies
21/// and works on `wasm32-unknown-unknown` (where
22/// `std::time::Instant::now()` panics).
23#[derive(Clone, Data, Debug, New)]
24pub struct ThrottledValue<T: Clone + PartialEq + Default + 'static> {
25 /// The emitted value signal. Defaults to
26 /// `Signal::create(T::default())` via
27 /// `#[new(skip)]`.
28 #[new(skip)]
29 #[get(type(copy))]
30 pub(crate) value: Signal<T>,
31 /// The latest input waiting for the next commit.
32 /// Defaults to `Signal::create(None)` via
33 /// `#[new(skip)]`.
34 #[new(skip)]
35 pub(crate) pending: Signal<Option<T>>,
36 /// The internal idle/cooldown state. Defaults to
37 /// `Signal::create(ThrottleState::Idle)` via
38 /// `#[new(skip)]`.
39 #[new(skip)]
40 pub(crate) state: Signal<ThrottleState>,
41 /// The throttle window in milliseconds.
42 pub(crate) interval_ms: u32,
43}
44
45/// `ThrottledValue<T>` is `Copy` when `T` is — every field
46/// is itself `Copy` (`Signal<T>`, `Signal<Option<T>>`, `u32`)
47/// or a simple `enum`, so the blanket impl is sound.
48impl<T> Copy for ThrottledValue<T> where T: Clone + PartialEq + Default + 'static {}