euv_ui/hook/previous/struct.rs
1use super::*;
2
3/// Tracks the previously observed value of some external
4/// reactive source.
5///
6/// Typical use: in a render closure, call
7/// `previous.record(current)` at the top, then read
8/// `previous.get_previous().get()` to find out what the
9/// value was on the previous render. The two reads are
10/// decoupled so callers can record and read independently.
11///
12/// # Why a `Signal<Option<T>>`?
13///
14/// Because the very first call to `record` has no
15/// "previous" to report. The signal starts at `None`
16/// and flips to `Some(value)` after the first record.
17/// Render code can branch on the `Option` for
18/// "first render vs subsequent".
19///
20/// # Lombok caveat
21///
22/// `Previous` cannot use Lombok `New` because the
23/// `previous: Signal<Option<T>>` field would require
24/// `T: Default` to satisfy `Signal::default()`. The
25/// struct intentionally keeps `T: Clone + PartialEq +
26/// 'static` (no `Default`), and the constructor is
27/// hand-written in `impl.rs` to wrap the field with
28/// `Signal::create(None)`.
29#[derive(Clone, Data, Debug)]
30pub struct Previous<T: Clone + PartialEq + 'static> {
31 /// The previous-value signal. `None` until the first
32 /// `record` call.
33 pub(crate) previous: Signal<Option<T>>,
34}
35
36/// `Previous<T>` is `Copy` when `T` is — `Signal<Option<T>>` is
37/// already `Copy` (the signal registry hands out cheap `usize`
38/// addresses), so this blanket impl is sound.
39impl<T> Copy for Previous<T> where T: Clone + PartialEq + 'static {}