From 2e037d92d34979c0f992029a3acbbe3335494c1c Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 1 Jun 2023 22:06:05 +0100 Subject: [PATCH] Remove Send+Sync bound from Measurable and create separate SyncMeasureFunc type --- src/lib.rs | 1 - src/tree/measure_func.rs | 48 +++++++++++++++++++++++++++++++++---- src/tree/mod.rs | 2 +- src/tree/taffy_tree/tree.rs | 10 +++----- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b90036474..64683f11c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 diff --git a/src/tree/measure_func.rs b/src/tree/measure_func.rs index 8e7c6ed60..83f7126d6 100644 --- a/src/tree/measure_func.rs +++ b/src/tree/measure_func.rs @@ -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; @@ -55,13 +55,53 @@ impl Measurable for MeasureFunc { } } +/// A function that can be used to compute the intrinsic size of a node +pub enum SyncMeasureFunc { + /// Stores an unboxed function with no context parameter + Raw(fn(Size>, Size) -> Size), + + /// Stores an unboxed function with a context parameter + RawWithContext(fn(Size>, Size, context: &mut Context) -> Size), + + /// Stores a boxed function + #[cfg(any(feature = "std", feature = "alloc"))] + Boxed(Box + Send + Sync>), +} + +impl Measurable for SyncMeasureFunc { + type Context = Context; + + /// Call the measure function to measure to the node + #[inline(always)] + fn measure( + &self, + known_dimensions: Size>, + available_space: Size, + context: &mut Context, + ) -> Size { + 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() {} + is_send_and_sync::(); + } #[test] - fn measure_func_is_send_and_sync() { + fn taffy_with_sync_measure_func_is_send_and_sync() { fn is_send_and_sync() {} - is_send_and_sync::(); + is_send_and_sync::>(); } } diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 5ca9c2b96..ca76a8219 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -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; diff --git a/src/tree/taffy_tree/tree.rs b/src/tree/taffy_tree/tree.rs index 804328720..09248ab61 100644 --- a/src/tree/taffy_tree/tree.rs +++ b/src/tree/taffy_tree/tree.rs @@ -33,7 +33,7 @@ where pub(crate) nodes: SlotMap, /// Functions/closures that compute the intrinsic size of leaf nodes - pub(crate) measure_funcs: SparseSecondaryMap>, + pub(crate) measure_funcs: SparseSecondaryMap, /// The children of each node /// @@ -168,11 +168,7 @@ impl Taffy { /// 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, - ) -> TaffyResult { + pub fn new_leaf_with_measure(&mut self, layout: Style, measure: Measure) -> TaffyResult { let mut data = NodeData::new(layout); data.needs_measure = true; @@ -225,7 +221,7 @@ impl Taffy { } /// Sets the [`MeasureFunc`] of the associated node - pub fn set_measure(&mut self, node: NodeId, measure: Option>) -> TaffyResult<()> { + pub fn set_measure(&mut self, node: NodeId, measure: Option) -> TaffyResult<()> { let key = node.into(); if let Some(measure) = measure { self.nodes[key].needs_measure = true;