1use super::*;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
4pub struct HostNodeId {
5 pub(super) index: u32,
6 pub(super) generation: u32,
7}
8
9impl fmt::Display for HostNodeId {
10 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
11 write!(formatter, "{}:{}", self.index, self.generation)
12 }
13}
14
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
16pub enum HostUpdateKind {
17 Layout,
18 Paint,
19 Interaction,
20}
21
22#[derive(Clone, Debug, PartialEq, Eq)]
23pub enum HostMutation {
24 InsertNode {
25 id: HostNodeId,
26 source: UiId,
27 bounds: UiRect,
28 },
29 RemoveNode {
30 id: HostNodeId,
31 source: UiId,
32 old_bounds: UiRect,
33 },
34 UpdateProps {
35 id: HostNodeId,
36 source: UiId,
37 kind: HostUpdateKind,
38 old_bounds: UiRect,
39 new_bounds: UiRect,
40 },
41 ReorderChildren {
42 id: HostNodeId,
43 source: UiId,
44 bounds: UiRect,
45 },
46}
47
48#[derive(Clone, Debug, PartialEq, Eq)]
49pub enum SceneMutation {
50 Insert(HostNodeId),
51 Update(HostNodeId),
52 Remove(HostNodeId),
53 Reorder,
54}
55
56#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
57pub struct HostCommitMetrics {
58 pub host_nodes: usize,
59 pub scene_nodes: usize,
60 pub visited_host_nodes: usize,
61 pub compiled_scene_nodes: usize,
62 pub host_mutations: usize,
63 pub scene_mutations: usize,
64 pub reused_scene_nodes: usize,
65}
66
67#[cfg(feature = "diagnostics-timing")]
68#[derive(Clone, Copy, Debug, Default)]
69#[doc(hidden)]
70pub struct HostCommitTimings {
71 pub change_scan_ms: f32,
72 pub node_patch_ms: f32,
73 pub scene_reconcile_ms: f32,
74 pub scene_snapshot_ms: f32,
75 pub damage_ms: f32,
76 pub finalize_ms: f32,
77}
78
79#[derive(Clone, Debug)]
80pub struct HostCommit {
81 pub mutations: Vec<HostMutation>,
82 pub scene_mutations: Vec<SceneMutation>,
83 pub damage: DamageReport,
84 pub scene: Scene,
85 pub metrics: HostCommitMetrics,
86 pub semantics: SemanticUpdate,
87 #[cfg(feature = "diagnostics-timing")]
88 #[doc(hidden)]
89 pub timings: HostCommitTimings,
90}
91
92#[derive(Clone, Copy, Debug, PartialEq, Eq)]
93pub enum DamageReason {
94 FirstCommit,
95 Explicit,
96 Insert,
97 Remove,
98 Layout,
99 Paint,
100 Interaction,
101 Structure,
102 Clean,
103}
104
105#[derive(Clone, Debug)]
106pub struct DamageDetail {
107 pub reason: DamageReason,
108 pub node_id: Option<UiId>,
109 pub old_bounds: Option<UiRect>,
110 pub new_bounds: Option<UiRect>,
111 pub rects: Vec<UiRect>,
112}
113
114#[derive(Clone, Debug)]
115pub struct DamageReport {
116 pub dirty: DirtyRegionSet,
117 pub reasons: Vec<DamageReason>,
118 pub details: Vec<DamageDetail>,
119}
120
121pub(super) struct HostNode {
122 pub(super) source: UiId,
123 pub(super) mounted: bool,
124 pub(super) parent: Option<HostNodeId>,
125 pub(super) children: Vec<HostNodeId>,
126 pub(super) kind: UiNodeKind,
127 pub(super) layout_bounds: UiRect,
128 pub(super) paint_bounds: UiRect,
129 pub(super) interaction: InteractionFlags,
130 pub(super) node: UiNode,
131}
132
133pub(super) struct HostSlot {
134 pub(super) generation: u32,
135 pub(super) node: Option<HostNode>,
136}
137
138#[derive(Clone)]
139pub(super) struct SceneNode {
140 pub(super) signature: u64,
141 pub(super) commands: Vec<ScenePrimitive>,
142}
143
144#[derive(Default)]
145pub struct HostRuntime {
146 pub(super) slots: Vec<HostSlot>,
147 pub(super) free: Vec<u32>,
148 pub(super) sources: HashMap<UiId, HostNodeId>,
149 pub(super) paint_order: Vec<HostNodeId>,
150 pub(super) scene: HashMap<HostNodeId, SceneNode>,
151 pub(super) scene_order: Vec<HostNodeId>,
152 pub(super) scene_ranges: HashMap<HostNodeId, (usize, usize)>,
153 pub(super) composed_scene: Scene,
154 pub(super) semantics: HashMap<UiId, SemanticNode>,
155 pub(super) initialized: bool,
156}
157
158impl HostRuntime {
159 pub(crate) fn estimated_bytes(&self) -> usize {
160 let host_nodes = self
161 .slots
162 .iter()
163 .filter_map(|slot| slot.node.as_ref())
164 .map(|node| {
165 std::mem::size_of::<HostNode>()
166 .saturating_add(
167 node.children
168 .capacity()
169 .saturating_mul(std::mem::size_of::<HostNodeId>()),
170 )
171 .saturating_add(node.node.estimated_bytes())
172 })
173 .sum::<usize>();
174 let scene_nodes = self
175 .scene
176 .values()
177 .map(|node| crate::core::estimate_scene_commands_bytes(&node.commands))
178 .sum::<usize>();
179 std::mem::size_of::<Self>()
180 .saturating_add(host_nodes)
181 .saturating_add(scene_nodes)
182 .saturating_add(self.composed_scene.estimated_bytes())
183 }
184}