gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 788HTML 740Markdown 12TOML 62535 Definitions

Replace refcounted nodes with index tree

943b719a212f0d8800d2b700b1df5662219e1cee · by msiglreith · (7 years ago) · parent cc263423e · browse the tree at this commit

Semantic delta · 26

src/node.rs

1 files · +167 −118

diff --git a/src/node.rs b/src/node.rs
index 5221c464a..b70d2c6a6 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -1,10 +1,8 @@
 #[cfg(not(feature = "std"))]
 use alloc::{vec, vec::Vec};
 
-use std::cell::RefCell;
+use std::collections::HashMap;
 use std::fmt;
-use std::rc::Rc;
-use std::rc::Weak;
 
 use crate::algo;
 use crate::geometry::Size;
@@ -14,161 +12,212 @@ use crate::style::*;
 
 type MeasureFunc = Box<Fn(Size<Number>) -> Result<Size<f32>>>;
 
-pub(crate) struct InternalNode {
-    pub(crate) style: Style,
-    pub(crate) parents: Vec<Weak<RefCell<InternalNode>>>,
-    pub(crate) children: Vec<Rc<RefCell<InternalNode>>>,
-    pub(crate) measure: Option<MeasureFunc>,
-    pub(crate) layout_cache: Option<Cache>,
-    pub(crate) is_dirty: bool,
+pub type NodeId = usize;
+type Storage<T> = HashMap<NodeId, T>;
+
+struct Allocator {
+    new_id: NodeId,
+    free_ids: Vec<NodeId>,
 }
 
-pub struct Node(Rc<RefCell<InternalNode>>);
-
-impl Node {
-    pub fn new_leaf(style: Style, measure: MeasureFunc) -> Node {
-        Node(Rc::new(RefCell::new(InternalNode {
-            style,
-            parents: Vec::with_capacity(1),
-            children: Vec::with_capacity(0),
-            measure: Some(measure),
-            layout_cache: None,
-            is_dirty: true,
-        })))
-    }
-
-    pub fn new(style: Style, children: Vec<&Node>) -> Node {
-        let parent = Node(Rc::new(RefCell::new(InternalNode {
-            style,
-            parents: Vec::with_capacity(1),
-            children: Vec::with_capacity(children.len()),
-            measure: None,
-            layout_cache: None,
-            is_dirty: true,
-        })));
-
-        for child in children {
-            child.0.borrow_mut().parents.push(Rc::downgrade(&parent.0));
-            parent.0.borrow_mut().children.push(Rc::clone(&child.0));
-        }
+impl Allocator {
+    pub fn new() -> Self {
+        Allocator { new_id: 0, free_ids: Vec::new() }
+    }
 
-        parent
+    pub fn allocate(&mut self) -> NodeId {
+        match self.free_ids.pop() {
+            Some(id) => id,
+            None => {
+                let id = self.new_id;
+                self.new_id += 1;
+                id
+            }
+        }
     }
+}
+
+pub struct Stretch {
+    nodes: Allocator,
+    pub(crate) style: Storage<Style>,
+    pub(crate) parents: Storage<Vec<NodeId>>,
+    pub(crate) children: Storage<Vec<NodeId>>,
+    pub(crate) measure: Storage<Option<MeasureFunc>>,
+    pub(crate) layout: Storage<Layout>,
+    pub(crate) layout_cache: Storage<Option<Cache>>,
+    pub(crate) is_dirty: Storage<bool>,
+}
 
-    pub fn set_measure(&mut self, measure: Option<MeasureFunc>) {
-        self.0.borrow_mut().measure = measure;
-        self.mark_dirty();
+impl Stretch {
+    pub fn new() -> Self {
+        Stretch {
+            nodes: Allocator::new(),
+            style: Storage::new(),
+            parents: Storage::new(),
+            children: Storage::new(),
+            measure: Storage::new(),
+            layout: Storage::new(),
+            layout_cache: Storage::new(),
+            is_dirty: Storage::new(),
+        }
     }
 
-    pub fn add_child(&mut self, child: &Node) {
-        child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
-        self.0.borrow_mut().children.push(Rc::clone(&child.0));
-        self.mark_dirty();
+    pub fn new_leaf(&mut self, style: Style, measure: MeasureFunc) -> NodeId {
+        // Node(Rc::new(RefCell::new(InternalNode {
+        //     style,
+        //     parents: Vec::with_capacity(1),
+        //     children: Vec::with_capacity(0),
+        //     measure: Some(measure),
+        //     layout_cache: None,
+        //     is_dirty: true,
+        // })))
+        unimplemented!()
     }
 
-    pub fn set_children(&mut self, children: Vec<&Node>) {
-        for child in &self.0.borrow().children {
-            let position =
-                child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
-            child.borrow_mut().parents.remove(position);
-        }
+    pub fn new_node(&mut self, style: Style, children: Vec<NodeId>) -> NodeId {
+        // let parent = Node(Rc::new(RefCell::new(InternalNode {
+        //     style,
+        //     parents: Vec::with_capacity(1),
+        //     children: Vec::with_capacity(children.len()),
+        //     measure: None,
+        //     layout_cache: None,
+        //     is_dirty: true,
+        // })));
 
-        self.0.borrow_mut().children = Vec::with_capacity(children.len());
+        // for child in children {
+        //     child.0.borrow_mut().parents.push(Rc::downgrade(&parent.0));
+        //     parent.0.borrow_mut().children.push(Rc::clone(&child.0));
+        // }
 
-        for child in children {
-            child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
-            self.0.borrow_mut().children.push(Rc::clone(&child.0));
-        }
+        // parent
 
-        self.mark_dirty();
+        unimplemented!()
     }
 
-    pub fn remove_child(&mut self, child: &Node) -> Node {
-        self.remove_child_at_index({
-            let parent = self.0.borrow();
-            parent.children.iter().position(|x| Rc::ptr_eq(&x, &child.0)).unwrap()
-        })
+    pub fn set_measure(&mut self, node: NodeId, measure: Option<MeasureFunc>) {
+        // self.0.borrow_mut().measure = measure;
+        // self.mark_dirty();
+
+        unimplemented!()
     }
 
-    pub fn remove_child_at_index(&mut self, index: usize) -> Node {
-        let child = {
-            let mut parent = self.0.borrow_mut();
-            let child = parent.children.remove(index);
-            let position =
-                child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
-            child.borrow_mut().parents.remove(position);
-            child
-        };
+    pub fn add_child(&mut self, node: NodeId, child: NodeId) {
+        // child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
+        // self.0.borrow_mut().children.push(Rc::clone(&child.0));
+        // self.mark_dirty();
 
-        self.mark_dirty();
-        Node(child)
+        unimplemented!()
     }
 
-    pub fn replace_child_at_index(&mut self, index: usize, child: &Node) -> Node {
-        child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
-        let old_child = std::mem::replace(&mut self.0.borrow_mut().children[index], Rc::clone(&child.0));
+    pub fn set_children(&mut self, node: NodeId, children: Vec<NodeId>) {
+        // for child in &self.0.borrow().children {
+        //     let position =
+        //         child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
+        //     child.borrow_mut().parents.remove(position);
+        // }
 
-        let position =
-            old_child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
-        old_child.borrow_mut().parents.remove(position);
+        // self.0.borrow_mut().children = Vec::with_capacity(children.len());
 
-        self.mark_dirty();
+        // for child in children {
+        //     child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
+        //     self.0.borrow_mut().children.push(Rc::clone(&child.0));
+        // }
 
-        Node(old_child)
+        // self.mark_dirty();
+
+        unimplemented!()
     }
 
-    pub fn children(&self) -> Vec<Node> {
-        let node = self.0.borrow_mut();
-        node.children.iter().map(|child| Node(Rc::clone(child))).collect()
+    pub fn remove_child(&mut self, node: NodeId, child: NodeId) -> NodeId {
+        // self.remove_child_at_index({
+        //     let parent = self.0.borrow();
+        //     parent.children.iter().position(|x| Rc::ptr_eq(&x, &child.0)).unwrap()
+        // })
+
+        unimplemented!()
+    }
+
+    pub fn remove_child_at_index(&mut self, node: NodeId, index: usize) -> NodeId {
+        // let child = {
+        //     let mut parent = self.0.borrow_mut();
+        //     let child = parent.children.remove(index);
+        //     let position =
+        //         child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
+        //     child.borrow_mut().parents.remove(position);
+        //     child
+        // };
+
+        // self.mark_dirty();
+        // Node(child)
+
+        unimplemented!()
     }
 
-    pub fn child_count(&self) -> usize {
-        let node = self.0.borrow_mut();
-        node.children.len()
+    pub fn replace_child_at_index(&mut self, node: NodeId, index: usize, child: NodeId) -> NodeId {
+        // child.0.borrow_mut().parents.push(Rc::downgrade(&self.0));
+        // let old_child = std::mem::replace(&mut self.0.borrow_mut().children[index], Rc::clone(&child.0));
+
+        // let position =
+        //     old_child.borrow().parents.iter().position(|x| Rc::ptr_eq(&x.upgrade().unwrap(), &self.0)).unwrap();
+        // old_child.borrow_mut().parents.remove(position);
+
+        // self.mark_dirty();
+
+        // Node(old_child)
+
+        unimplemented!()
     }
 
-    pub fn set_style(&mut self, style: Style) {
-        self.0.borrow_mut().style = style;
-        self.mark_dirty();
+    pub fn children(&self, node: NodeId) -> Vec<NodeId> {
+        // let node = self.0.borrow_mut();
+        // node.children.iter().map(|child| Node(Rc::clone(child))).collect()
+
+        unimplemented!()
     }
 
-    pub fn style(&self) -> Style {
-        self.0.borrow().style
+    pub fn child_count(&self, node: NodeId) -> usize {
+        // let node = self.0.borrow_mut();
+        // node.children.len()
+
+        unimplemented!()
     }
 
-    pub fn mark_dirty(&mut self) {
-        let mut node = self.0.borrow_mut();
-        node.layout_cache = None;
-        node.is_dirty = true;
+    pub fn set_style(&mut self, node: NodeId, style: Style) {
+        // self.0.borrow_mut().style = style;
+        // self.mark_dirty();
 
-        for parent in &node.parents {
-            if let Some(parent) = parent.upgrade() {
-                Node(parent).mark_dirty();
-            }
-        }
+        unimplemented!()
     }
 
-    pub fn dirty(&self) -> bool {
-        self.0.borrow().is_dirty
+    pub fn style(&self, node: NodeId) -> Style {
+        // self.0.borrow().style
+
+        unimplemented!()
     }
 
-    pub fn compute_layout(&self, size: Size<Number>) -> Result<Layout> {
-        algo::compute(&mut self.0.borrow_mut(), size)
+    pub fn mark_dirty(&mut self, node: NodeId) {
+        // let mut node = self.0.borrow_mut();
+        // node.layout_cache = None;
+        // node.is_dirty = true;
+
+        // for parent in &node.parents {
+        //     if let Some(parent) = parent.upgrade() {
+        //         Node(parent).mark_dirty();
+        //     }
+        // }
+
+        unimplemented!()
     }
-}
 
-impl fmt::Debug for Node {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let style = &self.0.borrow().style;
-        let children: Vec<_> = self.0.borrow().children.iter().map(|c| Node(Rc::clone(c))).collect();
-        write!(f, "Node {{ style: {:?}, children: {:?} }}", style, children)
+    pub fn dirty(&self, node: NodeId) -> bool {
+        // self.0.borrow().is_dirty
+
+        unimplemented!()
     }
-}
 
-impl PartialEq for Node {
-    fn eq(&self, other: &Node) -> bool {
-        Rc::ptr_eq(&self.0, &other.0)
+    pub fn compute_layout(&self, size: Size<Number>) -> Result<Layout> {
+        // algo::compute(&mut self.0.borrow_mut(), size)
+
+        unimplemented!()
     }
 }
-
-impl Eq for Node {}