1use crate::{ScopeId, Template, scheduler::ScopeOrder, virtual_dom::VirtualDom};
2use slab::Slab;
3use std::collections::HashMap;
4use std::num::NonZeroUsize;
5
6#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
12#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub struct ElementId(usize);
14
15impl ElementId {
16 pub const ROOT: Self = Self(0);
18
19 pub(crate) const fn new(index: usize) -> Self {
20 Self(index)
21 }
22
23 pub(crate) const fn index(self) -> usize {
24 self.0
25 }
26
27 pub const fn from_raw(index: usize) -> Self {
32 Self(index)
33 }
34
35 pub const fn raw(self) -> usize {
40 self.0
41 }
42}
43
44#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
49pub(crate) struct MountedElementId(NonZeroUsize);
50
51impl MountedElementId {
52 pub(crate) fn new(id: ElementId) -> Self {
53 Self::from_index(id.index())
54 }
55
56 pub(crate) fn from_index(index: usize) -> Self {
57 Self(NonZeroUsize::new(index).expect("root id"))
58 }
59
60 pub(crate) fn element_id(self) -> ElementId {
61 ElementId::new(self.index())
62 }
63
64 pub(crate) fn index(self) -> usize {
65 self.0.get()
66 }
67}
68
69#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
74#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
75pub struct RenderTargetId(usize);
76
77impl RenderTargetId {
78 pub const ROOT: Self = Self(0);
80
81 pub(crate) const fn new(index: usize) -> Self {
82 Self(index)
83 }
84
85 pub(crate) const fn index(self) -> usize {
86 self.0
87 }
88}
89
90#[derive(Clone, Debug, PartialEq, Eq)]
97pub(crate) enum MountedDynamicNodeSlot {
98 Empty,
99 Text(MountedElementId),
100 Component(ScopeId),
101 Fragment(usize),
102}
103
104#[derive(Debug)]
106pub(crate) struct RenderTargetState {
107 pub(crate) elements: Slab<Option<MountId>>,
108 pub(crate) template_roots: HashMap<(Template, usize), MountedElementId>,
109}
110
111impl RenderTargetState {
112 pub(crate) fn new() -> Self {
113 let mut elements = Slab::default();
114 elements.insert(None);
116
117 Self {
118 elements,
119 template_roots: HashMap::new(),
120 }
121 }
122}
123
124#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
129#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
130pub(crate) struct MountId(pub(crate) usize);
131
132impl VirtualDom {
133 pub(crate) fn current_render_target_id(&self) -> RenderTargetId {
134 self.runtime.current_render_target_id()
135 }
136
137 pub(crate) fn next_element_in_target(&mut self, target_id: RenderTargetId) -> MountedElementId {
138 let mut targets = self.runtime.render_targets.borrow_mut();
139 let target = targets.get_mut(target_id.index()).expect("target");
140 MountedElementId::new(ElementId::new(target.elements.insert(None)))
141 }
142
143 pub(crate) fn cached_template_root(
144 &self,
145 target_id: RenderTargetId,
146 template: Template,
147 root_anchor_idx: usize,
148 ) -> Option<MountedElementId> {
149 self.runtime
150 .render_targets
151 .borrow()
152 .get(target_id.index())
153 .and_then(|target| {
154 target
155 .template_roots
156 .get(&(template, root_anchor_idx))
157 .copied()
158 })
159 }
160
161 pub(crate) fn allocate_template_root(
162 &mut self,
163 target_id: RenderTargetId,
164 template: Template,
165 root_anchor_idx: usize,
166 ) -> MountedElementId {
167 let mut targets = self.runtime.render_targets.borrow_mut();
168 let target = targets.get_mut(target_id.index()).expect("target");
169 let id = MountedElementId::new(ElementId::new(target.elements.insert(None)));
170 target
171 .template_roots
172 .insert((template, root_anchor_idx), id);
173 id
174 }
175
176 pub(crate) fn set_element_ref_for_mount(&self, mount: MountId, el: MountedElementId) {
177 let target_id = self.mount_target_id(mount);
178 let mut targets = self.runtime.render_targets.borrow_mut();
179 let target = targets.get_mut(target_id.index()).expect("target");
180 let element = target.elements.get_mut(el.index()).expect("element");
181 *element = Some(mount);
182 }
183
184 pub(crate) fn reclaim_for_mount(&mut self, mount: MountId, el: MountedElementId) {
185 let target_id = self.mount_target_id(mount);
186 let mut targets = self.runtime.render_targets.borrow_mut();
187 let target = targets
188 .get_mut(target_id.index())
189 .expect("reclaim target must still be registered");
190 target.elements.try_remove(el.index());
191 }
192
193 pub(crate) fn drop_scope(&mut self, id: ScopeId) {
197 let height = {
198 let scope = self.scopes.remove(id.index());
199 let context = scope.state();
200 context.height
201 };
202
203 self.dirty_scopes.remove(&ScopeOrder::new(height, id));
204
205 self.resolved_scopes.retain(|s| s != &id);
207 }
208}