tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 501HTML 254C 19JavaScript 81413 Sutichaykuna

Fix js bindings

1b40f4a39765e363c51db83d6a8731e0f10502c7 · ruwaq David Flemström · (6 wata ñawpaq) · tayta e7ae3b06d · kay commitpi sach'ata qhaway

Semántico sayk'uy · 24

bindings/js/src/lib.rs

  • ukhunpi t'ikrakurqan fn new pub
  • ukhunpi t'ikrakurqan fn set_measure pub

src/algo.rs

src/geometry.rs

  • silq'uyninpi t'ikrakurqan fn map pub

src/node.rs

src/sys.rs

  • musuq type Box pub
  • musuq type Box pub

tests/measure.rs

tests/node.rs

8 qillqakuna · +120 −74

diff --git a/bindings/js/Cargo.toml b/bindings/js/Cargo.toml
index bead14406..d854b3f1b 100644
--- a/bindings/js/Cargo.toml
+++ b/bindings/js/Cargo.toml
@@ -13,7 +13,7 @@ default = ["console_error_panic_hook"]
 [dependencies]
 wasm-bindgen = "0.2"
 js-sys = "0.3"
-stretch = "0.3.2"
+stretch = { version = "0.3.2", path = "../.." }
 
 # The `console_error_panic_hook` crate provides better debugging of panics by
 # logging them with `console.error`. This is great for development, but requires
diff --git a/bindings/js/src/lib.rs b/bindings/js/src/lib.rs
index 2f13b0861..d86f33993 100644
--- a/bindings/js/src/lib.rs
+++ b/bindings/js/src/lib.rs
@@ -417,7 +417,7 @@ impl Node {
     pub fn new(allocator: &Allocator, style: &JsValue) -> Node {
         Node {
             allocator: allocator.clone(),
-            node: allocator.stretch.borrow_mut().new_node(parse_style(&style), vec![]).unwrap(),
+            node: allocator.stretch.borrow_mut().new_node(parse_style(&style), &[]).unwrap(),
             style: style.clone(),
             childCount: 0,
         }
@@ -432,7 +432,9 @@ impl Node {
             .borrow_mut()
             .set_measure(
                 self.node,
-                Some(Box::new(move |constraints| {
+                Some(stretch::node::MeasureFunc::Boxed(Box::new(move |constraints| {
+                    use stretch::number::OrElse;
+
                     let widthConstraint = if let stretch::number::Number::Defined(val) = constraints.width {
                         val.into()
                     } else {
@@ -450,12 +452,12 @@ impl Node {
                         let height = get_f32(&result, "height");
 
                         if width.is_some() && height.is_some() {
-                            return Ok(stretch::geometry::Size { width: width.unwrap(), height: height.unwrap() });
+                            return stretch::geometry::Size { width: width.unwrap(), height: height.unwrap() };
                         }
                     }
 
-                    Err(Box::new("Failed in javascript"))
-                })),
+                    constraints.map(|v| v.or_else(0.0))
+                }))),
             )
             .unwrap();
     }
diff --git a/src/algo.rs b/src/algo.rs
index caa0094d9..42457a780 100644
--- a/src/algo.rs
+++ b/src/algo.rs
@@ -2,6 +2,7 @@ use core::f32;
 
 use crate::forest::{Forest, NodeData};
 use crate::id::NodeId;
+use crate::node::MeasureFunc;
 use crate::result;
 use crate::style::*;
 use crate::sys;
@@ -195,7 +196,11 @@ impl Forest {
             }
 
             if let Some(ref measure) = self.nodes[node].measure {
-                let result = ComputeResult { size: measure(node_size) };
+                let result = match measure {
+                    MeasureFunc::Raw(measure) => ComputeResult { size: measure(node_size) },
+                    #[cfg(any(feature = "std", feature = "alloc"))]
+                    MeasureFunc::Boxed(measure) => ComputeResult { size: measure(node_size) },
+                };
                 self.nodes[node].layout_cache =
                     Some(result::Cache { node_size, parent_size, perform_layout, result: result.clone() });
                 return result;
diff --git a/src/geometry.rs b/src/geometry.rs
index d551d4c8b..7708b1830 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -101,7 +101,7 @@ impl Size<()> {
 }
 
 impl<T> Size<T> {
-    pub(crate) fn map<R, F>(self, f: F) -> Size<R>
+    pub fn map<R, F>(self, f: F) -> Size<R>
     where
         F: Fn(T) -> R,
     {
diff --git a/src/node.rs b/src/node.rs
index 566de55c4..6a32d17a6 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -9,7 +9,11 @@ use crate::style::*;
 use crate::sys;
 use crate::Error;
 
-pub type MeasureFunc = fn(Size<Number>) -> Size<f32>;
+pub enum MeasureFunc {
+    Raw(fn(Size<Number>) -> Size<f32>),
+    #[cfg(any(feature = "std", feature = "alloc"))]
+    Boxed(sys::Box<dyn Fn(Size<Number>) -> Size<f32>>),
+}
 
 lazy_static! {
     /// Global stretch instance id allocator.
diff --git a/src/sys.rs b/src/sys.rs
index 40156fb1b..51c59291d 100644
--- a/src/sys.rs
+++ b/src/sys.rs
@@ -1,5 +1,6 @@
 #[cfg(feature = "std")]
 mod std {
+    pub type Box<A> = ::std::boxed::Box<A>;
     pub type Map<K, V> = ::std::collections::HashMap<K, V>;
     pub type Vec<A> = ::std::vec::Vec<A>;
     pub type ChildrenVec<A> = ::std::vec::Vec<A>;
@@ -19,6 +20,7 @@ mod std {
 
 #[cfg(feature = "alloc")]
 mod alloc {
+    pub type Box<A> = ::alloc::boxed::Box<A>;
     pub type Map<K, V> = ::hashbrown::HashMap<K, V>;
     pub type Vec<A> = ::alloc::vec::Vec<A>;
     pub type ChildrenVec<A> = ::alloc::vec::Vec<A>;
diff --git a/tests/measure.rs b/tests/measure.rs
index 56aa95585..537125620 100644
--- a/tests/measure.rs
+++ b/tests/measure.rs
@@ -1,15 +1,19 @@
 #[cfg(test)]
 mod measure {
+    use stretch::node::MeasureFunc;
     use stretch::number::OrElse;
 
     #[test]
     fn measure_root() {
         let mut stretch = stretch::node::Stretch::new();
         let node = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| stretch::geometry::Size {
-                width: constraint.width.or_else(100.0),
-                height: constraint.height.or_else(100.0),
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
+                    width: constraint.width.or_else(100.0),
+                    height: constraint.height.or_else(100.0),
+                }),
+            )
             .unwrap();
 
         stretch.compute_layout(node, stretch::geometry::Size::undefined()).unwrap();
@@ -23,10 +27,13 @@ mod measure {
         let mut stretch = stretch::node::Stretch::new();
 
         let child = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| stretch::geometry::Size {
-                width: constraint.width.or_else(100.0),
-                height: constraint.height.or_else(100.0),
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
+                    width: constraint.width.or_else(100.0),
+                    height: constraint.height.or_else(100.0),
+                }),
+            )
             .unwrap();
 
         let node = stretch.new_node(stretch::style::Style { ..Default::default() }, &[child]).unwrap();
@@ -43,10 +50,13 @@ mod measure {
     fn measure_child_constraint() {
         let mut stretch = stretch::node::Stretch::new();
         let child = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| stretch::geometry::Size {
-                width: constraint.width.or_else(100.0),
-                height: constraint.height.or_else(100.0),
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
+                    width: constraint.width.or_else(100.0),
+                    height: constraint.height.or_else(100.0),
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -75,10 +85,13 @@ mod measure {
     fn measure_child_constraint_padding_parent() {
         let mut stretch = stretch::node::Stretch::new();
         let child = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| stretch::geometry::Size {
-                width: constraint.width.or_else(100.0),
-                height: constraint.height.or_else(100.0),
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
+                    width: constraint.width.or_else(100.0),
+                    height: constraint.height.or_else(100.0),
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -125,12 +138,13 @@ mod measure {
             .unwrap();
 
         let child1 = stretch
-            .new_leaf(stretch::style::Style { flex_grow: 1.0, ..Default::default() }, |constraint| {
-                stretch::geometry::Size {
+            .new_leaf(
+                stretch::style::Style { flex_grow: 1.0, ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
                     width: constraint.width.or_else(10.0),
                     height: constraint.height.or_else(50.0),
-                }
-            })
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -170,10 +184,13 @@ mod measure {
             .unwrap();
 
         let child1 = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| stretch::geometry::Size {
-                width: constraint.width.or_else(100.0),
-                height: constraint.height.or_else(50.0),
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
+                    width: constraint.width.or_else(100.0),
+                    height: constraint.height.or_else(50.0),
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -212,11 +229,14 @@ mod measure {
             .unwrap();
 
         let child1 = stretch
-            .new_leaf(stretch::style::Style { flex_grow: 1.0, ..Default::default() }, |constraint| {
-                let width = constraint.width.or_else(10.0);
-                let height = constraint.height.or_else(width * 2.0);
-                stretch::geometry::Size { width, height }
-            })
+            .new_leaf(
+                stretch::style::Style { flex_grow: 1.0, ..Default::default() },
+                MeasureFunc::Raw(|constraint| {
+                    let width = constraint.width.or_else(10.0);
+                    let height = constraint.height.or_else(width * 2.0);
+                    stretch::geometry::Size { width, height }
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -258,11 +278,14 @@ mod measure {
             .unwrap();
 
         let child1 = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| {
-                let width = constraint.width.or_else(100.0);
-                let height = constraint.height.or_else(width * 2.0);
-                stretch::geometry::Size { width, height }
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| {
+                    let width = constraint.width.or_else(100.0);
+                    let height = constraint.height.or_else(width * 2.0);
+                    stretch::geometry::Size { width, height }
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -290,11 +313,14 @@ mod measure {
         let mut stretch = stretch::node::Stretch::new();
 
         let child = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| {
-                let height = constraint.height.or_else(50.0);
-                let width = constraint.width.or_else(height);
-                stretch::geometry::Size { width, height }
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| {
+                    let height = constraint.height.or_else(50.0);
+                    let width = constraint.width.or_else(height);
+                    stretch::geometry::Size { width, height }
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -328,10 +354,10 @@ mod measure {
                     },
                     ..Default::default()
                 },
-                |constraint| stretch::geometry::Size {
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
                     width: constraint.width.or_else(100.0),
                     height: constraint.height.or_else(100.0),
-                },
+                }),
             )
             .unwrap();
 
@@ -354,10 +380,10 @@ mod measure {
                     },
                     ..Default::default()
                 },
-                |constraint| stretch::geometry::Size {
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
                     width: constraint.width.or_else(100.0),
                     height: constraint.height.or_else(100.0),
-                },
+                }),
             )
             .unwrap();
 
@@ -389,10 +415,10 @@ mod measure {
                     flex_grow: 1.0,
                     ..Default::default()
                 },
-                |constraint| stretch::geometry::Size {
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
                     width: constraint.width.or_else(100.0),
                     height: constraint.height.or_else(100.0),
-                },
+                }),
             )
             .unwrap();
 
@@ -421,10 +447,13 @@ mod measure {
     fn stretch_overrides_measure() {
         let mut stretch = stretch::node::Stretch::new();
         let child = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| stretch::geometry::Size {
-                width: constraint.width.or_else(50.0),
-                height: constraint.height.or_else(50.0),
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
+                    width: constraint.width.or_else(50.0),
+                    height: constraint.height.or_else(50.0),
+                }),
+            )
             .unwrap();
 
         let node = stretch
@@ -452,10 +481,10 @@ mod measure {
         let child = stretch
             .new_leaf(
                 stretch::style::Style { position_type: stretch::style::PositionType::Absolute, ..Default::default() },
-                |constraint| stretch::geometry::Size {
+                MeasureFunc::Raw(|constraint| stretch::geometry::Size {
                     width: constraint.width.or_else(50.0),
                     height: constraint.height.or_else(50.0),
-                },
+                }),
             )
             .unwrap();
 
@@ -482,10 +511,10 @@ mod measure {
     fn ignore_invalid_measure() {
         let mut stretch = stretch::node::Stretch::new();
         let child = stretch
-            .new_leaf(stretch::style::Style { flex_grow: 1.0, ..Default::default() }, |_| stretch::geometry::Size {
-                width: 200.0,
-                height: 200.0,
-            })
+            .new_leaf(
+                stretch::style::Style { flex_grow: 1.0, ..Default::default() },
+                MeasureFunc::Raw(|_| stretch::geometry::Size { width: 200.0, height: 200.0 }),
+            )
             .unwrap();
 
         let node = stretch
@@ -515,13 +544,16 @@ mod measure {
         static NUM_MEASURES: atomic::AtomicU32 = atomic::AtomicU32::new(0);
 
         let grandchild = stretch
-            .new_leaf(stretch::style::Style { ..Default::default() }, |constraint| {
-                NUM_MEASURES.fetch_add(1, atomic::Ordering::Relaxed);
-                stretch::geometry::Size {
-                    width: constraint.width.or_else(50.0),
-                    height: constraint.height.or_else(50.0),
-                }
-            })
+            .new_leaf(
+                stretch::style::Style { ..Default::default() },
+                MeasureFunc::Raw(|constraint| {
+                    NUM_MEASURES.fetch_add(1, atomic::Ordering::Relaxed);
+                    stretch::geometry::Size {
+                        width: constraint.width.or_else(50.0),
+                        height: constraint.height.or_else(50.0),
+                    }
+                }),
+            )
             .unwrap();
 
         let child = stretch.new_node(stretch::style::Style { ..Default::default() }, &[grandchild]).unwrap();
diff --git a/tests/node.rs b/tests/node.rs
index 849b9a5c7..bb062cb4d 100644
--- a/tests/node.rs
+++ b/tests/node.rs
@@ -1,7 +1,7 @@
 #[cfg(test)]
 mod node {
     use stretch::geometry::*;
-    use stretch::node::Stretch;
+    use stretch::node::{MeasureFunc, Stretch};
     use stretch::style::*;
 
     #[test]
@@ -19,11 +19,12 @@ mod node {
     #[test]
     fn set_measure() {
         let mut stretch = Stretch::new();
-        let node = stretch.new_leaf(Style::default(), |_| Size { width: 200.0, height: 200.0 }).unwrap();
+        let node =
+            stretch.new_leaf(Style::default(), MeasureFunc::Raw(|_| Size { width: 200.0, height: 200.0 })).unwrap();
         stretch.compute_layout(node, Size::undefined()).unwrap();
         assert_eq!(stretch.layout(node).unwrap().size.width, 200.0);
 
-        stretch.set_measure(node, Some(|_| Size { width: 100.0, height: 100.0 })).unwrap();
+        stretch.set_measure(node, Some(MeasureFunc::Raw(|_| Size { width: 100.0, height: 100.0 }))).unwrap();
         stretch.compute_layout(node, Size::undefined()).unwrap();
         assert_eq!(stretch.layout(node).unwrap().size.width, 100.0);
     }