gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 709HTML 662Markdown 12TOML 62348 Definitions

⎇ 0582914f5abfde3aaaafa507a3806f21f0e5f81a src/forest.rs Rust · 178 lines · 5.4 KB History Who touched what raw

Enable compilation of crate for no_std again. 0582914f5 · David Flemström ·

1//! Forest - ECS like datastructure for storing node trees.
2//!
3//! Backing datastructure for `Stretch` structs.
4
5#[cfg(not(feature = "std"))]
6use alloc::vec::Vec;
7
8use crate::geometry::Size;
9use crate::id::NodeId;
10use crate::node::MeasureFunc;
11use crate::number::Number;
12use crate::result::{Cache, Layout};
13use crate::style::Style;
14use crate::Error;
15
16pub(crate) struct NodeData {
17    pub(crate) style: Style,
18    pub(crate) measure: Option<MeasureFunc>,
19    pub(crate) layout: Layout,
20    pub(crate) layout_cache: Option<Cache>,
21    pub(crate) is_dirty: bool,
22}
23
24impl NodeData {
25    fn new_leaf(style: Style, measure: MeasureFunc) -> Self {
26        NodeData { style, measure: Some(measure), layout_cache: None, layout: Layout::new(), is_dirty: true }
27    }
28
29    fn new(style: Style) -> Self {
30        NodeData { style, measure: None, layout_cache: None, layout: Layout::new(), is_dirty: true }
31    }
32}
33
34pub(crate) struct Forest {
35    pub(crate) nodes: Vec<NodeData>,
36    pub(crate) children: Vec<Vec<NodeId>>,
37    pub(crate) parents: Vec<Vec<NodeId>>,
38}
39
40impl Forest {
41    pub fn with_capacity(capacity: usize) -> Self {
42        Forest {
43            nodes: Vec::with_capacity(capacity),
44            children: Vec::with_capacity(capacity),
45            parents: Vec::with_capacity(capacity),
46        }
47    }
48
49    pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> NodeId {
50        let id = self.nodes.len();
51        self.nodes.push(NodeData::new_leaf(style, measure));
52        self.children.push(Vec::with_capacity(0));
53        self.parents.push(Vec::with_capacity(1));
54        id
55    }
56
57    pub fn new_node(&mut self, style: Style, children: Vec<NodeId>) -> NodeId {
58        let id = self.nodes.len();
59        for child in &children {
60            self.parents[*child].push(id);
61        }
62        self.nodes.push(NodeData::new(style));
63        self.children.push(children);
64        self.parents.push(Vec::with_capacity(1));
65        id
66    }
67
68    pub fn add_child(&mut self, node: NodeId, child: NodeId) {
69        self.parents[child].push(node);
70        self.children[node].push(child);
71        self.mark_dirty(node)
72    }
73
74    pub fn clear(&mut self) {
75        self.nodes.clear();
76        self.children.clear();
77        self.parents.clear();
78    }
79
80    /// Removes a node and swaps with the last node.
81    pub fn swap_remove(&mut self, node: NodeId) -> Option<NodeId> {
82        self.nodes.swap_remove(node);
83
84        // Now the last element is swapped in at index `node`.
85        if self.nodes.is_empty() {
86            self.children.clear();
87            self.parents.clear();
88            return None;
89        }
90
91        // Remove old node as parent from all its chilren.
92        for child in &self.children[node] {
93            let parents_child = &mut self.parents[*child];
94            let mut pos = 0;
95            while pos < parents_child.len() {
96                if parents_child[pos] == node {
97                    parents_child.swap_remove(pos);
98                } else {
99                    pos += 1;
100                }
101            }
102        }
103
104        // Remove old node as child from all its parents.
105        for parent in &self.parents[node] {
106            let childrens_parent = &mut self.children[*parent];
107            let mut pos = 0;
108            while pos < childrens_parent.len() {
109                if childrens_parent[pos] == node {
110                    childrens_parent.swap_remove(pos);
111                } else {
112                    pos += 1;
113                }
114            }
115        }
116
117        let last = self.nodes.len();
118
119        return if last != node {
120            // Update ids for every child of the swapped in node.
121            for child in &self.children[last] {
122                for parent in &mut self.parents[*child] {
123                    if *parent == last {
124                        *parent = node;
125                    }
126                }
127            }
128
129            // Update ids for every parent of the swapped in node.
130            for parent in &self.parents[last] {
131                for child in &mut self.children[*parent] {
132                    if *child == last {
133                        *child = node;
134                    }
135                }
136            }
137
138            self.children.swap_remove(node);
139            self.parents.swap_remove(node);
140
141            Some(last)
142        } else {
143            self.children.swap_remove(node);
144            self.parents.swap_remove(node);
145            None
146        };
147    }
148
149    pub unsafe fn remove_child(&mut self, node: NodeId, child: NodeId) -> NodeId {
150        let index = self.children[node].iter().position(|n| *n == child).unwrap();
151        self.remove_child_at_index(node, index)
152    }
153
154    pub fn remove_child_at_index(&mut self, node: NodeId, index: usize) -> NodeId {
155        let child = self.children[node].remove(index);
156        self.parents[child].retain(|p| *p != node);
157        self.mark_dirty(node);
158        child
159    }
160
161    pub fn mark_dirty(&mut self, node: NodeId) {
162        fn mark_dirty_impl(nodes: &mut Vec<NodeData>, parents: &Vec<Vec<NodeId>>, node_id: NodeId) {
163            let node = &mut nodes[node_id];
164            node.layout_cache = None;
165            node.is_dirty = true;
166
167            for parent in &parents[node_id] {
168                mark_dirty_impl(nodes, parents, *parent);
169            }
170        }
171
172        mark_dirty_impl(&mut self.nodes, &self.parents, node);
173    }
174
175    pub fn compute_layout(&mut self, node: NodeId, size: Size<Number>) -> Result<(), Error> {
176        self.compute(node, size).map_err(|err| Error::Measure(err))
177    }
178}