Skip to content

Commit 4fe585d

Browse files
committed
Enable measure func setting
1 parent fbf0604 commit 4fe585d

File tree

1 file changed

+51
-46
lines changed

1 file changed

+51
-46
lines changed

bindings/wasm/src/lib.rs

+51-46
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
mod utils;
44

5-
use core::str::FromStr;
65
use std::cell::RefCell;
76
use std::rc::Rc;
87

8+
use js_sys::Array;
99
use js_sys::Function;
1010
use js_sys::Reflect;
11-
use taffy::style::*;
11+
use taffy::prelude::*;
1212
use taffy::tree::LayoutTree;
1313
use 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-
313318
fn 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

Comments
 (0)