Clean up the WebComponentHandle closure.

Had a misunderstanding regarding closure lifetimes.
This commit is contained in:
Jeremy Wall 2022-10-09 15:51:31 -04:00
parent 7ffcab1416
commit 94e8ee07c6
2 changed files with 10 additions and 15 deletions

View File

@ -109,7 +109,7 @@ fn expand_struct_trait_shim(struct_name: &Ident, observed_attrs: Literal) -> syn
<Self as #trait_path>::class_name() <Self as #trait_path>::class_name()
} }
pub fn define() -> std::result::Result<#handle_path<#struct_name>, JsValue> { pub fn define() -> std::result::Result<#handle_path, JsValue> {
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
use web_sys::{window, Element, HtmlElement}; use web_sys::{window, Element, HtmlElement};
let registry = web_sys::window().unwrap().custom_elements(); let registry = web_sys::window().unwrap().custom_elements();
@ -151,21 +151,20 @@ return element;",
element_name = Self::element_name(), element_name = Self::element_name(),
observed_attributes = #observed_attrs, observed_attributes = #observed_attrs,
); );
let fun = Function::new_with_args("impl", &body); let fun = js_sys::Function::new_with_args("impl", &body);
let f: Box<dyn FnMut() -> Self> = Box::new(|| { let f: Box<dyn FnMut() -> Self> = Box::new(|| {
let obj = Self::new(); let obj = Self::new();
obj obj
}); });
let constructor_handle = Closure::wrap(f); let constructor_handle = wasm_bindgen::prelude::Closure::wrap(f).into_js_value().unchecked_into::<js_sys::Function>();
let element = fun let element = fun
.call1( .call1(
&window().unwrap(), &window().unwrap(),
constructor_handle.as_ref().unchecked_ref::<Function>(), constructor_handle.as_ref(),
)? )?
.dyn_into()?; .dyn_into()?;
Ok(WebComponentHandle { Ok(#handle_path {
element_constructor: element, element_constructor: element,
impl_handle: constructor_handle,
}) })
} }
} }

View File

@ -1,5 +1,5 @@
use js_sys::Function; use js_sys::Function;
use wasm_bindgen::{convert::IntoWasmAbi, prelude::Closure, JsValue}; use wasm_bindgen::{convert::IntoWasmAbi, JsValue};
use web_sys::{window, Element, Event, HtmlElement, Window}; use web_sys::{window, Element, Event, HtmlElement, Window};
/// This attribute proc-macro will generate the following trait implementations /// This attribute proc-macro will generate the following trait implementations
@ -73,13 +73,9 @@ pub trait WebComponentBinding: WebComponentDef {
/// of the callback functions for the component. /// of the callback functions for the component.
pub trait WebComponent: WebComponentBinding {} pub trait WebComponent: WebComponentBinding {}
/// A handle for your WebComponent Definition. It is important that this /// A handle for your WebComponent Definition. Offers easy access to construct your
/// handle is live for as long as your Web-Component might be used. /// element.
pub struct WebComponentHandle<T> { pub struct WebComponentHandle {
/// The handle for the closure that is used to construct your Rust instance
/// in the Javascript shim constructor. If this is dropped then your web component
/// will not be able to be constructed properly.
pub impl_handle: Closure<dyn FnMut() -> T>,
/// A javascript function that can construct your element. /// A javascript function that can construct your element.
pub element_constructor: Function, pub element_constructor: Function,
} }
@ -164,7 +160,7 @@ mod tests {
} }
Timer::new("custom-element::timing"); Timer::new("custom-element::timing");
let handle = BenchElement::define(); let _ = BenchElement::define();
let body = window().unwrap().document().unwrap().body().unwrap(); let body = window().unwrap().document().unwrap().body().unwrap();
for _ in 1..100000 { for _ in 1..100000 {