Enable compilation of crate for no_std again.
1#[cfg(not(feature = "std"))]
2use alloc::{boxed::Box, vec::Vec};
3#[cfg(not(feature = "std"))]
4use hashbrown::HashMap;
5#[cfg(feature = "std")]
6use std::collections::HashMap;
7
8use core::any::Any;
9use core::ops::Drop;
10
11use crate::forest::Forest;
12use crate::geometry::Size;
13use crate::id::{self, NodeId};
14use crate::number::Number;
15use crate::result::Layout;
16use crate::style::*;
17use crate::Error;
18
19pub type MeasureFunc = Box<dyn Fn(Size<Number>) -> Result<Size<f32>, Box<dyn Any>>>;
20
21lazy_static! {
22 /// Global stretch instance id allocator.
23 static ref INSTANCE_ALLOCATOR: id::Allocator = id::Allocator::new();
24}
25
26#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
27pub struct Node {
28 instance: id::Id,
29 local: id::Id,
30}
31
32pub struct Stretch {
33 id: id::Id,
34 nodes: id::Allocator,
35 nodes_to_ids: HashMap<Node, NodeId>,
36 ids_to_nodes: HashMap<NodeId, Node>,
37 forest: Forest,
38}
39
40impl Stretch {
41 const DEFAULT_CAPACITY: usize = 16;
42
43 pub fn new() -> Self {
44 Self::with_capacity(Self::DEFAULT_CAPACITY)
45 }
46
47 pub fn with_capacity(capacity: usize) -> Self {
48 Stretch {
49 id: INSTANCE_ALLOCATOR.allocate(),
50 nodes: id::Allocator::new(),
51 nodes_to_ids: HashMap::with_capacity(capacity),
52 ids_to_nodes: HashMap::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 self.nodes_to_ids.insert(node, id);
64 self.ids_to_nodes.insert(id, node);
65 }
66
67 // Find node in the forest.
68 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: Vec<Node>) -> Result<Node, Error> {
83 let node = self.allocate_node();
84 let children = children.iter().map(|child| self.find_node(*child)).collect::<Result<Vec<_>, Error>>()?;
85 let id = self.forest.new_node(style, children);
86 self.add_node(node, id);
87 Ok(node)
88 }
89
90 /// Removes all nodes.
91 ///
92 /// All associated nodes will be invalid.
93 pub fn clear(&mut self) {
94 for node in self.nodes_to_ids.keys() {
95 self.nodes.free(&[node.local]);
96 }
97 self.nodes_to_ids.clear();
98 self.ids_to_nodes.clear();
99 self.forest.clear();
100 }
101
102 /// Remove nodes.
103 pub fn remove(&mut self, node: Node) {
104 let id = if let Ok(id) = self.find_node(node) { id } else { return };
105
106 self.nodes_to_ids.remove(&node);
107 self.ids_to_nodes.remove(&id);
108
109 if let Some(new_id) = self.forest.swap_remove(id) {
110 let new = self.ids_to_nodes.remove(&new_id).unwrap();
111 self.nodes_to_ids.insert(new, id);
112 }
113 }
114
115 pub fn set_measure(&mut self, node: Node, measure: Option<MeasureFunc>) -> Result<(), Error> {
116 let id = self.find_node(node)?;
117 self.forest.nodes[id].measure = measure;
118 self.forest.mark_dirty(id);
119 Ok(())
120 }
121
122 pub fn add_child(&mut self, node: Node, child: Node) -> Result<(), Error> {
123 let node_id = self.find_node(node)?;
124 let child_id = self.find_node(child)?;
125
126 self.forest.add_child(node_id, child_id);
127 Ok(())
128 }
129
130 pub fn set_children(&mut self, node: Node, children: Vec<Node>) -> Result<(), Error> {
131 let node_id = self.find_node(node)?;
132 let children_id = children.iter().map(|child| self.find_node(*child)).collect::<Result<Vec<_>, _>>()?;
133
134 // Remove node as parent from all its current children.
135 for child in &self.forest.children[node_id] {
136 self.forest.parents[*child].retain(|p| *p != node_id);
137 }
138
139 // Build up relation node <-> child
140 for child in &children_id {
141 self.forest.parents[*child].push(node_id);
142 }
143 self.forest.children[node_id] = children_id;
144
145 self.forest.mark_dirty(node_id);
146 Ok(())
147 }
148
149 pub fn remove_child(&mut self, node: Node, child: Node) -> Result<Node, Error> {
150 let node_id = self.find_node(node)?;
151 let child_id = self.find_node(child)?;
152
153 let prev_id = unsafe { self.forest.remove_child(node_id, child_id) };
154 Ok(self.ids_to_nodes[&prev_id])
155 }
156
157 pub fn remove_child_at_index(&mut self, node: Node, index: usize) -> Result<Node, Error> {
158 let node_id = self.find_node(node)?;
159 // TODO: index check
160
161 let prev_id = self.forest.remove_child_at_index(node_id, index);
162 Ok(self.ids_to_nodes[&prev_id])
163 }
164
165 pub fn replace_child_at_index(&mut self, node: Node, index: usize, child: Node) -> Result<Node, Error> {
166 let node_id = self.find_node(node)?;
167 let child_id = self.find_node(child)?;
168 // TODO: index check
169
170 self.forest.parents[child_id].push(node_id);
171 let old_child = core::mem::replace(&mut self.forest.children[node_id][index], child_id);
172 self.forest.parents[old_child].retain(|p| *p != node_id);
173
174 self.forest.mark_dirty(node_id);
175
176 Ok(self.ids_to_nodes[&old_child])
177 }
178
179 pub fn children(&self, node: Node) -> Result<Vec<Node>, Error> {
180 let id = self.find_node(node)?;
181 Ok(self.forest.children[id].iter().map(|child| self.ids_to_nodes[child]).collect())
182 }
183
184 pub fn child_count(&self, node: Node) -> Result<usize, Error> {
185 let id = self.find_node(node)?;
186 Ok(self.forest.children[id].len())
187 }
188
189 pub fn set_style(&mut self, node: Node, style: Style) -> Result<(), Error> {
190 let id = self.find_node(node)?;
191 self.forest.nodes[id].style = style;
192 self.forest.mark_dirty(id);
193 Ok(())
194 }
195
196 pub fn style(&self, node: Node) -> Result<&Style, Error> {
197 let id = self.find_node(node)?;
198 Ok(&self.forest.nodes[id].style)
199 }
200
201 pub fn layout(&self, node: Node) -> Result<&Layout, Error> {
202 let id = self.find_node(node)?;
203 Ok(&self.forest.nodes[id].layout)
204 }
205
206 pub fn mark_dirty(&mut self, node: Node) -> Result<(), Error> {
207 let id = self.find_node(node)?;
208 self.forest.mark_dirty(id);
209 Ok(())
210 }
211
212 pub fn dirty(&self, node: Node) -> Result<bool, Error> {
213 let id = self.find_node(node)?;
214 Ok(self.forest.nodes[id].is_dirty)
215 }
216
217 pub fn compute_layout(&mut self, node: Node, size: Size<Number>) -> Result<(), Error> {
218 let id = self.find_node(node)?;
219 self.forest.compute_layout(id, size)
220 }
221}
222
223impl Drop for Stretch {
224 fn drop(&mut self) {
225 INSTANCE_ALLOCATOR.free(&[self.id]);
226 }
227}