1use core::ops::Drop;
2
3use crate::forest::Forest;
4use crate::geometry::Size;
5use crate::id::{self, NodeId};
6use crate::number::Number;
7use crate::result::Layout;
8use crate::style::*;
9use crate::sys;
10use crate::Error;
11
12pub enum MeasureFunc {
13 Raw(fn(Size<Number>) -> Size<f32>),
14 #[cfg(any(feature = "std", feature = "alloc"))]
15 Boxed(sys::Box<dyn Fn(Size<Number>) -> Size<f32>>),
16}
17
18static INSTANCE_ALLOCATOR: id::Allocator = id::Allocator::new();
20
21#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
22#[cfg_attr(not(any(feature = "std", feature = "alloc")), derive(hash32_derive::Hash32))]
23pub struct Node {
24 instance: id::Id,
25 local: id::Id,
26}
27
28pub struct Stretch {
29 id: id::Id,
30 nodes: id::Allocator,
31 nodes_to_ids: crate::sys::Map<Node, NodeId>,
32 ids_to_nodes: crate::sys::Map<NodeId, Node>,
33 forest: Forest,
34}
35
36impl Default for Stretch {
37 fn default() -> Self {
38 Self::with_capacity(16)
39 }
40}
41
42impl Stretch {
43 pub fn new() -> Self {
44 Default::default()
45 }
46
47 pub fn with_capacity(capacity: usize) -> Self {
48 Self {
49 id: INSTANCE_ALLOCATOR.allocate(),
50 nodes: id::Allocator::new(),
51 nodes_to_ids: crate::sys::new_map_with_capacity(capacity),
52 ids_to_nodes: crate::sys::new_map_with_capacity(capacity),
53 forest: Forest::with_capacity(capacity),
54 }
55 }
56
57 fn allocate_node(&mut self) -> Node {
58 let local = self.nodes.allocate();
59 Node { instance: self.id, local }
60 }
61
62 fn add_node(&mut self, node: Node, id: NodeId) {
63 let _ = self.nodes_to_ids.insert(node, id);
64 let _ = self.ids_to_nodes.insert(id, node);
65 }
66
67 fn find_node(&self, node: Node) -> Result<NodeId, Error> {
69 match self.nodes_to_ids.get(&node) {
70 Some(id) => Ok(*id),
71 None => Err(Error::InvalidNode(node)),
72 }
73 }
74
75 pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> Result<Node, Error> {
76 let node = self.allocate_node();
77 let id = self.forest.new_leaf(style, measure);
78 self.add_node(node, id);
79 Ok(node)
80 }
81
82 pub fn new_node(&mut self, style: Style, children: &[Node]) -> Result<Node, Error> {
83 let node = self.allocate_node();
84 let children =
85 children.iter().map(|child| self.find_node(*child)).collect::<Result<sys::ChildrenVec<_>, Error>>()?;
86 let id = self.forest.new_node(style, children);
87 self.add_node(node, id);
88 Ok(node)
89 }
90
91 pub fn clear(&mut self) {
95 for node in self.nodes_to_ids.keys() {
96 self.nodes.free(&[node.local]);
97 }
98 self.nodes_to_ids.clear();
99 self.ids_to_nodes.clear();
100 self.forest.clear();
101 }
102
103 pub fn remove(&mut self, node: Node) {
105 let id = if let Ok(id) = self.find_node(node) { id } else { return };
106
107 self.nodes_to_ids.remove(&node);
108 self.ids_to_nodes.remove(&id);
109
110 if let Some(new_id) = self.forest.swap_remove(id) {
111 let new = self.ids_to_nodes.remove(&new_id).unwrap();
112 let _ = self.nodes_to_ids.insert(new, id);
113 let _ = self.ids_to_nodes.insert(id, new);
114 }
115 }
116
117 pub fn set_measure(&mut self, node: Node, measure: Option<MeasureFunc>) -> Result<(), Error> {
118 let id = self.find_node(node)?;
119 self.forest.nodes[id].measure = measure;
120 self.forest.mark_dirty(id);
121 Ok(())
122 }
123
124 pub fn add_child(&mut self, node: Node, child: Node) -> Result<(), Error> {
125 let node_id = self.find_node(node)?;
126 let child_id = self.find_node(child)?;
127
128 self.forest.add_child(node_id, child_id);
129 Ok(())
130 }
131
132 pub fn set_children(&mut self, node: Node, children: &[Node]) -> Result<(), Error> {
133 let node_id = self.find_node(node)?;
134 let children_id =
135 children.iter().map(|child| self.find_node(*child)).collect::<Result<sys::ChildrenVec<_>, _>>()?;
136
137 for child in &self.forest.children[node_id] {
139 self.forest.parents[*child].retain(|p| *p != node_id);
140 }
141
142 for child in &children_id {
144 self.forest.parents[*child].push(node_id);
145 }
146 self.forest.children[node_id] = children_id;
147
148 self.forest.mark_dirty(node_id);
149 Ok(())
150 }
151
152 pub fn remove_child(&mut self, node: Node, child: Node) -> Result<Node, Error> {
153 let node_id = self.find_node(node)?;
154 let child_id = self.find_node(child)?;
155
156 let prev_id = self.forest.remove_child(node_id, child_id);
157 Ok(self.ids_to_nodes[&prev_id])
158 }
159
160 pub fn remove_child_at_index(&mut self, node: Node, index: usize) -> Result<Node, Error> {
161 let node_id = self.find_node(node)?;
162 let prev_id = self.forest.remove_child_at_index(node_id, index);
165 Ok(self.ids_to_nodes[&prev_id])
166 }
167
168 pub fn replace_child_at_index(&mut self, node: Node, index: usize, child: Node) -> Result<Node, Error> {
169 let node_id = self.find_node(node)?;
170 let child_id = self.find_node(child)?;
171 self.forest.parents[child_id].push(node_id);
174 let old_child = core::mem::replace(&mut self.forest.children[node_id][index], child_id);
175 self.forest.parents[old_child].retain(|p| *p != node_id);
176
177 self.forest.mark_dirty(node_id);
178
179 Ok(self.ids_to_nodes[&old_child])
180 }
181
182 pub fn children(&self, node: Node) -> Result<sys::Vec<Node>, Error> {
183 let id = self.find_node(node)?;
184 Ok(self.forest.children[id].iter().map(|child| self.ids_to_nodes[child]).collect())
185 }
186
187 pub fn child_at_index(&self, node: Node, index: usize) -> Result<Node, Error> {
188 let id = self.find_node(node)?;
189 Ok(self.ids_to_nodes[&self.forest.children[id][index]])
190 }
191
192 pub fn child_count(&self, node: Node) -> Result<usize, Error> {
193 let id = self.find_node(node)?;
194 Ok(self.forest.children[id].len())
195 }
196
197 pub fn set_style(&mut self, node: Node, style: Style) -> Result<(), Error> {
198 let id = self.find_node(node)?;
199 self.forest.nodes[id].style = style;
200 self.forest.mark_dirty(id);
201 Ok(())
202 }
203
204 pub fn style(&self, node: Node) -> Result<&Style, Error> {
205 let id = self.find_node(node)?;
206 Ok(&self.forest.nodes[id].style)
207 }
208
209 pub fn layout(&self, node: Node) -> Result<&Layout, Error> {
211 let id = self.find_node(node)?;
212 Ok(&self.forest.nodes[id].layout)
213 }
214
215 pub fn mark_dirty(&mut self, node: Node) -> Result<(), Error> {
216 let id = self.find_node(node)?;
217 self.forest.mark_dirty(id);
218 Ok(())
219 }
220
221 pub fn dirty(&self, node: Node) -> Result<bool, Error> {
222 let id = self.find_node(node)?;
223 Ok(self.forest.nodes[id].is_dirty)
224 }
225
226 pub fn compute_layout(&mut self, node: Node, size: Size<Number>) -> Result<(), Error> {
227 let id = self.find_node(node)?;
228 self.forest.compute_layout(id, size);
229 Ok(())
230 }
231}
232
233impl Drop for Stretch {
234 fn drop(&mut self) {
235 INSTANCE_ALLOCATOR.free(&[self.id]);
236 }
237}