1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//! A shared generation-stamp registry for analysis results that have no other
//! natural home to track their own "computed against generation N" bookkeeping in.
//!
//! # Why this exists alongside `state::result_is_stale`, not instead of it
//!
//! Deep Solve and Optimize already stamp their own result generation directly on
//! [`super::state::EditorState`] (`deep_solve_result_generation`/
//! `pending_optimize`'s stored generation) and read it back in
//! [`super::view::push_stale_content`] -- that machinery predates this module and
//! is not migrated here: `EditorState`'s fields are immutable, and duplicating a
//! second stamp for the same two results would be duplication. This module instead
//! covers the ONE remaining result that has no `EditorState` field of its own to
//! live on: the Retarget proposal, whose generation is produced from TWO different
//! call sites (`callbacks::retarget_actions`'s Shift-mode intent handler and its
//! async Optimize-mode completion handler) that cannot otherwise share a single
//! owner without a new `EditorState` field. A `thread_local!` map, keyed by
//! [`ResultKind`], gives both call sites one shared place to stamp into and gives
//! [`refresh_badges`] one shared place to read back from, entirely in this module.
//!
//! Tilt curves (`ui/models/tilt.slint`'s `cached_curve_*`/`curves_stale`) are
//! deliberately NOT stamped here: `gui::tilt` sits outside `gui::editor`'s module
//! tree (Rust privacy: `mod activity;`/`mod auto_solve;` in `gui/editor/mod.rs`
//! are visible only within that subtree), so it cannot reach this registry. Instead,
//! `gui::tilt::tilt_profile` keys tilt-curve staleness off its own already-existing
//! `AxesCacheKey`/`hash_planes` comparison (the exact planes/material/light the
//! curve was swept against), which is self-contained and more precise than a generic
//! edit-generation counter would be.
//! Trace staleness (`ViewportModel.trace_stale`) is likewise left as-is: it already
//! has its own generation home on `RenderContext::planes_owner`
//! (`bridge::render_thread::context::RenderContext::traced_planes_are_stale`),
//! read directly by `view::push_trace_staleness`.
//!
//! Reachable only from within `gui::editor` -- see [`ResultKind`]/[`stamp`]/
//! [`clear`]/[`refresh_badges`]'s own visibility. The registry itself
//! (`ResultKind`/`StaleStamps`) lives in `indicatrix_editor::stale`, shared with the
//! web app; this module keeps the UI-thread holder and the Slint badge push.
use crate::;
pub use ResultKind;
use StaleStamps;
use ComponentHandle;
use RefCell;
thread_local!
/// Records that `kind`'s current result was computed against `generation` --
/// called the moment a fresh result actually lands (a rebuilt Shift-mode proposal,
/// a completed async Optimize-mode search).
pub
/// Forgets `kind`'s stamp -- called whenever its result is discarded outright
/// (the dialog closes, the held proposal is applied/cancelled) so a badge can
/// never survive its own result.
pub
/// Re-derives every `*_stale` Slint property this registry drives, against the
/// design's current `live_generation` -- called once per edit from
/// [`super::view::push_stale_content`], alongside that function's own direct
/// Deep-Solve/Optimize staleness pushes (see the module doc comment for why those
/// two are not routed through here).
pub