Skip to content

Commit 325413c

Browse files
authored
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
1 parent 2ef49c4 commit 325413c

File tree

7 files changed

+83
-59
lines changed

7 files changed

+83
-59
lines changed

src/compute/flexbox.rs

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use core::f32;
33

44
use crate::compute::common::alignment::compute_alignment_offset;
5-
use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
5+
use crate::compute::LayoutAlgorithm;
66
use crate::geometry::{Point, Rect, Size};
77
use crate::layout::{Layout, RunMode, SizeAndBaselines, SizingMode};
88
use crate::math::MaybeMath;
@@ -382,14 +382,7 @@ fn compute_preliminary(
382382
let child = tree.child(node, order);
383383
if tree.style(child).display == Display::None {
384384
*tree.layout_mut(child) = Layout::with_order(order as u32);
385-
GenericAlgorithm::perform_layout(
386-
tree,
387-
child,
388-
Size::NONE,
389-
Size::NONE,
390-
Size::MAX_CONTENT,
391-
SizingMode::InherentSize,
392-
);
385+
tree.perform_child_layout(child, Size::NONE, Size::NONE, Size::MAX_CONTENT, SizingMode::InherentSize);
393386
}
394387
}
395388

@@ -661,15 +654,15 @@ fn determine_flex_base_size(
661654
ckd
662655
};
663656

664-
break 'flex_basis GenericAlgorithm::measure_size(
665-
tree,
666-
child.node,
667-
child_known_dimensions,
668-
child_parent_size,
669-
child_available_space,
670-
SizingMode::ContentSize,
671-
)
672-
.main(dir);
657+
break 'flex_basis tree
658+
.measure_child_size(
659+
child.node,
660+
child_known_dimensions,
661+
child_parent_size,
662+
child_available_space,
663+
SizingMode::ContentSize,
664+
)
665+
.main(dir);
673666
};
674667

675668
// Floor flex-basis by the padding_border_sum (floors inner_flex_basis at zero)
@@ -708,8 +701,7 @@ fn determine_flex_base_size(
708701
let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
709702
let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
710703

711-
GenericAlgorithm::measure_size(
712-
tree,
704+
tree.measure_child_size(
713705
child.node,
714706
Size::NONE,
715707
child_parent_size,
@@ -904,15 +896,15 @@ fn determine_container_main_size(
904896
_ => {
905897
// Either the min- or max- content size depending on which constraint we are sizing under.
906898
// TODO: Optimise by using already computed values where available
907-
let content_main_size = GenericAlgorithm::measure_size(
908-
tree,
909-
item.node,
910-
Size::NONE,
911-
constants.node_inner_size,
912-
Size { width: main_axis_available_space, height: main_axis_available_space },
913-
SizingMode::InherentSize,
914-
)
915-
.main(constants.dir)
899+
let content_main_size = tree
900+
.measure_child_size(
901+
item.node,
902+
Size::NONE,
903+
constants.node_inner_size,
904+
Size { width: main_axis_available_space, height: main_axis_available_space },
905+
SizingMode::InherentSize,
906+
)
907+
.main(constants.dir)
916908
+ item.margin.main_axis_sum(constants.dir);
917909

918910
// 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(
12231215
.maybe_max(padding_border_sum);
12241216

12251217
let child_inner_cross = child_cross.unwrap_or_else(|| {
1226-
GenericAlgorithm::measure_size(
1227-
tree,
1218+
tree.measure_child_size(
12281219
child.node,
12291220
Size {
12301221
width: if constants.is_row { child.target_size.width.into() } else { child_cross },
@@ -1278,8 +1269,7 @@ fn calculate_children_base_lines(
12781269
continue;
12791270
}
12801271

1281-
let measured_size_and_baselines = GenericAlgorithm::perform_layout(
1282-
tree,
1272+
let measured_size_and_baselines = tree.perform_child_layout(
12831273
child.node,
12841274
Size {
12851275
width: if constants.is_row {
@@ -1714,8 +1704,7 @@ fn calculate_flex_item(
17141704
node_inner_size: Size<Option<f32>>,
17151705
direction: FlexDirection,
17161706
) {
1717-
let preliminary_size_and_baselines = GenericAlgorithm::perform_layout(
1718-
tree,
1707+
let preliminary_size_and_baselines = tree.perform_child_layout(
17191708
item.node,
17201709
item.target_size.map(|s| s.into()),
17211710
node_inner_size,
@@ -1900,8 +1889,7 @@ fn perform_absolute_layout_on_absolute_children(tree: &mut impl LayoutTree, node
19001889
known_dimensions = known_dimensions.maybe_apply_aspect_ratio(aspect_ratio).maybe_clamp(min_size, max_size);
19011890
}
19021891

1903-
let measured_size_and_baselines = GenericAlgorithm::perform_layout(
1904-
tree,
1892+
let measured_size_and_baselines = tree.perform_child_layout(
19051893
child,
19061894
known_dimensions,
19071895
constants.node_inner_size,

src/compute/grid/alignment.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
use super::types::GridTrack;
33
use crate::axis::InBothAbsAxis;
44
use crate::compute::common::alignment::compute_alignment_offset;
5-
use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
65
use crate::geometry::{Line, Point, Rect, Size};
76
use crate::layout::{Layout, SizingMode};
87
use crate::math::MaybeMath;
@@ -189,8 +188,7 @@ pub(super) fn align_and_position_item(
189188
let Size { width, height } = Size { width, height }.maybe_clamp(min_size, max_size);
190189

191190
// Layout node
192-
let measured_size_and_baselines = GenericAlgorithm::perform_layout(
193-
tree,
191+
let measured_size_and_baselines = tree.perform_child_layout(
194192
node,
195193
Size { width, height },
196194
grid_area_size.map(Option::Some),

src/compute/grid/mod.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub(crate) use types::{GridCoordinate, GridLine, OriginZeroLine};
2424
#[cfg(feature = "debug")]
2525
use crate::debug::NODE_LOGGER;
2626

27-
use super::{GenericAlgorithm, LayoutAlgorithm};
27+
use super::LayoutAlgorithm;
2828

2929
mod alignment;
3030
mod explicit_grid;
@@ -453,14 +453,7 @@ pub fn compute(
453453
// Position hidden child
454454
if child_style.display == Display::None {
455455
*tree.layout_mut(child) = Layout::with_order(order);
456-
GenericAlgorithm::perform_layout(
457-
tree,
458-
child,
459-
Size::NONE,
460-
Size::NONE,
461-
Size::MAX_CONTENT,
462-
SizingMode::InherentSize,
463-
);
456+
tree.perform_child_layout(child, Size::NONE, Size::NONE, Size::MAX_CONTENT, SizingMode::InherentSize);
464457
order += 1;
465458
return;
466459
}

src/compute/grid/track_sizing.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
//! <https://www.w3.org/TR/css-grid-1/#layout-algorithm>
33
use super::types::{GridItem, GridTrack, TrackCounts};
44
use crate::axis::AbstractAxis;
5-
use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
65
use crate::geometry::Size;
76
use crate::layout::SizingMode;
87
use crate::math::MaybeMath;
@@ -470,8 +469,7 @@ fn resolve_item_baselines(
470469

471470
// Compute the baselines of all items in the row
472471
for item in row_items.iter_mut() {
473-
let measured_size_and_baselines = GenericAlgorithm::perform_layout(
474-
tree,
472+
let measured_size_and_baselines = tree.perform_child_layout(
475473
item.node,
476474
Size::NONE,
477475
inner_node_size,

src/compute/grid/types/grid_item.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
use super::GridTrack;
33
use crate::axis::AbstractAxis;
44
use crate::compute::grid::OriginZeroLine;
5-
use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
65
use crate::geometry::{Line, Rect, Size};
76
use crate::layout::SizingMode;
87
use crate::math::MaybeMath;
@@ -328,8 +327,7 @@ impl GridItem {
328327
inner_node_size: Size<Option<f32>>,
329328
) -> f32 {
330329
let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
331-
GenericAlgorithm::measure_size(
332-
tree,
330+
tree.measure_child_size(
333331
self.node,
334332
known_dimensions,
335333
available_space,
@@ -367,8 +365,7 @@ impl GridItem {
367365
inner_node_size: Size<Option<f32>>,
368366
) -> f32 {
369367
let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
370-
GenericAlgorithm::measure_size(
371-
tree,
368+
tree.measure_child_size(
372369
self.node,
373370
known_dimensions,
374371
available_space,

src/node.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use slotmap::{DefaultKey, SlotMap, SparseSecondaryMap};
66
/// A node in a layout.
77
pub type Node = slotmap::DefaultKey;
88

9+
use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
910
use crate::error::{TaffyError, TaffyResult};
1011
use crate::geometry::Size;
11-
use crate::layout::{Cache, Layout};
12+
use crate::layout::{Cache, Layout, SizeAndBaselines, SizingMode};
1213
use crate::prelude::LayoutTree;
1314
use crate::style::{AvailableSpace, Style};
1415
#[cfg(any(feature = "std", feature = "alloc"))]
@@ -75,18 +76,22 @@ impl Default for Taffy {
7576
impl LayoutTree for Taffy {
7677
type ChildIter<'a> = core::slice::Iter<'a, DefaultKey>;
7778

79+
#[inline(always)]
7880
fn children(&self, node: Node) -> Self::ChildIter<'_> {
7981
self.children[node].iter()
8082
}
8183

84+
#[inline(always)]
8285
fn child_count(&self, node: Node) -> usize {
8386
self.children[node].len()
8487
}
8588

89+
#[inline(always)]
8690
fn style(&self, node: Node) -> &Style {
8791
&self.nodes[node].style
8892
}
8993

94+
#[inline(always)]
9095
fn layout_mut(&mut self, node: Node) -> &mut Layout {
9196
&mut self.nodes[node].layout
9297
}
@@ -113,9 +118,34 @@ impl LayoutTree for Taffy {
113118
&mut self.nodes[node].size_cache[index]
114119
}
115120

121+
#[inline(always)]
116122
fn child(&self, node: Node, id: usize) -> Node {
117123
self.children[node][id]
118124
}
125+
126+
#[inline(always)]
127+
fn measure_child_size(
128+
&mut self,
129+
node: Node,
130+
known_dimensions: Size<Option<f32>>,
131+
parent_size: Size<Option<f32>>,
132+
available_space: Size<AvailableSpace>,
133+
sizing_mode: SizingMode,
134+
) -> Size<f32> {
135+
GenericAlgorithm::measure_size(self, node, known_dimensions, parent_size, available_space, sizing_mode)
136+
}
137+
138+
#[inline(always)]
139+
fn perform_child_layout(
140+
&mut self,
141+
node: Node,
142+
known_dimensions: Size<Option<f32>>,
143+
parent_size: Size<Option<f32>>,
144+
available_space: Size<AvailableSpace>,
145+
sizing_mode: SizingMode,
146+
) -> SizeAndBaselines {
147+
GenericAlgorithm::perform_layout(self, node, known_dimensions, parent_size, available_space, sizing_mode)
148+
}
119149
}
120150

121151
#[allow(clippy::iter_cloned_collect)] // due to no-std support, we need to use `iter_cloned` instead of `collect`

src/tree.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use slotmap::DefaultKey;
44

55
use crate::{
6-
layout::{Cache, Layout},
6+
layout::{Cache, Layout, SizeAndBaselines, SizingMode},
77
prelude::*,
88
};
99

@@ -48,4 +48,24 @@ pub trait LayoutTree {
4848

4949
/// Get a cache entry for this Node by index
5050
fn cache_mut(&mut self, node: Node, index: usize) -> &mut Option<Cache>;
51+
52+
/// Compute the size of the node given the specified constraints
53+
fn measure_child_size(
54+
&mut self,
55+
node: Node,
56+
known_dimensions: Size<Option<f32>>,
57+
parent_size: Size<Option<f32>>,
58+
available_space: Size<AvailableSpace>,
59+
sizing_mode: SizingMode,
60+
) -> Size<f32>;
61+
62+
/// Perform a full layout on the node given the specified constraints
63+
fn perform_child_layout(
64+
&mut self,
65+
node: Node,
66+
known_dimensions: Size<Option<f32>>,
67+
parent_size: Size<Option<f32>>,
68+
available_space: Size<AvailableSpace>,
69+
sizing_mode: SizingMode,
70+
) -> SizeAndBaselines;
5171
}

0 commit comments

Comments
 (0)