tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 583HTML 275Markdown 8TOML 41586 Definiciones

⎇ 586edff8ecf0901edccc7e34ed8548dffa88820b src/node.rs Rust · 232 líneas · 7.0 KB Historia Quién tocó qué crudo

Update deps and rust 586edff8e · Emil Sjölander ·

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 Default for Stretch {
41    fn default() -> Self {
42        Stretch::with_capacity(16)
43    }
44}
45
46impl Stretch {
47    pub fn new() -> Self {
48        Default::default()
49    }
50
51    pub fn with_capacity(capacity: usize) -> Self {
52        Stretch {
53            id: INSTANCE_ALLOCATOR.allocate(),
54            nodes: id::Allocator::new(),
55            nodes_to_ids: HashMap::with_capacity(capacity),
56            ids_to_nodes: HashMap::with_capacity(capacity),
57            forest: Forest::with_capacity(capacity),
58        }
59    }
60
61    fn allocate_node(&mut self) -> Node {
62        let local = self.nodes.allocate();
63        Node { instance: self.id, local }
64    }
65
66    fn add_node(&mut self, node: Node, id: NodeId) {
67        self.nodes_to_ids.insert(node, id);
68        self.ids_to_nodes.insert(id, node);
69    }
70
71    // Find node in the forest.
72    fn find_node(&self, node: Node) -> Result<NodeId, Error> {
73        match self.nodes_to_ids.get(&node) {
74            Some(id) => Ok(*id),
75            None => Err(Error::InvalidNode(node)),
76        }
77    }
78
79    pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> Result<Node, Error> {
80        let node = self.allocate_node();
81        let id = self.forest.new_leaf(style, measure);
82        self.add_node(node, id);
83        Ok(node)
84    }
85
86    pub fn new_node(&mut self, style: Style, children: Vec<Node>) -> Result<Node, Error> {
87        let node = self.allocate_node();
88        let children = children.iter().map(|child| self.find_node(*child)).collect::<Result<Vec<_>, Error>>()?;
89        let id = self.forest.new_node(style, children);
90        self.add_node(node, id);
91        Ok(node)
92    }
93
94    /// Removes all nodes.
95    ///
96    /// All associated nodes will be invalid.
97    pub fn clear(&mut self) {
98        for node in self.nodes_to_ids.keys() {
99            self.nodes.free(&[node.local]);
100        }
101        self.nodes_to_ids.clear();
102        self.ids_to_nodes.clear();
103        self.forest.clear();
104    }
105
106    /// Remove nodes.
107    pub fn remove(&mut self, node: Node) {
108        let id = if let Ok(id) = self.find_node(node) { id } else { return };
109
110        self.nodes_to_ids.remove(&node);
111        self.ids_to_nodes.remove(&id);
112
113        if let Some(new_id) = self.forest.swap_remove(id) {
114            let new = self.ids_to_nodes.remove(&new_id).unwrap();
115            self.nodes_to_ids.insert(new, id);
116            self.ids_to_nodes.insert(id, new);
117        }
118    }
119
120    pub fn set_measure(&mut self, node: Node, measure: Option<MeasureFunc>) -> Result<(), Error> {
121        let id = self.find_node(node)?;
122        self.forest.nodes[id].measure = measure;
123        self.forest.mark_dirty(id);
124        Ok(())
125    }
126
127    pub fn add_child(&mut self, node: Node, child: Node) -> Result<(), Error> {
128        let node_id = self.find_node(node)?;
129        let child_id = self.find_node(child)?;
130
131        self.forest.add_child(node_id, child_id);
132        Ok(())
133    }
134
135    pub fn set_children(&mut self, node: Node, children: Vec<Node>) -> Result<(), Error> {
136        let node_id = self.find_node(node)?;
137        let children_id = children.iter().map(|child| self.find_node(*child)).collect::<Result<Vec<_>, _>>()?;
138
139        // Remove node as parent from all its current children.
140        for child in &self.forest.children[node_id] {
141            self.forest.parents[*child].retain(|p| *p != node_id);
142        }
143
144        // Build up relation node <-> child
145        for child in &children_id {
146            self.forest.parents[*child].push(node_id);
147        }
148        self.forest.children[node_id] = children_id;
149
150        self.forest.mark_dirty(node_id);
151        Ok(())
152    }
153
154    pub fn remove_child(&mut self, node: Node, child: Node) -> Result<Node, Error> {
155        let node_id = self.find_node(node)?;
156        let child_id = self.find_node(child)?;
157
158        let prev_id = unsafe { self.forest.remove_child(node_id, child_id) };
159        Ok(self.ids_to_nodes[&prev_id])
160    }
161
162    pub fn remove_child_at_index(&mut self, node: Node, index: usize) -> Result<Node, Error> {
163        let node_id = self.find_node(node)?;
164        // TODO: index check
165
166        let prev_id = self.forest.remove_child_at_index(node_id, index);
167        Ok(self.ids_to_nodes[&prev_id])
168    }
169
170    pub fn replace_child_at_index(&mut self, node: Node, index: usize, child: Node) -> Result<Node, Error> {
171        let node_id = self.find_node(node)?;
172        let child_id = self.find_node(child)?;
173        // TODO: index check
174
175        self.forest.parents[child_id].push(node_id);
176        let old_child = core::mem::replace(&mut self.forest.children[node_id][index], child_id);
177        self.forest.parents[old_child].retain(|p| *p != node_id);
178
179        self.forest.mark_dirty(node_id);
180
181        Ok(self.ids_to_nodes[&old_child])
182    }
183
184    pub fn children(&self, node: Node) -> Result<Vec<Node>, Error> {
185        let id = self.find_node(node)?;
186        Ok(self.forest.children[id].iter().map(|child| self.ids_to_nodes[child]).collect())
187    }
188
189    pub fn child_count(&self, node: Node) -> Result<usize, Error> {
190        let id = self.find_node(node)?;
191        Ok(self.forest.children[id].len())
192    }
193
194    pub fn set_style(&mut self, node: Node, style: Style) -> Result<(), Error> {
195        let id = self.find_node(node)?;
196        self.forest.nodes[id].style = style;
197        self.forest.mark_dirty(id);
198        Ok(())
199    }
200
201    pub fn style(&self, node: Node) -> Result<&Style, Error> {
202        let id = self.find_node(node)?;
203        Ok(&self.forest.nodes[id].style)
204    }
205
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    }
226}
227
228impl Drop for Stretch {
229    fn drop(&mut self) {
230        INSTANCE_ALLOCATOR.free(&[self.id]);
231    }
232}