Add a lower level node forest structure and adjust data layout
1#[cfg(not(feature = "std"))]
2use alloc::{vec, vec::Vec};
3
4use core::any::Any;
5
6use std::collections::HashMap;
7use std::ops::Drop;
8use std::sync::Mutex;
9
10use crate::geometry::Size;
11use crate::id::{self, NodeId};
12use crate::number::Number;
13use crate::result::{Cache, Layout};
14use crate::style::*;
15use crate::Error;
16
17type MeasureFunc = Box<Fn(Size<Number>) -> Result<Size<f32>, Box<Any>>>;
18
19lazy_static! {
20 /// Global stretch instance id allocator.
21 static ref INSTANCE_ALLOCATOR: Mutex<id::Allocator> = Mutex::new(id::Allocator::new());
22}
23
24#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
25pub struct Node {
26 instance: id::Id,
27 local: id::Id,
28}
29
30pub struct Stretch {
31 id: id::Id,
32 nodes: id::Allocator,
33 nodes_to_ids: HashMap<Node, NodeId>,
34 ids_to_nodes: HashMap<NodeId, Node>,
35 forest: Forest,
36}
37
38impl Stretch {
39 const DEFAULT_CAPACITY: usize = 16;
40
41 pub fn new() -> Self {
42 Self::with_capacity(Self::DEFAULT_CAPACITY)
43 }
44
45 pub fn with_capacity(capacity: usize) -> Self {
46 Stretch {
47 id: INSTANCE_ALLOCATOR.lock().unwrap().allocate(),
48 nodes: id::Allocator::new(),
49 nodes_to_ids: HashMap::with_capacity(capacity),
50 ids_to_nodes: HashMap::with_capacity(capacity),
51 forest: Forest::with_capacity(capacity),
52 }
53 }
54
55 fn allocate_node(&mut self) -> Node {
56 let local = self.nodes.allocate();
57 Node { instance: self.id, local }
58 }
59
60 fn add_node(&mut self, node: Node, id: NodeId) {
61 self.nodes_to_ids.insert(node, id);
62 self.ids_to_nodes.insert(id, node);
63 }
64
65 // Find node in the forest.
66 fn find_node(&self, node: Node) -> Result<NodeId, Error> {
67 match self.nodes_to_ids.get(&node) {
68 Some(id) => Ok(*id),
69 None => Err(Error::InvalidNode(node)),
70 }
71 }
72
73 pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> Node {
74 let node = self.allocate_node();
75 let id = self.forest.new_leaf(style, measure);
76 self.add_node(node, id);
77 node
78 }
79
80 pub fn new_node(&mut self, style: Style, children: Vec<Node>) -> Result<Node, Error> {
81 let node = self.allocate_node();
82 let children = children.iter().map(|child| self.find_node(*child)).collect::<Result<Vec<_>, Error>>()?;
83 let id = self.forest.new_node(style, children);
84 self.add_node(node, id);
85 Ok(node)
86 }
87
88 pub fn set_measure(&mut self, node: Node, measure: Option<MeasureFunc>) -> Result<(), Error> {
89 let id = self.find_node(node)?;
90 self.forest.nodes[id].measure = measure;
91 self.forest.mark_dirty(id);
92 Ok(())
93 }
94
95 pub fn add_child(&mut self, node: Node, child: Node) -> Result<(), Error> {
96 let node_id = self.find_node(node)?;
97 let child_id = self.find_node(child)?;
98
99 self.forest.add_child(node_id, child_id);
100 Ok(())
101 }
102
103 pub fn set_children(&mut self, node: Node, children: Vec<Node>) -> Result<(), Error> {
104 let node_id = self.find_node(node)?;
105 let children_id = children.iter().map(|child| self.find_node(*child)).collect::<Result<Vec<_>, _>>()?;
106
107 // Remove node as parent from all its current children.
108 for child in &self.forest.children[node_id] {
109 self.forest.parents[*child].retain(|p| *p != node_id);
110 }
111
112 // Build up relation node <-> child
113 for child in &children_id {
114 self.forest.parents[*child].push(node_id);
115 }
116 self.forest.children[node_id] = children_id;
117
118 self.forest.mark_dirty(node_id);
119 Ok(())
120 }
121
122 pub fn remove_child(&mut self, node: Node, child: Node) -> Result<Node, Error> {
123 let node_id = self.find_node(node)?;
124 let child_id = self.find_node(child)?;
125
126 let prev_id = unsafe { self.forest.remove_child(node_id, child_id) };
127 Ok(self.ids_to_nodes[&prev_id])
128 }
129
130 pub fn remove_child_at_index(&mut self, node: Node, index: usize) -> Result<Node, Error> {
131 let node_id = self.find_node(node)?;
132 // TODO: index check
133
134 let prev_id = self.forest.remove_child_at_index(node_id, index);
135 Ok(self.ids_to_nodes[&prev_id])
136 }
137
138 pub fn replace_child_at_index(&mut self, node: Node, index: usize, child: Node) -> Result<Node, Error> {
139 let node_id = self.find_node(node)?;
140 let child_id = self.find_node(child)?;
141 // TODO: index check
142
143 self.forest.parents[child_id].push(node_id);
144 let old_child = std::mem::replace(&mut self.forest.children[node_id][index], child_id);
145 self.forest.parents[old_child].retain(|p| *p != node_id);
146
147 self.forest.mark_dirty(node_id);
148
149 Ok(self.ids_to_nodes[&old_child])
150 }
151
152 pub fn children(&self, node: Node) -> Result<Vec<Node>, Error> {
153 let id = self.find_node(node)?;
154 Ok(self.forest.children[id].iter().map(|child| self.ids_to_nodes[child]).collect())
155 }
156
157 pub fn child_count(&self, node: Node) -> Result<usize, Error> {
158 let id = self.find_node(node)?;
159 Ok(self.forest.children[id].len())
160 }
161
162 pub fn set_style(&mut self, node: Node, style: Style) -> Result<(), Error> {
163 let id = self.find_node(node)?;
164 self.forest.nodes[id].style = style;
165 self.forest.mark_dirty(id);
166 Ok(())
167 }
168
169 pub fn style(&self, node: Node) -> Result<&Style, Error> {
170 let id = self.find_node(node)?;
171 Ok(&self.forest.nodes[id].style)
172 }
173
174 pub fn layout(&self, node: Node) -> Result<&Layout, Error> {
175 let id = self.find_node(node)?;
176 Ok(&self.forest.nodes[id].layout)
177 }
178
179 pub fn mark_dirty(&mut self, node: Node) -> Result<(), Error> {
180 let id = self.find_node(node)?;
181 self.forest.mark_dirty(id);
182 Ok(())
183 }
184
185 pub fn dirty(&self, node: Node) -> Result<bool, Error> {
186 let id = self.find_node(node)?;
187 Ok(self.forest.nodes[id].is_dirty)
188 }
189
190 pub fn compute_layout(&mut self, node: Node, size: Size<Number>) -> Result<(), Error> {
191 let id = self.find_node(node)?;
192 self.forest.compute(id, size).map_err(|err| Error::Measure(err))
193 }
194}
195
196impl Drop for Stretch {
197 fn drop(&mut self) {
198 INSTANCE_ALLOCATOR.lock().unwrap().free(&[self.id]);
199 }
200}
201
202pub(crate) struct NodeData {
203 pub(crate) style: Style,
204 pub(crate) measure: Option<MeasureFunc>,
205 pub(crate) layout: Layout,
206 pub(crate) layout_cache: Option<Cache>,
207 pub(crate) is_dirty: bool,
208}
209
210impl NodeData {
211 fn new_leaf(style: Style, measure: MeasureFunc) -> Self {
212 NodeData { style, measure: Some(measure), layout_cache: None, layout: Layout::new(), is_dirty: true }
213 }
214
215 fn new(style: Style) -> Self {
216 NodeData { style, measure: None, layout_cache: None, layout: Layout::new(), is_dirty: true }
217 }
218}
219
220pub(crate) struct Forest {
221 pub(crate) nodes: Vec<NodeData>,
222 pub(crate) children: Vec<Vec<id::NodeId>>,
223 pub(crate) parents: Vec<Vec<id::NodeId>>,
224}
225
226impl Forest {
227 pub fn with_capacity(capacity: usize) -> Self {
228 Forest {
229 nodes: Vec::with_capacity(capacity),
230 children: Vec::with_capacity(capacity),
231 parents: Vec::with_capacity(capacity),
232 }
233 }
234
235 pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> NodeId {
236 let id = self.nodes.len();
237 self.nodes.push(NodeData::new_leaf(style, measure));
238 self.children.push(Vec::with_capacity(0));
239 self.parents.push(Vec::with_capacity(1));
240 id
241 }
242
243 pub fn new_node(&mut self, style: Style, children: Vec<NodeId>) -> NodeId {
244 let id = self.nodes.len();
245 for child in &children {
246 self.parents[*child].push(id);
247 }
248 self.nodes.push(NodeData::new(style));
249 self.children.push(children);
250 self.parents.push(Vec::with_capacity(1));
251 id
252 }
253
254 pub fn add_child(&mut self, node: NodeId, child: NodeId) {
255 self.parents[child].push(node);
256 self.children[node].push(child);
257 self.mark_dirty(node)
258 }
259
260 pub unsafe fn remove_child(&mut self, node: NodeId, child: NodeId) -> NodeId {
261 let index = self.children[node].iter().position(|n| *n == child).unwrap();
262 self.remove_child_at_index(node, index)
263 }
264
265 pub fn remove_child_at_index(&mut self, node: NodeId, index: usize) -> NodeId {
266 let child = self.children[node].remove(index);
267 self.parents[child].retain(|p| *p != node);
268 self.mark_dirty(node);
269 child
270 }
271
272 pub fn mark_dirty(&mut self, node: NodeId) {
273 fn mark_dirty_impl(nodes: &mut Vec<NodeData>, parents: &Vec<Vec<NodeId>>, node_id: NodeId) {
274 let node = &mut nodes[node_id];
275 node.layout_cache = None;
276 node.is_dirty = true;
277
278 for parent in &parents[node_id] {
279 mark_dirty_impl(nodes, parents, *parent);
280 }
281 }
282
283 mark_dirty_impl(&mut self.nodes, &self.parents, node);
284 }
285
286 pub fn compute_layout(&mut self, node: NodeId, size: Size<Number>) -> Result<(), Error> {
287 self.compute(node, size).map_err(|err| Error::Measure(err))
288 }
289}