Skip to content

Commit

Permalink
Use per-node children cache
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed Sep 25, 2023
1 parent eda4487 commit d270760
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
6 changes: 6 additions & 0 deletions src/tree/node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! UI node types and related data structures.
//!
//! Layouts are composed of multiple nodes, which live in a tree-like data structure.
use core::cell::RefCell;

use crate::style::Style;
use crate::tree::Cache;
use crate::tree::Layout;
Expand Down Expand Up @@ -82,6 +84,9 @@ pub(crate) struct NodeData {

/// The cached results of the layout computation
pub(crate) cache: Cache,

/// The cached results of resolved children (factoring in Display::Contents)
pub(crate) children_cache: RefCell<Option<Vec<NodeId>>>,
}

impl NodeData {
Expand All @@ -91,6 +96,7 @@ impl NodeData {
Self {
style,
cache: Cache::new(),
children_cache: RefCell::new(None),
unrounded_layout: Layout::new(),
final_layout: Layout::new(),
needs_measure: false,
Expand Down
23 changes: 10 additions & 13 deletions src/tree/taffy_tree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ pub struct Taffy {
/// the layout algorithms during layout, while exposing the `NodeData.final_layout` when called by external users.
/// This allows us to fix <https://github.com/DioxusLabs/taffy/issues/501> without breaking backwards compatibility
pub(crate) is_layouting: bool,

/// Used to cache the resolved children of a node (taking into account `Display::contents`) during layout
/// so that repeated calls to the children method don't need to re-resolve the list.
node_children_cache: RefCell<(NodeId, Vec<NodeId>)>,
}

impl Default for Taffy {
Expand Down Expand Up @@ -98,13 +94,13 @@ impl LayoutTree for Taffy {

#[inline(always)]
fn children(&self, node: NodeId) -> Self::ChildIter<'_> {
let mut cache = self.node_children_cache.borrow_mut();
if cache.0 != node {
cache.1.clear();
cache.0 = node;
find_children_recursive(&mut cache.1, self, node);
let mut cache = self.nodes[node.into()].children_cache.borrow_mut();
if cache.is_none() {
let mut children = Vec::new();
find_children_recursive(&mut children, self, node);
*cache = Some(children);
}
RefCellVecIter { children: RefMut::map(cache, |c| &mut c.1), index: 0 }
RefCellVecIter { children: RefMut::map(cache, |c| c.as_mut().unwrap()), index: 0 }
}

#[inline(always)]
Expand Down Expand Up @@ -171,15 +167,17 @@ impl LayoutTree for Taffy {
sizing_mode: SizingMode,
vertical_margins_are_collapsible: Line<bool>,
) -> SizeBaselinesAndMargins {
perform_node_layout(
let result = perform_node_layout(
self,
node,
known_dimensions,
parent_size,
available_space,
sizing_mode,
vertical_margins_are_collapsible,
)
);
*self.nodes[node.into()].children_cache.borrow_mut() = None;
result
}
}

Expand All @@ -205,7 +203,6 @@ impl Taffy {
measure_funcs: SparseSecondaryMap::with_capacity(capacity),
config: TaffyConfig::default(),
is_layouting: false,
node_children_cache: RefCell::new((NodeId::new(0), Vec::new())),
}
}

Expand Down

0 comments on commit d270760

Please sign in to comment.