Trampoline child measurement/layout through the `LayoutTree` trait (#427)
* Add measure_child_size and perform_child_layout methods to LayoutTree trait
* Force inlining of methods on internal implementation of LayoutTree
* Use import instead of fully qualified path
325413cd16d8e81598b36d2129c717d4c53baaa9 · por Nico Burns · 2023-04-10T17:27:50Z (hace 3 años) · padre 2ef49c4ae · ver el árbol en este commit
Delta semántico · 15
src/compute/grid/alignment.rs
src/compute/grid/track_sizing.rs
src/compute/grid/types/grid_item.rs
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index c72416232..eef31a4ba 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -2,7 +2,7 @@
use core::f32;
use crate::compute::common::alignment::compute_alignment_offset;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
+use crate::compute::LayoutAlgorithm;
use crate::geometry::{Point, Rect, Size};
use crate::layout::{Layout, RunMode, SizeAndBaselines, SizingMode};
use crate::math::MaybeMath;
@@ -382,14 +382,7 @@ fn compute_preliminary(
let child = tree.child(node, order);
if tree.style(child).display == Display::None {
*tree.layout_mut(child) = Layout::with_order(order as u32);
- GenericAlgorithm::perform_layout(
- tree,
- child,
- Size::NONE,
- Size::NONE,
- Size::MAX_CONTENT,
- SizingMode::InherentSize,
- );
+ tree.perform_child_layout(child, Size::NONE, Size::NONE, Size::MAX_CONTENT, SizingMode::InherentSize);
}
}
@@ -661,15 +654,15 @@ fn determine_flex_base_size(
ckd
};
- break 'flex_basis GenericAlgorithm::measure_size(
- tree,
- child.node,
- child_known_dimensions,
- child_parent_size,
- child_available_space,
- SizingMode::ContentSize,
- )
- .main(dir);
+ break 'flex_basis tree
+ .measure_child_size(
+ child.node,
+ child_known_dimensions,
+ child_parent_size,
+ child_available_space,
+ SizingMode::ContentSize,
+ )
+ .main(dir);
};
// Floor flex-basis by the padding_border_sum (floors inner_flex_basis at zero)
@@ -708,8 +701,7 @@ fn determine_flex_base_size(
let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
- GenericAlgorithm::measure_size(
- tree,
+ tree.measure_child_size(
child.node,
Size::NONE,
child_parent_size,
@@ -904,15 +896,15 @@ fn determine_container_main_size(
_ => {
// Either the min- or max- content size depending on which constraint we are sizing under.
// TODO: Optimise by using already computed values where available
- let content_main_size = GenericAlgorithm::measure_size(
- tree,
- item.node,
- Size::NONE,
- constants.node_inner_size,
- Size { width: main_axis_available_space, height: main_axis_available_space },
- SizingMode::InherentSize,
- )
- .main(constants.dir)
+ let content_main_size = tree
+ .measure_child_size(
+ item.node,
+ Size::NONE,
+ constants.node_inner_size,
+ Size { width: main_axis_available_space, height: main_axis_available_space },
+ SizingMode::InherentSize,
+ )
+ .main(constants.dir)
+ item.margin.main_axis_sum(constants.dir);
// This is somewhat bizarre in that it's asymetrical depending whether the flex container is a column or a row.
@@ -1223,8 +1215,7 @@ fn determine_hypothetical_cross_size(
.maybe_max(padding_border_sum);
let child_inner_cross = child_cross.unwrap_or_else(|| {
- GenericAlgorithm::measure_size(
- tree,
+ tree.measure_child_size(
child.node,
Size {
width: if constants.is_row { child.target_size.width.into() } else { child_cross },
@@ -1278,8 +1269,7 @@ fn calculate_children_base_lines(
continue;
}
- let measured_size_and_baselines = GenericAlgorithm::perform_layout(
- tree,
+ let measured_size_and_baselines = tree.perform_child_layout(
child.node,
Size {
width: if constants.is_row {
@@ -1714,8 +1704,7 @@ fn calculate_flex_item(
node_inner_size: Size<Option<f32>>,
direction: FlexDirection,
) {
- let preliminary_size_and_baselines = GenericAlgorithm::perform_layout(
- tree,
+ let preliminary_size_and_baselines = tree.perform_child_layout(
item.node,
item.target_size.map(|s| s.into()),
node_inner_size,
@@ -1900,8 +1889,7 @@ fn perform_absolute_layout_on_absolute_children(tree: &mut impl LayoutTree, node
known_dimensions = known_dimensions.maybe_apply_aspect_ratio(aspect_ratio).maybe_clamp(min_size, max_size);
}
- let measured_size_and_baselines = GenericAlgorithm::perform_layout(
- tree,
+ let measured_size_and_baselines = tree.perform_child_layout(
child,
known_dimensions,
constants.node_inner_size,
diff --git a/src/compute/grid/alignment.rs b/src/compute/grid/alignment.rs
index 0b85fb792..14a60bafe 100644
--- a/src/compute/grid/alignment.rs
+++ b/src/compute/grid/alignment.rs
@@ -2,7 +2,6 @@
use super::types::GridTrack;
use crate::axis::InBothAbsAxis;
use crate::compute::common::alignment::compute_alignment_offset;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
use crate::geometry::{Line, Point, Rect, Size};
use crate::layout::{Layout, SizingMode};
use crate::math::MaybeMath;
@@ -189,8 +188,7 @@ pub(super) fn align_and_position_item(
let Size { width, height } = Size { width, height }.maybe_clamp(min_size, max_size);
// Layout node
- let measured_size_and_baselines = GenericAlgorithm::perform_layout(
- tree,
+ let measured_size_and_baselines = tree.perform_child_layout(
node,
Size { width, height },
grid_area_size.map(Option::Some),
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index 09a91eb09..490a96310 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -24,7 +24,7 @@ pub(crate) use types::{GridCoordinate, GridLine, OriginZeroLine};
#[cfg(feature = "debug")]
use crate::debug::NODE_LOGGER;
-use super::{GenericAlgorithm, LayoutAlgorithm};
+use super::LayoutAlgorithm;
mod alignment;
mod explicit_grid;
@@ -453,14 +453,7 @@ pub fn compute(
// Position hidden child
if child_style.display == Display::None {
*tree.layout_mut(child) = Layout::with_order(order);
- GenericAlgorithm::perform_layout(
- tree,
- child,
- Size::NONE,
- Size::NONE,
- Size::MAX_CONTENT,
- SizingMode::InherentSize,
- );
+ tree.perform_child_layout(child, Size::NONE, Size::NONE, Size::MAX_CONTENT, SizingMode::InherentSize);
order += 1;
return;
}
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index a1fa6db78..cfd415487 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -2,7 +2,6 @@
//! <https://www.w3.org/TR/css-grid-1/#layout-algorithm>
use super::types::{GridItem, GridTrack, TrackCounts};
use crate::axis::AbstractAxis;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
use crate::geometry::Size;
use crate::layout::SizingMode;
use crate::math::MaybeMath;
@@ -470,8 +469,7 @@ fn resolve_item_baselines(
// Compute the baselines of all items in the row
for item in row_items.iter_mut() {
- let measured_size_and_baselines = GenericAlgorithm::perform_layout(
- tree,
+ let measured_size_and_baselines = tree.perform_child_layout(
item.node,
Size::NONE,
inner_node_size,
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index 513038d2f..cd9fb8234 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -2,7 +2,6 @@
use super::GridTrack;
use crate::axis::AbstractAxis;
use crate::compute::grid::OriginZeroLine;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
use crate::geometry::{Line, Rect, Size};
use crate::layout::SizingMode;
use crate::math::MaybeMath;
@@ -328,8 +327,7 @@ impl GridItem {
inner_node_size: Size<Option<f32>>,
) -> f32 {
let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
- GenericAlgorithm::measure_size(
- tree,
+ tree.measure_child_size(
self.node,
known_dimensions,
available_space,
@@ -367,8 +365,7 @@ impl GridItem {
inner_node_size: Size<Option<f32>>,
) -> f32 {
let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
- GenericAlgorithm::measure_size(
- tree,
+ tree.measure_child_size(
self.node,
known_dimensions,
available_space,
diff --git a/src/node.rs b/src/node.rs
index 854c76e41..430aa7153 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -6,9 +6,10 @@ use slotmap::{DefaultKey, SlotMap, SparseSecondaryMap};
/// A node in a layout.
pub type Node = slotmap::DefaultKey;
+use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
use crate::error::{TaffyError, TaffyResult};
use crate::geometry::Size;
-use crate::layout::{Cache, Layout};
+use crate::layout::{Cache, Layout, SizeAndBaselines, SizingMode};
use crate::prelude::LayoutTree;
use crate::style::{AvailableSpace, Style};
#[cfg(any(feature = "std", feature = "alloc"))]
@@ -75,18 +76,22 @@ impl Default for Taffy {
impl LayoutTree for Taffy {
type ChildIter<'a> = core::slice::Iter<'a, DefaultKey>;
+ #[inline(always)]
fn children(&self, node: Node) -> Self::ChildIter<'_> {
self.children[node].iter()
}
+ #[inline(always)]
fn child_count(&self, node: Node) -> usize {
self.children[node].len()
}
+ #[inline(always)]
fn style(&self, node: Node) -> &Style {
&self.nodes[node].style
}
+ #[inline(always)]
fn layout_mut(&mut self, node: Node) -> &mut Layout {
&mut self.nodes[node].layout
}
@@ -113,9 +118,34 @@ impl LayoutTree for Taffy {
&mut self.nodes[node].size_cache[index]
}
+ #[inline(always)]
fn child(&self, node: Node, id: usize) -> Node {
self.children[node][id]
}
+
+ #[inline(always)]
+ fn measure_child_size(
+ &mut self,
+ node: Node,
+ known_dimensions: Size<Option<f32>>,
+ parent_size: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ sizing_mode: SizingMode,
+ ) -> Size<f32> {
+ GenericAlgorithm::measure_size(self, node, known_dimensions, parent_size, available_space, sizing_mode)
+ }
+
+ #[inline(always)]
+ fn perform_child_layout(
+ &mut self,
+ node: Node,
+ known_dimensions: Size<Option<f32>>,
+ parent_size: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ sizing_mode: SizingMode,
+ ) -> SizeAndBaselines {
+ GenericAlgorithm::perform_layout(self, node, known_dimensions, parent_size, available_space, sizing_mode)
+ }
}
#[allow(clippy::iter_cloned_collect)] // due to no-std support, we need to use `iter_cloned` instead of `collect`
diff --git a/src/tree.rs b/src/tree.rs
index 47bb7fbd5..0b015045c 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -3,7 +3,7 @@
use slotmap::DefaultKey;
use crate::{
- layout::{Cache, Layout},
+ layout::{Cache, Layout, SizeAndBaselines, SizingMode},
prelude::*,
};
@@ -48,4 +48,24 @@ pub trait LayoutTree {
/// Get a cache entry for this Node by index
fn cache_mut(&mut self, node: Node, index: usize) -> &mut Option<Cache>;
+
+ /// Compute the size of the node given the specified constraints
+ fn measure_child_size(
+ &mut self,
+ node: Node,
+ known_dimensions: Size<Option<f32>>,
+ parent_size: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ sizing_mode: SizingMode,
+ ) -> Size<f32>;
+
+ /// Perform a full layout on the node given the specified constraints
+ fn perform_child_layout(
+ &mut self,
+ node: Node,
+ known_dimensions: Size<Option<f32>>,
+ parent_size: Size<Option<f32>>,
+ available_space: Size<AvailableSpace>,
+ sizing_mode: SizingMode,
+ ) -> SizeAndBaselines;
}