tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 497HTML 254C 19JavaScript 81329 Definiciones

⎇ 09eca732fb671db2a93f4adfec52108104549b7b src/node.rs Rust · 254 líneas · 7.3 KB Historia Quién tocó qué crudo

Improve error handling for index based API 09eca732f · 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;
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(crate) struct Storage<T>(HashMap<Node, T>);
31
32impl<T> Storage<T> {
33    pub fn new() -> Self {
34        Storage(HashMap::new())
35    }
36
37    pub fn get(&self, node: Node) -> Result<&T, Error> {
38        match self.0.get(&node) {
39            Some(v) => Ok(v),
40            None => Err(Error::InvalidNode(node)),
41        }
42    }
43
44    pub fn get_mut(&mut self, node: Node) -> Result<&mut T, Error> {
45        match self.0.get_mut(&node) {
46            Some(v) => Ok(v),
47            None => Err(Error::InvalidNode(node)),
48        }
49    }
50
51    pub fn insert(&mut self, node: Node, value: T) -> Option<T> {
52        self.0.insert(node, value)
53    }
54}
55
56impl<T> std::ops::Index<&Node> for Storage<T> {
57    type Output = T;
58
59    fn index(&self, idx: &Node) -> &T {
60        &(self.0)[idx]
61    }
62}
63
64pub struct Stretch {
65    id: id::Id,
66    nodes: id::Allocator,
67    pub(crate) style: Storage<Style>,
68    pub(crate) parents: Storage<Vec<Node>>,
69    pub(crate) children: Storage<Vec<Node>>,
70    pub(crate) measure: Storage<Option<MeasureFunc>>,
71    pub(crate) layout: Storage<Layout>,
72    pub(crate) layout_cache: Storage<Option<Cache>>,
73    pub(crate) is_dirty: Storage<bool>,
74}
75
76impl Stretch {
77    pub fn new() -> Self {
78        Stretch {
79            id: INSTANCE_ALLOCATOR.lock().unwrap().allocate(),
80            nodes: id::Allocator::new(),
81            style: Storage::new(),
82            parents: Storage::new(),
83            children: Storage::new(),
84            measure: Storage::new(),
85            layout: Storage::new(),
86            layout_cache: Storage::new(),
87            is_dirty: Storage::new(),
88        }
89    }
90
91    fn allocate_node(&mut self) -> Node {
92        let local = self.nodes.allocate();
93        Node { instance: self.id, local }
94    }
95
96    pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> Node {
97        let node = self.allocate_node();
98
99        self.style.insert(node, style);
100        self.parents.insert(node, Vec::with_capacity(1));
101        self.children.insert(node, Vec::with_capacity(0));
102        self.measure.insert(node, Some(measure));
103        self.layout.insert(node, Layout::new());
104        self.layout_cache.insert(node, None);
105        self.is_dirty.insert(node, true);
106
107        node
108    }
109
110    pub fn new_node(&mut self, style: Style, children: Vec<Node>) -> Result<Node, Error> {
111        let node = self.allocate_node();
112
113        for child in &children {
114            self.parents.get_mut(*child)?.push(node);
115        }
116
117        self.style.insert(node, style);
118        self.parents.insert(node, Vec::with_capacity(1));
119        self.children.insert(node, children);
120        self.measure.insert(node, None);
121        self.layout.insert(node, Layout::new());
122        self.layout_cache.insert(node, None);
123        self.is_dirty.insert(node, true);
124
125        Ok(node)
126    }
127
128    pub fn set_measure(&mut self, node: Node, measure: Option<MeasureFunc>) -> Result<(), Error> {
129        *self.measure.get_mut(node)? = measure;
130        self.mark_dirty(node)?;
131        Ok(())
132    }
133
134    pub fn add_child(&mut self, node: Node, child: Node) {
135        // child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
136        // self.0.borrow_mut().children.push(Rc::clone(&child.0));
137        // self.mark_dirty();
138
139        unimplemented!()
140    }
141
142    pub fn set_children(&mut self, node: Node, children: Vec<Node>) {
143        // for child in &self.0.borrow().children {
144        //     let position =
145        //         child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
146        //     child.borrow_mut().parents.remove(position);
147        // }
148
149        // self.0.borrow_mut().children = Vec::with_capacity(children.len());
150
151        // for child in children {
152        //     child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
153        //     self.0.borrow_mut().children.push(Rc::clone(&child.0));
154        // }
155
156        // self.mark_dirty();
157
158        unimplemented!()
159    }
160
161    pub fn remove_child(&mut self, node: Node, child: Node) -> Node {
162        // self.remove_child_at_index({
163        //     let parent = self.0.borrow();
164        //     parent.children.iter().position(|x| Rc::ptr_eq(&x, &child.0)).unwrap()
165        // })
166
167        unimplemented!()
168    }
169
170    pub fn remove_child_at_index(&mut self, node: Node, index: usize) -> Node {
171        // let child = {
172        //     let mut parent = self.0.borrow_mut();
173        //     let child = parent.children.remove(index);
174        //     let position =
175        //         child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
176        //     child.borrow_mut().parents.remove(position);
177        //     child
178        // };
179
180        // self.mark_dirty();
181        // Node(child)
182
183        unimplemented!()
184    }
185
186    pub fn replace_child_at_index(&mut self, node: Node, index: usize, child: Node) -> Node {
187        // child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
188        // let old_child = std::mem::replace(&mut self.0.borrow_mut().children[index], Rc::clone(&child.0));
189
190        // let position =
191        //     old_child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
192        // old_child.borrow_mut().parents.remove(position);
193
194        // self.mark_dirty();
195
196        // Node(old_child)
197
198        unimplemented!()
199    }
200
201    pub fn children(&self, node: Node) -> Result<Vec<Node>, Error> {
202        self.children.get(node).map(Clone::clone)
203    }
204
205    pub fn child_count(&self, node: Node) -> Result<usize, Error> {
206        self.children.get(node).map(Vec::len)
207    }
208
209    pub fn set_style(&mut self, node: Node, style: Style) {
210        // self.0.borrow_mut().style = style;
211        // self.mark_dirty();
212
213        unimplemented!()
214    }
215
216    pub fn style(&self, node: Node) -> Result<&Style, Error> {
217        self.style.get(node)
218    }
219
220    pub fn layout(&self, node: Node) -> Result<&Layout, Error> {
221        self.layout.get(node)
222    }
223
224    pub fn mark_dirty(&mut self, node: Node) -> Result<(), Error> {
225        // let mut node = self.0.borrow_mut();
226        // node.layout_cache = None;
227        // node.is_dirty = true;
228
229        // for parent in &node.parents {
230        //     if let Some(parent) = parent.upgrade() {
231        //         Node(parent).mark_dirty();
232        //     }
233        // }
234
235        unimplemented!()
236    }
237
238    pub fn dirty(&self, node: Node) -> Result<bool, Error> {
239        self.is_dirty.get(node).map(|v| *v)
240    }
241
242    pub fn compute_layout(&mut self, node: Node, size: Size<Number>) -> Result<(), Error> {
243        match self.layout.get(node) {
244            Ok(_) => self.compute(node, size).map_err(|err| Error::Measure(err)),
245            _ => Err(Error::InvalidNode(node)),
246        }
247    }
248}
249
250impl Drop for Stretch {
251    fn drop(&mut self) {
252        INSTANCE_ALLOCATOR.lock().unwrap().free(&[self.id]);
253    }
254}