Semántico sayk'uy · 28
examples/custom_tree_owned_partial.rs
examples/custom_tree_owned_unsafe.rs
examples/custom_tree_vec.rs
diff --git a/examples/custom_tree_owned_partial.rs b/examples/custom_tree_owned_partial.rs
index 430381ef7..7cae4b6ae 100644
--- a/examples/custom_tree_owned_partial.rs
+++ b/examples/custom_tree_owned_partial.rs
@@ -13,7 +13,7 @@ use common::image::{image_measure_function, ImageContext};
use common::text::{text_measure_function, FontMetrics, TextContext, WritingMode, LOREM_IPSUM};
use taffy::{
compute_cached_layout, compute_flexbox_layout, compute_grid_layout, compute_leaf_layout, compute_root_layout,
- prelude::*, Cache, Layout, Style,
+ prelude::*, Cache, CacheTree, Layout, Style,
};
#[derive(Debug, Copy, Clone)]
@@ -138,11 +138,6 @@ impl taffy::LayoutPartialTree for Node {
where
Self: 'a;
- type CacheMut<'b>
- = &'b mut Cache
- where
- Self: 'b;
-
fn get_core_container_style(&self, node_id: NodeId) -> Self::CoreContainerStyle<'_> {
&self.node_from_id(node_id).style
}
@@ -151,10 +146,6 @@ impl taffy::LayoutPartialTree for Node {
self.node_from_id_mut(node_id).layout = *layout
}
- fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache {
- &mut self.node_from_id_mut(node_id).cache
- }
-
fn compute_child_layout(&mut self, node_id: NodeId, inputs: taffy::tree::LayoutInput) -> taffy::tree::LayoutOutput {
compute_cached_layout(self, node_id, inputs, |parent, node_id, inputs| {
let node = parent.node_from_id_mut(node_id);
@@ -179,6 +170,33 @@ impl taffy::LayoutPartialTree for Node {
}
}
+impl CacheTree for Node {
+ fn cache_get(
+ &self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: taffy::RunMode,
+ ) -> Option<taffy::LayoutOutput> {
+ self.node_from_id(node_id).cache.get(known_dimensions, available_space, run_mode)
+ }
+
+ fn cache_store(
+ &mut self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: taffy::RunMode,
+ layout_output: taffy::LayoutOutput,
+ ) {
+ self.node_from_id_mut(node_id).cache.store(known_dimensions, available_space, run_mode, layout_output)
+ }
+
+ fn cache_clear(&mut self, node_id: NodeId) {
+ self.node_from_id_mut(node_id).cache.clear()
+ }
+}
+
impl taffy::LayoutFlexboxContainer for Node {
type FlexboxContainerStyle<'a>
= &'a Style
diff --git a/examples/custom_tree_owned_unsafe.rs b/examples/custom_tree_owned_unsafe.rs
index ce6cd28c0..753424b06 100644
--- a/examples/custom_tree_owned_unsafe.rs
+++ b/examples/custom_tree_owned_unsafe.rs
@@ -8,7 +8,7 @@ use taffy::tree::Cache;
use taffy::util::print_tree;
use taffy::{
compute_cached_layout, compute_flexbox_layout, compute_grid_layout, compute_leaf_layout, compute_root_layout,
- prelude::*, round_layout,
+ prelude::*, round_layout, CacheTree,
};
#[derive(Debug, Copy, Clone)]
@@ -135,11 +135,6 @@ impl LayoutPartialTree for StatelessLayoutTree {
where
Self: 'a;
- type CacheMut<'b>
- = &'b mut Cache
- where
- Self: 'b;
-
fn get_core_container_style(&self, node_id: NodeId) -> Self::CoreContainerStyle<'_> {
unsafe { &node_from_id(node_id).style }
}
@@ -148,10 +143,6 @@ impl LayoutPartialTree for StatelessLayoutTree {
unsafe { node_from_id_mut(node_id).unrounded_layout = *layout };
}
- fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache {
- unsafe { &mut node_from_id_mut(node_id).cache }
- }
-
fn compute_child_layout(&mut self, node_id: NodeId, inputs: taffy::tree::LayoutInput) -> taffy::tree::LayoutOutput {
compute_cached_layout(self, node_id, inputs, |tree, node_id, inputs| {
let node = unsafe { node_from_id_mut(node_id) };
@@ -176,6 +167,33 @@ impl LayoutPartialTree for StatelessLayoutTree {
}
}
+impl CacheTree for StatelessLayoutTree {
+ fn cache_get(
+ &self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: taffy::RunMode,
+ ) -> Option<taffy::LayoutOutput> {
+ unsafe { node_from_id(node_id) }.cache.get(known_dimensions, available_space, run_mode)
+ }
+
+ fn cache_store(
+ &mut self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: taffy::RunMode,
+ layout_output: taffy::LayoutOutput,
+ ) {
+ unsafe { node_from_id_mut(node_id) }.cache.store(known_dimensions, available_space, run_mode, layout_output)
+ }
+
+ fn cache_clear(&mut self, node_id: NodeId) {
+ unsafe { node_from_id_mut(node_id) }.cache.clear()
+ }
+}
+
impl taffy::LayoutFlexboxContainer for StatelessLayoutTree {
type FlexboxContainerStyle<'a>
= &'a Style
diff --git a/examples/custom_tree_vec.rs b/examples/custom_tree_vec.rs
index a2cf7e00b..89ed08584 100644
--- a/examples/custom_tree_vec.rs
+++ b/examples/custom_tree_vec.rs
@@ -7,7 +7,7 @@ use common::text::{text_measure_function, FontMetrics, TextContext, WritingMode,
use taffy::util::print_tree;
use taffy::{
compute_cached_layout, compute_flexbox_layout, compute_grid_layout, compute_leaf_layout, compute_root_layout,
- prelude::*, round_layout, Cache,
+ prelude::*, round_layout, Cache, CacheTree,
};
#[derive(Debug, Copy, Clone)]
@@ -144,11 +144,6 @@ impl taffy::LayoutPartialTree for Tree {
where
Self: 'a;
- type CacheMut<'b>
- = &'b mut Cache
- where
- Self: 'b;
-
fn get_core_container_style(&self, node_id: NodeId) -> Self::CoreContainerStyle<'_> {
&self.node_from_id(node_id).style
}
@@ -157,10 +152,6 @@ impl taffy::LayoutPartialTree for Tree {
self.node_from_id_mut(node_id).unrounded_layout = *layout;
}
- fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache {
- &mut self.node_from_id_mut(node_id).cache
- }
-
fn compute_child_layout(&mut self, node_id: NodeId, inputs: taffy::tree::LayoutInput) -> taffy::tree::LayoutOutput {
compute_cached_layout(self, node_id, inputs, |tree, node_id, inputs| {
let node = tree.node_from_id_mut(node_id);
@@ -185,6 +176,33 @@ impl taffy::LayoutPartialTree for Tree {
}
}
+impl CacheTree for Tree {
+ fn cache_get(
+ &self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: taffy::RunMode,
+ ) -> Option<taffy::LayoutOutput> {
+ self.node_from_id(node_id).cache.get(known_dimensions, available_space, run_mode)
+ }
+
+ fn cache_store(
+ &mut self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: taffy::RunMode,
+ layout_output: taffy::LayoutOutput,
+ ) {
+ self.node_from_id_mut(node_id).cache.store(known_dimensions, available_space, run_mode, layout_output)
+ }
+
+ fn cache_clear(&mut self, node_id: NodeId) {
+ self.node_from_id_mut(node_id).cache.clear()
+ }
+}
+
impl taffy::LayoutFlexboxContainer for Tree {
type FlexboxContainerStyle<'a>
= &'a Style
diff --git a/src/compute/mod.rs b/src/compute/mod.rs
index 1c6ba62a5..42c3b03f3 100644
--- a/src/compute/mod.rs
+++ b/src/compute/mod.rs
@@ -52,7 +52,7 @@ use crate::tree::{
use crate::util::debug::{debug_log, debug_log_node, debug_pop_node, debug_push_node};
use crate::util::sys::round;
use crate::util::ResolveOrZero;
-use crate::{BoxSizing, MaybeMath, MaybeResolve};
+use crate::{BoxSizing, CacheTree, MaybeMath, MaybeResolve};
/// Compute layout for the root node in the tree
pub fn compute_root_layout(tree: &mut impl LayoutPartialTree, root: NodeId, available_space: Size<AvailableSpace>) {
@@ -153,7 +153,7 @@ pub fn compute_root_layout(tree: &mut impl LayoutPartialTree, root: NodeId, avai
///
/// Uses the provided closure to compute the layout (and then stores the result in the cache) if no cached layout is found.
#[inline(always)]
-pub fn compute_cached_layout<Tree: LayoutPartialTree + ?Sized, ComputeFunction>(
+pub fn compute_cached_layout<Tree: CacheTree + ?Sized, ComputeFunction>(
tree: &mut Tree,
node: NodeId,
inputs: LayoutInput,
@@ -166,7 +166,7 @@ where
let LayoutInput { known_dimensions, available_space, run_mode, .. } = inputs;
// First we check if we have a cached result for the given input
- let cache_entry = tree.get_cache_mut(node).get(known_dimensions, available_space, run_mode);
+ let cache_entry = tree.cache_get(node, known_dimensions, available_space, run_mode);
if let Some(cached_size_and_baselines) = cache_entry {
debug_log_node!(known_dimensions, inputs.parent_size, available_space, run_mode, inputs.sizing_mode);
debug_log!("RESULT (CACHED)", dbg:cached_size_and_baselines.size);
@@ -179,7 +179,7 @@ where
let computed_size_and_baselines = compute_uncached(tree, node, inputs);
// Cache result
- tree.get_cache_mut(node).store(known_dimensions, available_space, run_mode, computed_size_and_baselines);
+ tree.cache_store(node, known_dimensions, available_space, run_mode, computed_size_and_baselines);
debug_log!("RESULT", dbg:computed_size_and_baselines.size);
debug_pop_node!();
@@ -258,9 +258,9 @@ pub fn round_layout(tree: &mut impl RoundTree, node_id: NodeId) {
/// Creates a layout for this node and its children, recursively.
/// Each hidden node has zero size and is placed at the origin
-pub fn compute_hidden_layout(tree: &mut impl LayoutPartialTree, node: NodeId) -> LayoutOutput {
+pub fn compute_hidden_layout(tree: &mut (impl LayoutPartialTree + CacheTree), node: NodeId) -> LayoutOutput {
// Clear cache and set zeroed-out layout for the node
- tree.get_cache_mut(node).clear();
+ tree.cache_clear(node);
tree.set_unrounded_layout(node, &Layout::with_order(0));
// Perform hidden layout on all children
diff --git a/src/tree/taffy_tree.rs b/src/tree/taffy_tree.rs
index 732acf99a..69bcc43c4 100644
--- a/src/tree/taffy_tree.rs
+++ b/src/tree/taffy_tree.rs
@@ -17,6 +17,7 @@ use crate::util::sys::{new_vec_with_capacity, ChildrenVec, Vec};
use crate::compute::{
compute_cached_layout, compute_hidden_layout, compute_leaf_layout, compute_root_layout, round_layout,
};
+use crate::CacheTree;
#[cfg(feature = "block_layout")]
use crate::{compute::compute_block_layout, LayoutBlockContainer};
#[cfg(feature = "flexbox")]
@@ -190,6 +191,34 @@ impl<NodeContext> TraversePartialTree for TaffyTree<NodeContext> {
// TraverseTree impl for TaffyTree
impl<NodeContext> TraverseTree for TaffyTree<NodeContext> {}
+// CacheTree impl for TaffyTree
+impl<NodeContext> CacheTree for TaffyTree<NodeContext> {
+ fn cache_get(
+ &self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: RunMode,
+ ) -> Option<LayoutOutput> {
+ self.nodes[node_id.into()].cache.get(known_dimensions, available_space, run_mode)
+ }
+
+ fn cache_store(
+ &mut self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: RunMode,
+ layout_output: LayoutOutput,
+ ) {
+ self.nodes[node_id.into()].cache.store(known_dimensions, available_space, run_mode, layout_output)
+ }
+
+ fn cache_clear(&mut self, node_id: NodeId) {
+ self.nodes[node_id.into()].cache.clear()
+ }
+}
+
// PrintTree impl for TaffyTree
impl<NodeContext> PrintTree for TaffyTree<NodeContext> {
#[inline(always)]
@@ -284,21 +313,12 @@ where
= &'a Style
where
Self: 'a;
- type CacheMut<'b>
- = &'b mut Cache
- where
- Self: 'b;
#[inline(always)]
fn get_core_container_style(&self, node_id: NodeId) -> Self::CoreContainerStyle<'_> {
&self.taffy.nodes[node_id.into()].style
}
- #[inline(always)]
- fn get_cache_mut(&mut self, node: NodeId) -> &mut Cache {
- &mut self.taffy.nodes[node.into()].cache
- }
-
#[inline(always)]
fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout) {
self.taffy.nodes[node_id.into()].unrounded_layout = *layout;
@@ -355,6 +375,37 @@ where
}
}
+impl<NodeContext, MeasureFunction> CacheTree for TaffyView<'_, NodeContext, MeasureFunction>
+where
+ MeasureFunction:
+ FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>, &Style) -> Size<f32>,
+{
+ fn cache_get(
+ &self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: RunMode,
+ ) -> Option<LayoutOutput> {
+ self.taffy.nodes[node_id.into()].cache.get(known_dimensions, available_space, run_mode)
+ }
+
+ fn cache_store(
+ &mut self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: RunMode,
+ layout_output: LayoutOutput,
+ ) {
+ self.taffy.nodes[node_id.into()].cache.store(known_dimensions, available_space, run_mode, layout_output)
+ }
+
+ fn cache_clear(&mut self, node_id: NodeId) {
+ self.taffy.nodes[node_id.into()].cache.clear()
+ }
+}
+
#[cfg(feature = "block_layout")]
impl<NodeContext, MeasureFunction> LayoutBlockContainer for TaffyView<'_, NodeContext, MeasureFunction>
where
@@ -804,7 +855,7 @@ impl<NodeContext> TaffyTree<NodeContext> {
/// Returns an instance of LayoutTree representing the TaffyTree
#[cfg(test)]
- pub(crate) fn as_layout_tree(&mut self) -> impl LayoutPartialTree + '_ {
+ pub(crate) fn as_layout_tree(&mut self) -> impl LayoutPartialTree + CacheTree + '_ {
TaffyView { taffy: self, measure_function: |_, _, _, _, _| Size::ZERO }
}
}
diff --git a/src/tree/traits.rs b/src/tree/traits.rs
index 2642b0749..d70cc7416 100644
--- a/src/tree/traits.rs
+++ b/src/tree/traits.rs
@@ -126,7 +126,7 @@
//! }
//! ```
//!
-use super::{Cache, Layout, LayoutInput, LayoutOutput, NodeId, RequestedAxis, RunMode, SizingMode};
+use super::{Layout, LayoutInput, LayoutOutput, NodeId, RequestedAxis, RunMode, SizingMode};
use crate::geometry::{AbsoluteAxis, Line, Size};
use crate::style::{AvailableSpace, CoreStyle};
#[cfg(feature = "flexbox")]
@@ -135,7 +135,6 @@ use crate::style::{FlexboxContainerStyle, FlexboxItemStyle};
use crate::style::{GridContainerStyle, GridItemStyle};
#[cfg(feature = "block_layout")]
use crate::{BlockContainerStyle, BlockItemStyle};
-use core::ops::{Deref, DerefMut};
/// Taffy's abstraction for downward tree traversal.
///
@@ -173,25 +172,43 @@ pub trait LayoutPartialTree: TraversePartialTree {
where
Self: 'a;
- /// A mutable reference to the cache. This is an associated type to allow for different
- /// types of mutable reference such as mutex or refcell guards
- type CacheMut<'b>: Deref<Target = Cache> + DerefMut
- where
- Self: 'b;
-
/// Get core style
fn get_core_container_style(&self, node_id: NodeId) -> Self::CoreContainerStyle<'_>;
/// Set the node's unrounded layout
fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout);
- /// Get a mutable reference to the [`Cache`] for this node.
- fn get_cache_mut(&mut self, node_id: NodeId) -> Self::CacheMut<'_>;
-
/// Compute the specified node's size or full layout given the specified constraints
fn compute_child_layout(&mut self, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput;
}
+/// Trait used by the `compute_cached_layout` method which allows cached layout results to be stored and retrieved.
+///
+/// The `Cache` struct implements a per-node cache that is compatible with this trait.
+pub trait CacheTree {
+ /// Try to retrieve a cached result from the cache
+ fn cache_get(
+ &self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: RunMode,
+ ) -> Option<LayoutOutput>;
+
+ /// Store a computed size in the cache
+ fn cache_store(
+ &mut self,
+ node_id: NodeId,
+ known_dimensions: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ run_mode: RunMode,
+ layout_output: LayoutOutput,
+ );
+
+ /// Clear all cache entries for the node
+ fn cache_clear(&mut self, node_id: NodeId);
+}
+
/// Trait used by the `round_layout` method which takes a tree of unrounded float-valued layouts and performs
/// rounding to snap the values to the pixel grid.
///