Skip to content

Commit

Permalink
Remove Send+Sync bound from Measurable and create separate SyncMeasur…
Browse files Browse the repository at this point in the history
…eFunc type
  • Loading branch information
nicoburns committed Jun 1, 2023
1 parent 9865cd1 commit 2e037d9
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
1 change: 0 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#![deny(unsafe_code)]
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]
#![forbid(unsafe_code)]

// We always need std for the tests
// See <https://github.com/la10736/rstest/issues/149#issuecomment-1156402989>
Expand Down
48 changes: 44 additions & 4 deletions src/tree/measure_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::util::sys::Box;
/// A function type that can be used in a [`MeasureFunc`]
///
/// This trait is automatically implemented for all types (including closures) that define a function with the appropriate type signature.
pub trait Measurable: Send + Sync {
pub trait Measurable {
/// A user-defined context which is passed to taffy when the `compute_layout` function is called, and which Taffy then passes
/// into measure functions when it calls them
type Context;
Expand Down Expand Up @@ -55,13 +55,53 @@ impl<Context> Measurable for MeasureFunc<Context> {
}
}

/// A function that can be used to compute the intrinsic size of a node
pub enum SyncMeasureFunc<Context = ()> {
/// Stores an unboxed function with no context parameter
Raw(fn(Size<Option<f32>>, Size<AvailableSpace>) -> Size<f32>),

/// Stores an unboxed function with a context parameter
RawWithContext(fn(Size<Option<f32>>, Size<AvailableSpace>, context: &mut Context) -> Size<f32>),

/// Stores a boxed function
#[cfg(any(feature = "std", feature = "alloc"))]
Boxed(Box<dyn Measurable<Context = Context> + Send + Sync>),
}

impl<Context> Measurable for SyncMeasureFunc<Context> {
type Context = Context;

/// Call the measure function to measure to the node
#[inline(always)]
fn measure(
&self,
known_dimensions: Size<Option<f32>>,
available_space: Size<AvailableSpace>,
context: &mut Context,
) -> Size<f32> {
match self {
Self::Raw(measure) => measure(known_dimensions, available_space),
Self::RawWithContext(measure) => measure(known_dimensions, available_space, context),
#[cfg(any(feature = "std", feature = "alloc"))]
Self::Boxed(measurable) => measurable.measure(known_dimensions, available_space, context),
}
}
}

#[cfg(test)]
mod test {
use super::MeasureFunc;
use super::SyncMeasureFunc;
use crate::tree::Taffy;

#[test]
fn sync_measure_func_is_send_and_sync() {
fn is_send_and_sync<T: Send + Sync>() {}
is_send_and_sync::<SyncMeasureFunc>();
}

#[test]
fn measure_func_is_send_and_sync() {
fn taffy_with_sync_measure_func_is_send_and_sync() {
fn is_send_and_sync<T: Send + Sync>() {}
is_send_and_sync::<MeasureFunc>();
is_send_and_sync::<Taffy<SyncMeasureFunc>>();
}
}
2 changes: 1 addition & 1 deletion src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::style::{AvailableSpace, Style};
mod cache;
pub use cache::{Cache, CacheEntry};
mod measure_func;
pub use measure_func::{Measurable, MeasureFunc};
pub use measure_func::{Measurable, MeasureFunc, SyncMeasureFunc};
mod node;
#[cfg(feature = "taffy_tree")]
pub(self) use node::NodeData;
Expand Down
10 changes: 3 additions & 7 deletions src/tree/taffy_tree/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ where
pub(crate) nodes: SlotMap<DefaultKey, NodeData>,

/// Functions/closures that compute the intrinsic size of leaf nodes
pub(crate) measure_funcs: SparseSecondaryMap<DefaultKey, MeasureFunc<Measure::Context>>,
pub(crate) measure_funcs: SparseSecondaryMap<DefaultKey, Measure>,

/// The children of each node
///
Expand Down Expand Up @@ -168,11 +168,7 @@ impl<Measure: Measurable> Taffy<Measure> {
/// Creates and adds a new unattached leaf node to the tree, and returns the node of the new node
///
/// Creates and adds a new leaf node with a supplied [`MeasureFunc`]
pub fn new_leaf_with_measure(
&mut self,
layout: Style,
measure: MeasureFunc<Measure::Context>,
) -> TaffyResult<NodeId> {
pub fn new_leaf_with_measure(&mut self, layout: Style, measure: Measure) -> TaffyResult<NodeId> {
let mut data = NodeData::new(layout);
data.needs_measure = true;

Expand Down Expand Up @@ -225,7 +221,7 @@ impl<Measure: Measurable> Taffy<Measure> {
}

/// Sets the [`MeasureFunc`] of the associated node
pub fn set_measure(&mut self, node: NodeId, measure: Option<MeasureFunc<Measure::Context>>) -> TaffyResult<()> {
pub fn set_measure(&mut self, node: NodeId, measure: Option<Measure>) -> TaffyResult<()> {
let key = node.into();
if let Some(measure) = measure {
self.nodes[key].needs_measure = true;
Expand Down

0 comments on commit 2e037d9

Please sign in to comment.