Skip to main content

fret_ui/tree/debug/
invalidation.rs

1use super::super::*;
2use fret_runtime::ModelCreatedDebugInfo;
3
4#[derive(Debug, Default, Clone, Copy)]
5pub struct UiDebugHoverDeclarativeInvalidationHotspot {
6    pub node: NodeId,
7    pub element: Option<GlobalElementId>,
8    pub hit_test: u32,
9    pub layout: u32,
10    pub paint: u32,
11}
12
13#[derive(Debug, Default, Clone, Copy)]
14pub(in crate::tree) struct UiDebugHoverDeclarativeInvalidationCounts {
15    pub(in crate::tree) hit_test: u32,
16    pub(in crate::tree) layout: u32,
17    pub(in crate::tree) paint: u32,
18}
19
20#[derive(Debug, Default, Clone, Copy)]
21pub struct UiDebugModelChangeHotspot {
22    pub model: ModelId,
23    pub observation_edges: u32,
24    pub changed: Option<fret_runtime::model::ModelChangedDebugInfo>,
25}
26
27#[derive(Debug, Clone, Copy)]
28pub struct UiDebugModelChangeUnobserved {
29    pub model: ModelId,
30    pub created: Option<ModelCreatedDebugInfo>,
31    pub changed: Option<fret_runtime::model::ModelChangedDebugInfo>,
32}
33
34#[derive(Debug, Clone, Copy)]
35pub struct UiDebugGlobalChangeHotspot {
36    pub global: TypeId,
37    pub observation_edges: u32,
38}
39
40#[derive(Debug, Clone, Copy)]
41pub struct UiDebugGlobalChangeUnobserved {
42    pub global: TypeId,
43}
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum UiDebugInvalidationSource {
46    ModelChange,
47    GlobalChange,
48    Notify,
49    Hover,
50    Focus,
51    Other,
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum UiDebugInvalidationDetail {
56    Unknown,
57    ModelObservation,
58    GlobalObservation,
59    NotifyCall,
60    HoverEvent,
61    /// A hover edge that must re-run declarative view-cache subtrees.
62    ///
63    /// `HoverRegion` is a mechanism-layer primitive that provides a `hovered: bool` signal to
64    /// component code. Under view-cache reuse, paint-only invalidations do not re-run child render
65    /// closures by design, so hover edges must be treated as "view dirty" to preserve the
66    /// contract for hover-driven policies (e.g. hover cards).
67    HoverRegionEdge,
68    /// A pressable hover edge that must re-run declarative view-cache subtrees.
69    ///
70    /// `Pressable` exposes a `hovered: bool` signal to declarative component code. Under
71    /// view-cache reuse, paint-only invalidations do not re-run child render closures by design,
72    /// so hover edges must be treated as "view dirty" when component trees depend on pressable
73    /// hover state to mount/unmount children (e.g. tab strip close buttons).
74    PressableHoverEdge,
75    FocusEvent,
76    ScrollHandleHitTestOnly,
77    ScrollHandleLayout,
78    ScrollHandleWindowUpdate,
79    ScrollDeferredProbe,
80    ScrollExtentsObservationBudgetHit,
81    ScrollHandleScrollToItemWindowUpdate,
82    ScrollHandleViewportResizeWindowUpdate,
83    ScrollHandleItemsRevisionWindowUpdate,
84    ScrollHandlePrefetchWindowUpdate,
85    FocusVisiblePolicy,
86    InputModalityPolicy,
87    AnimationFrameRequest,
88}
89
90impl UiDebugInvalidationDetail {
91    pub fn from_source(source: UiDebugInvalidationSource) -> Self {
92        match source {
93            UiDebugInvalidationSource::ModelChange => Self::ModelObservation,
94            UiDebugInvalidationSource::GlobalChange => Self::GlobalObservation,
95            UiDebugInvalidationSource::Notify => Self::NotifyCall,
96            UiDebugInvalidationSource::Hover => Self::HoverEvent,
97            UiDebugInvalidationSource::Focus => Self::FocusEvent,
98            UiDebugInvalidationSource::Other => Self::Unknown,
99        }
100    }
101
102    pub fn as_str(self) -> Option<&'static str> {
103        match self {
104            Self::Unknown => None,
105            Self::ModelObservation => Some("model_observation"),
106            Self::GlobalObservation => Some("global_observation"),
107            Self::NotifyCall => Some("notify_call"),
108            Self::HoverEvent => Some("hover_event"),
109            Self::HoverRegionEdge => Some("hover_region_edge"),
110            Self::PressableHoverEdge => Some("pressable_hover_edge"),
111            Self::FocusEvent => Some("focus_event"),
112            Self::ScrollHandleHitTestOnly => Some("scroll_handle_hit_test_only"),
113            Self::ScrollHandleLayout => Some("scroll_handle_layout"),
114            Self::ScrollHandleWindowUpdate => Some("scroll_handle_window_update"),
115            Self::ScrollDeferredProbe => Some("scroll_deferred_probe"),
116            Self::ScrollExtentsObservationBudgetHit => {
117                Some("scroll_extents_observation_budget_hit")
118            }
119            Self::ScrollHandleScrollToItemWindowUpdate => {
120                Some("scroll_handle_scroll_to_item_window_update")
121            }
122            Self::ScrollHandleViewportResizeWindowUpdate => {
123                Some("scroll_handle_viewport_resize_window_update")
124            }
125            Self::ScrollHandleItemsRevisionWindowUpdate => {
126                Some("scroll_handle_items_revision_window_update")
127            }
128            Self::ScrollHandlePrefetchWindowUpdate => Some("scroll_handle_prefetch_window_update"),
129            Self::FocusVisiblePolicy => Some("focus_visible_policy"),
130            Self::InputModalityPolicy => Some("input_modality_policy"),
131            Self::AnimationFrameRequest => Some("animation_frame_request"),
132        }
133    }
134}
135
136#[derive(Debug, Clone, Copy)]
137pub struct UiDebugDirtyView {
138    pub view: ViewId,
139    pub element: Option<GlobalElementId>,
140    pub source: UiDebugInvalidationSource,
141    pub detail: UiDebugInvalidationDetail,
142}
143
144#[derive(Debug, Clone, Copy)]
145pub struct UiDebugNotifyRequest {
146    pub frame_id: FrameId,
147    pub caller_node: NodeId,
148    pub target_view: ViewId,
149    pub file: &'static str,
150    pub line: u32,
151    pub column: u32,
152}
153
154#[derive(Debug, Clone, Copy)]
155pub struct UiDebugInvalidationWalk {
156    pub root: NodeId,
157    pub root_element: Option<GlobalElementId>,
158    pub inv: Invalidation,
159    pub source: UiDebugInvalidationSource,
160    pub detail: UiDebugInvalidationDetail,
161    pub walked_nodes: u32,
162    pub truncated_at: Option<NodeId>,
163}