22
33mod utils;
44
5- use core:: str:: FromStr ;
65use std:: cell:: RefCell ;
76use std:: rc:: Rc ;
87
8+ use js_sys:: Array ;
99use js_sys:: Function ;
1010use js_sys:: Reflect ;
11- use taffy:: style :: * ;
11+ use taffy:: prelude :: * ;
1212use taffy:: tree:: LayoutTree ;
1313use wasm_bindgen:: prelude:: * ;
1414
@@ -94,51 +94,57 @@ impl Node {
9494
9595 #[ wasm_bindgen( js_name = setMeasure) ]
9696 pub fn set_measure ( & mut self , measure : & JsValue ) {
97- let _measure = Function :: from ( measure. clone ( ) ) ;
97+ // let js_measure_func = Arc::new(Mutex::new(Function::from(measure.clone())));
98+
99+ struct FuncWrap ( Function ) ;
100+ impl FuncWrap {
101+ fn apply ( & self , this : & JsValue , args : & Array ) -> Result < JsValue , JsValue > {
102+ self . 0 . apply ( this, args)
103+ }
104+ }
105+ // SAFETY: Wasm is single-threaded so there can't be multiple threads
106+ unsafe impl Send for FuncWrap { }
107+ unsafe impl Sync for FuncWrap { }
108+
109+ let js_measure_func = FuncWrap ( Function :: from ( measure. clone ( ) ) ) ;
110+
111+ let measure_func = move |known_dimensions : Size < Option < f32 > > , available_space : Size < AvailableSpace > | {
112+ fn convert_available_space ( val : AvailableSpace ) -> JsValue {
113+ match val {
114+ AvailableSpace :: Definite ( val) => val. into ( ) ,
115+ AvailableSpace :: MaxContent => JsValue :: from_str ( "max-content" ) ,
116+ AvailableSpace :: MinContent => JsValue :: from_str ( "min-content" ) ,
117+ }
118+ }
119+
120+ let known_width = known_dimensions. width . map ( |val| val. into ( ) ) . unwrap_or ( JsValue :: UNDEFINED ) ;
121+ let known_height = known_dimensions. height . map ( |val| val. into ( ) ) . unwrap_or ( JsValue :: UNDEFINED ) ;
122+
123+ let available_width = convert_available_space ( available_space. width ) ;
124+ let available_height = convert_available_space ( available_space. height ) ;
125+
126+ let args = Array :: new_with_length ( 4 ) ;
127+ args. set ( 0 , known_width) ;
128+ args. set ( 1 , known_height) ;
129+ args. set ( 2 , available_width) ;
130+ args. set ( 3 , available_height) ;
131+
132+ if let Ok ( result) = js_measure_func. apply ( & JsValue :: UNDEFINED , & args) {
133+ let width = get_f32 ( & result, "width" ) ;
134+ let height = get_f32 ( & result, "height" ) ;
135+
136+ if width. is_some ( ) && height. is_some ( ) {
137+ return Size { width : width. unwrap ( ) , height : height. unwrap ( ) } ;
138+ }
139+ }
140+
141+ known_dimensions. unwrap_or ( Size :: ZERO )
142+ } ;
98143
99144 self . allocator
100145 . taffy
101146 . borrow_mut ( )
102- . set_measure (
103- self . node ,
104- // TODO: fix setting measure functions
105- // Some(taffy::node::MeasureFunc::Boxed(Box::new(
106- // move |constraints| {
107- // use taffy::number::OrElse;
108-
109- // let widthConstraint =
110- // if let taffy::number::Number::Defined(val) = constraints.width {
111- // val.into()
112- // } else {
113- // JsValue::UNDEFINED
114- // };
115-
116- // let heightConstaint =
117- // if let taffy::number::Number::Defined(val) = constraints.height {
118- // val.into()
119- // } else {
120- // JsValue::UNDEFINED
121- // };
122-
123- // if let Ok(result) =
124- // measure.call2(&JsValue::UNDEFINED, &widthConstraint, &heightConstaint)
125- // {
126- // let width = get_f32(&result, "width");
127- // let height = get_f32(&result, "height");
128-
129- // if width.is_some() && height.is_some() {
130- // return taffy::geometry::Size {
131- // width: width.unwrap(),
132- // height: height.unwrap(),
133- // };
134- // }
135- // }
136-
137- // constraints.map(|v| v.or_else(0.0))
138- // },
139- // ))),
140- None ,
141- )
147+ . set_measure ( self . node , Some ( taffy:: node:: MeasureFunc :: Boxed ( Box :: new ( measure_func) ) ) )
142148 . unwrap ( ) ;
143149 }
144150
@@ -309,14 +315,13 @@ fn try_parse_from_i32<T: TryFrom<i32>>(style: &JsValue, property_key: &'static s
309315 get_i32 ( style, property_key) . and_then ( |i| T :: try_from ( i) . ok ( ) )
310316}
311317
312-
313318fn try_parse_dimension ( obj : & JsValue , key : & str ) -> Option < Dimension > {
314319 if let Some ( val) = get_key ( obj, key) {
315320 if let Some ( number) = val. as_f64 ( ) {
316321 return Some ( Dimension :: Points ( number as f32 ) ) ;
317322 }
318323 if let Some ( string) = val. as_string ( ) {
319- return string. parse ( ) . ok ( )
324+ return string. parse ( ) . ok ( ) ;
320325 }
321326 } ;
322327 None
@@ -338,7 +343,7 @@ fn try_parse_available_space(obj: &JsValue, key: &str) -> Option<AvailableSpace>
338343 return Some ( AvailableSpace :: Definite ( number as f32 ) ) ;
339344 }
340345 if let Some ( string) = val. as_string ( ) {
341- return string. parse ( ) . ok ( )
346+ return string. parse ( ) . ok ( ) ;
342347 }
343348 }
344349 None
0 commit comments