2
2
3
3
mod utils;
4
4
5
- use core:: str:: FromStr ;
6
5
use std:: cell:: RefCell ;
7
6
use std:: rc:: Rc ;
8
7
8
+ use js_sys:: Array ;
9
9
use js_sys:: Function ;
10
10
use js_sys:: Reflect ;
11
- use taffy:: style :: * ;
11
+ use taffy:: prelude :: * ;
12
12
use taffy:: tree:: LayoutTree ;
13
13
use wasm_bindgen:: prelude:: * ;
14
14
@@ -94,51 +94,57 @@ impl Node {
94
94
95
95
#[ wasm_bindgen( js_name = setMeasure) ]
96
96
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
+ } ;
98
143
99
144
self . allocator
100
145
. taffy
101
146
. 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) ) ) )
142
148
. unwrap ( ) ;
143
149
}
144
150
@@ -309,14 +315,13 @@ fn try_parse_from_i32<T: TryFrom<i32>>(style: &JsValue, property_key: &'static s
309
315
get_i32 ( style, property_key) . and_then ( |i| T :: try_from ( i) . ok ( ) )
310
316
}
311
317
312
-
313
318
fn try_parse_dimension ( obj : & JsValue , key : & str ) -> Option < Dimension > {
314
319
if let Some ( val) = get_key ( obj, key) {
315
320
if let Some ( number) = val. as_f64 ( ) {
316
321
return Some ( Dimension :: Points ( number as f32 ) ) ;
317
322
}
318
323
if let Some ( string) = val. as_string ( ) {
319
- return string. parse ( ) . ok ( )
324
+ return string. parse ( ) . ok ( ) ;
320
325
}
321
326
} ;
322
327
None
@@ -338,7 +343,7 @@ fn try_parse_available_space(obj: &JsValue, key: &str) -> Option<AvailableSpace>
338
343
return Some ( AvailableSpace :: Definite ( number as f32 ) ) ;
339
344
}
340
345
if let Some ( string) = val. as_string ( ) {
341
- return string. parse ( ) . ok ( )
346
+ return string. parse ( ) . ok ( ) ;
342
347
}
343
348
}
344
349
None
0 commit comments