tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 501HTML 254C 19JavaScript 81414 Sutichaykuna

⎇ fbc09ab4330f07896fd37956f2f6946fa2eb30bf src/node.rs Rust · 248 siq'ikuna · 7.6 KB Ñawpa willay Pi imata llamkarqan ch'uya

Remove Allocator::free (#105) fbc09ab43 · Alice Cecile ·

1use crate::forest::Forest;
2use crate::geometry::Size;
3use crate::layout::Layout;
4use crate::number::Number;
5use crate::style::Style;
6#[cfg(any(feature = "std", feature = "alloc"))]
7use crate::sys::Box;
8use crate::sys::{new_map_with_capacity, ChildrenVec, Map, Vec};
9use crate::Error;
10use core::sync::atomic::{AtomicUsize, Ordering};
11
12pub enum MeasureFunc {
13    Raw(fn(Size<Number>) -> Size<f32>),
14    #[cfg(any(feature = "std", feature = "alloc"))]
15    Boxed(Box<dyn Fn(Size<Number>) -> Size<f32>>),
16}
17
18/// Global sprawl instance id allocator.
19static INSTANCE_ALLOCATOR: Allocator = 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,
25    local: Id,
26}
27
28pub struct Sprawl {
29    id: Id,
30    nodes: Allocator,
31    nodes_to_ids: Map<Node, NodeId>,
32    ids_to_nodes: Map<NodeId, Node>,
33    forest: Forest,
34}
35
36impl Default for Sprawl {
37    fn default() -> Self {
38        Self::with_capacity(16)
39    }
40}
41
42impl Sprawl {
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: Allocator::new(),
51            nodes_to_ids: new_map_with_capacity(capacity),
52            ids_to_nodes: 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    // 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: &[Node]) -> Result<Node, Error> {
83        let node = self.allocate_node();
84        let children =
85            children.iter().map(|child| self.find_node(*child)).collect::<Result<ChildrenVec<_>, Error>>()?;
86        let id = self.forest.new_node(style, children);
87        self.add_node(node, id);
88        Ok(node)
89    }
90
91    /// Removes all nodes.
92    ///
93    /// All associated nodes will be invalid.
94    pub fn clear(&mut self) {
95        self.nodes_to_ids.clear();
96        self.ids_to_nodes.clear();
97        self.forest.clear();
98    }
99
100    /// Remove nodes.
101    pub fn remove(&mut self, node: Node) {
102        let id = if let Ok(id) = self.find_node(node) { id } else { return };
103
104        self.nodes_to_ids.remove(&node);
105        self.ids_to_nodes.remove(&id);
106
107        if let Some(new_id) = self.forest.swap_remove(id) {
108            let new = self.ids_to_nodes.remove(&new_id).unwrap();
109            let _ = self.nodes_to_ids.insert(new, id);
110            let _ = self.ids_to_nodes.insert(id, new);
111        }
112    }
113
114    pub fn set_measure(&mut self, node: Node, measure: Option<MeasureFunc>) -> Result<(), Error> {
115        let id = self.find_node(node)?;
116        self.forest.nodes[id].measure = measure;
117        self.forest.mark_dirty(id);
118        Ok(())
119    }
120
121    pub fn add_child(&mut self, node: Node, child: Node) -> Result<(), Error> {
122        let node_id = self.find_node(node)?;
123        let child_id = self.find_node(child)?;
124
125        self.forest.add_child(node_id, child_id);
126        Ok(())
127    }
128
129    pub fn set_children(&mut self, node: Node, children: &[Node]) -> Result<(), Error> {
130        let node_id = self.find_node(node)?;
131        let children_id = children.iter().map(|child| self.find_node(*child)).collect::<Result<ChildrenVec<_>, _>>()?;
132
133        // Remove node as parent from all its current children.
134        for child in &self.forest.children[node_id] {
135            self.forest.parents[*child].retain(|p| *p != node_id);
136        }
137
138        // Build up relation node <-> child
139        for child in &children_id {
140            self.forest.parents[*child].push(node_id);
141        }
142        self.forest.children[node_id] = children_id;
143
144        self.forest.mark_dirty(node_id);
145        Ok(())
146    }
147
148    pub fn remove_child(&mut self, node: Node, child: Node) -> Result<Node, Error> {
149        let node_id = self.find_node(node)?;
150        let child_id = self.find_node(child)?;
151
152        let prev_id = self.forest.remove_child(node_id, child_id);
153        Ok(self.ids_to_nodes[&prev_id])
154    }
155
156    pub fn remove_child_at_index(&mut self, node: Node, index: usize) -> Result<Node, Error> {
157        let node_id = self.find_node(node)?;
158        // TODO: index check
159
160        let prev_id = self.forest.remove_child_at_index(node_id, index);
161        Ok(self.ids_to_nodes[&prev_id])
162    }
163
164    pub fn replace_child_at_index(&mut self, node: Node, index: usize, child: Node) -> Result<Node, Error> {
165        let node_id = self.find_node(node)?;
166        let child_id = self.find_node(child)?;
167        // TODO: index check
168
169        self.forest.parents[child_id].push(node_id);
170        let old_child = core::mem::replace(&mut self.forest.children[node_id][index], child_id);
171        self.forest.parents[old_child].retain(|p| *p != node_id);
172
173        self.forest.mark_dirty(node_id);
174
175        Ok(self.ids_to_nodes[&old_child])
176    }
177
178    pub fn children(&self, node: Node) -> Result<Vec<Node>, Error> {
179        let id = self.find_node(node)?;
180        Ok(self.forest.children[id].iter().map(|child| self.ids_to_nodes[child]).collect())
181    }
182
183    pub fn child_at_index(&self, node: Node, index: usize) -> Result<Node, Error> {
184        let id = self.find_node(node)?;
185        Ok(self.ids_to_nodes[&self.forest.children[id][index]])
186    }
187
188    pub fn child_count(&self, node: Node) -> Result<usize, Error> {
189        let id = self.find_node(node)?;
190        Ok(self.forest.children[id].len())
191    }
192
193    pub fn set_style(&mut self, node: Node, style: Style) -> Result<(), Error> {
194        let id = self.find_node(node)?;
195        self.forest.nodes[id].style = style;
196        self.forest.mark_dirty(id);
197        Ok(())
198    }
199
200    pub fn style(&self, node: Node) -> Result<&Style, Error> {
201        let id = self.find_node(node)?;
202        Ok(&self.forest.nodes[id].style)
203    }
204
205    /// Return this node layout relative to its parent
206    pub fn layout(&self, node: Node) -> Result<&Layout, Error> {
207        let id = self.find_node(node)?;
208        Ok(&self.forest.nodes[id].layout)
209    }
210
211    pub fn mark_dirty(&mut self, node: Node) -> Result<(), Error> {
212        let id = self.find_node(node)?;
213        self.forest.mark_dirty(id);
214        Ok(())
215    }
216
217    pub fn dirty(&self, node: Node) -> Result<bool, Error> {
218        let id = self.find_node(node)?;
219        Ok(self.forest.nodes[id].is_dirty)
220    }
221
222    pub fn compute_layout(&mut self, node: Node, size: Size<Number>) -> Result<(), Error> {
223        let id = self.find_node(node)?;
224        self.forest.compute_layout(id, size);
225        Ok(())
226    }
227}
228
229/// Internal node id.
230pub(crate) type NodeId = usize;
231
232#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
233#[cfg_attr(not(any(feature = "std", feature = "alloc")), derive(hash32_derive::Hash32))]
234pub(crate) struct Id(usize);
235
236pub(crate) struct Allocator {
237    new_id: AtomicUsize,
238}
239
240impl Allocator {
241    pub const fn new() -> Self {
242        Self { new_id: AtomicUsize::new(0) }
243    }
244
245    pub fn allocate(&self) -> Id {
246        Id(self.new_id.fetch_add(1, Ordering::Relaxed))
247    }
248}