tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 583HTML 275Markdown 8TOML 41586 Definitions

⎇ 17acee6ac4bdb1a9ad3b03105b8e5d5e04ed6dca src/node.rs Rust · 289 lines · 9.0 KB History Who touched what raw

Add a lower level node forest structure and adjust data layout 17acee6ac · msiglreith ·

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}