@@ -7,7 +7,7 @@ use crate::compute::taffy_tree::{compute_layout, measure_node_size, perform_node
77use crate :: geometry:: { Line , Size } ;
88use crate :: prelude:: LayoutTree ;
99use crate :: style:: { AvailableSpace , Style } ;
10- use crate :: tree:: { Layout , MeasureFunc , NodeData , NodeId , SizeBaselinesAndMargins , SizingMode } ;
10+ use crate :: tree:: { Layout , Measurable , MeasureFunc , NodeData , NodeId , SizeBaselinesAndMargins , SizingMode } ;
1111use crate :: util:: sys:: { new_vec_with_capacity, ChildrenVec , Vec } ;
1212
1313use super :: { TaffyError , TaffyResult } ;
@@ -25,12 +25,15 @@ impl Default for TaffyConfig {
2525}
2626
2727/// A tree of UI nodes suitable for UI layout
28- pub struct Taffy {
28+ pub struct Taffy < Measure = MeasureFunc < ( ) > >
29+ where
30+ Measure : Measurable ,
31+ {
2932 /// The [`NodeData`] for each node stored in this tree
3033 pub ( crate ) nodes : SlotMap < DefaultKey , NodeData > ,
3134
3235 /// Functions/closures that compute the intrinsic size of leaf nodes
33- pub ( crate ) measure_funcs : SparseSecondaryMap < DefaultKey , MeasureFunc > ,
36+ pub ( crate ) measure_funcs : SparseSecondaryMap < DefaultKey , MeasureFunc < Measure :: Context > > ,
3437
3538 /// The children of each node
3639 ///
@@ -44,6 +47,9 @@ pub struct Taffy {
4447
4548 /// Layout mode configuration
4649 pub ( crate ) config : TaffyConfig ,
50+
51+ /// Used to store the context during layout. Cleared before returning from `compute_layout`.
52+ pub ( crate ) context : Option < Measure :: Context > ,
4753}
4854
4955impl Default for Taffy {
@@ -62,8 +68,8 @@ impl<'a> Iterator for TaffyChildIter<'a> {
6268 }
6369}
6470
65- impl LayoutTree for Taffy {
66- type ChildIter < ' a > = TaffyChildIter < ' a > ;
71+ impl < Measure : Measurable > LayoutTree for Taffy < Measure > {
72+ type ChildIter < ' a > = TaffyChildIter < ' a > where Measure : ' a ;
6773
6874 #[ inline( always) ]
6975 fn children ( & self , node : NodeId ) -> Self :: ChildIter < ' _ > {
@@ -139,29 +145,7 @@ impl LayoutTree for Taffy {
139145}
140146
141147#[ allow( clippy:: iter_cloned_collect) ] // due to no-std support, we need to use `iter_cloned` instead of `collect`
142- impl Taffy {
143- /// Creates a new [`Taffy`]
144- ///
145- /// The default capacity of a [`Taffy`] is 16 nodes.
146- #[ must_use]
147- pub fn new ( ) -> Self {
148- Self :: with_capacity ( 16 )
149- }
150-
151- /// Creates a new [`Taffy`] that can store `capacity` nodes before reallocation
152- #[ must_use]
153- pub fn with_capacity ( capacity : usize ) -> Self {
154- Self {
155- // TODO: make this method const upstream,
156- // so constructors here can be const
157- nodes : SlotMap :: with_capacity ( capacity) ,
158- children : SlotMap :: with_capacity ( capacity) ,
159- parents : SlotMap :: with_capacity ( capacity) ,
160- measure_funcs : SparseSecondaryMap :: with_capacity ( capacity) ,
161- config : TaffyConfig :: default ( ) ,
162- }
163- }
164-
148+ impl < Measure : Measurable > Taffy < Measure > {
165149 /// Enable rounding of layout values. Rounding is enabled by default.
166150 pub fn enable_rounding ( & mut self ) {
167151 self . config . use_rounding = true ;
@@ -184,7 +168,11 @@ impl Taffy {
184168 /// Creates and adds a new unattached leaf node to the tree, and returns the node of the new node
185169 ///
186170 /// Creates and adds a new leaf node with a supplied [`MeasureFunc`]
187- pub fn new_leaf_with_measure ( & mut self , layout : Style , measure : MeasureFunc ) -> TaffyResult < NodeId > {
171+ pub fn new_leaf_with_measure (
172+ & mut self ,
173+ layout : Style ,
174+ measure : MeasureFunc < Measure :: Context > ,
175+ ) -> TaffyResult < NodeId > {
188176 let mut data = NodeData :: new ( layout) ;
189177 data. needs_measure = true ;
190178
@@ -237,7 +225,7 @@ impl Taffy {
237225 }
238226
239227 /// Sets the [`MeasureFunc`] of the associated node
240- pub fn set_measure ( & mut self , node : NodeId , measure : Option < MeasureFunc > ) -> TaffyResult < ( ) > {
228+ pub fn set_measure ( & mut self , node : NodeId , measure : Option < MeasureFunc < Measure :: Context > > ) -> TaffyResult < ( ) > {
241229 let key = node. into ( ) ;
242230 if let Some ( measure) = measure {
243231 self . nodes [ key] . needs_measure = true ;
@@ -420,9 +408,47 @@ impl Taffy {
420408 Ok ( self . nodes [ node. into ( ) ] . cache . is_empty ( ) )
421409 }
422410
411+ /// Updates the stored layout of the provided `node` and its children
412+ pub fn compute_layout_with_context (
413+ & mut self ,
414+ node : NodeId ,
415+ available_space : Size < AvailableSpace > ,
416+ context : Measure :: Context ,
417+ ) -> Result < ( ) , TaffyError > {
418+ self . context = Some ( context) ;
419+ let result = compute_layout ( self , node, available_space) ;
420+ self . context = None ;
421+ result
422+ }
423+ }
424+
425+ impl Taffy < MeasureFunc < ( ) > > {
426+ /// Creates a new [`Taffy`]
427+ ///
428+ /// The default capacity of a [`Taffy`] is 16 nodes.
429+ #[ must_use]
430+ pub fn new ( ) -> Self {
431+ Self :: with_capacity ( 16 )
432+ }
433+
434+ /// Creates a new [`Taffy`] that can store `capacity` nodes before reallocation
435+ #[ must_use]
436+ pub fn with_capacity ( capacity : usize ) -> Self {
437+ Taffy {
438+ // TODO: make this method const upstream,
439+ // so constructors here can be const
440+ nodes : SlotMap :: with_capacity ( capacity) ,
441+ children : SlotMap :: with_capacity ( capacity) ,
442+ parents : SlotMap :: with_capacity ( capacity) ,
443+ measure_funcs : SparseSecondaryMap :: with_capacity ( capacity) ,
444+ config : TaffyConfig :: default ( ) ,
445+ context : None ,
446+ }
447+ }
448+
423449 /// Updates the stored layout of the provided `node` and its children
424450 pub fn compute_layout ( & mut self , node : NodeId , available_space : Size < AvailableSpace > ) -> Result < ( ) , TaffyError > {
425- compute_layout ( self , node, available_space)
451+ self . compute_layout_with_context ( node, available_space, ( ) )
426452 }
427453}
428454
0 commit comments