tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 499HTML 245JavaScript 8Markdown 71218 Sutichaykuna

Make `MeasureFunc` Send and Sync (#157)

* Make MeasureFunc Send and Sync

* Update RELEASE notes

e35eef766092f051c24af50f48b4bf7e4669155e · ruwaq Alice Cecile · (4 wata ñawpaq) · tayta db25d95eb · kay commitpi sach'ata qhaway

Semántico sayk'uy · 5

src/node.rs

2 qillqakuna · +21 −2

diff --git a/RELEASES.md b/RELEASES.md
index d8d05efe5..f1eee4e22 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -22,6 +22,7 @@
 - fixed rounding of fractional values to follow latest Chrome - values are now rounded the same regardless of their position
 - fixed computing free space when using both `flex-grow` and a minimum size
 - padding is now only subtracted when determining the available space if the node size is unspecified, following [section 9.2.2 of the flexbox spec](https://www.w3.org/TR/css-flexbox-1/#line-sizing)
+- `MeasureFunc` (and hence `NodeData` and hence `Forest` and hence the public `Taffy` type) are now `Send` and `Sync`, enabling their use in async and parallel applications
 
 ### 0.2.0 Removed
 
diff --git a/src/node.rs b/src/node.rs
index 502f16e9c..c5429f6ae 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -11,13 +11,20 @@ use crate::sys::Box;
 use crate::sys::{new_map_with_capacity, ChildrenVec, Map, Vec};
 use core::sync::atomic::{AtomicUsize, Ordering};
 
-/// A function that can be applied to a `Size<Option<f32>>` to obtain a `Size<f32>`
+/// 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 + Fn(Size<Option<f32>>) -> Size<f32> {}
+
+impl<F: Send + Sync + Fn(Size<Option<f32>>) -> Size<f32>> Measurable for F {}
+
+/// A function that can be used to compute the intrinsic size of a node
 pub enum MeasureFunc {
     /// Stores an unboxed function
     Raw(fn(Size<Option<f32>>) -> Size<f32>),
     /// Stores a boxed function
     #[cfg(any(feature = "std", feature = "alloc"))]
-    Boxed(Box<dyn Fn(Size<Option<f32>>) -> Size<f32>>),
+    Boxed(Box<dyn Measurable>),
 }
 
 /// Global taffy instance id allocator.
@@ -320,3 +327,14 @@ impl Allocator {
         Id(self.last_id.fetch_add(1, Ordering::Relaxed))
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn measure_func_is_send_and_sync() {
+        fn is_send_and_sync<T: Sync>() {}
+        is_send_and_sync::<MeasureFunc>();
+    }
+}