[−][src]Struct virtual_dom_rs::Closure
A handle to both a closure in Rust as well as JS closure which will invoke the Rust closure.
A Closure
is the primary way that a 'static
lifetime closure is
transferred from Rust to JS. Closure
currently requires that the closures
it's created with have the 'static
lifetime in Rust for soundness reasons.
This type is a "handle" in the sense that whenever it is dropped it will
invalidate the JS closure that it refers to. Any usage of the closure in JS
after the Closure
has been dropped will raise an exception. It's then up
to you to arrange for Closure
to be properly deallocate at an appropriate
location in your program.
The type parameter on Closure
is the type of closure that this represents.
Currently this can only be the Fn
and FnMut
traits with up to 7
arguments (and an optional return value). The arguments/return value of the
trait must be numbers like u32
for now, although this restriction may be
lifted in the future!
Example
Sample usage of Closure
to invoke the setTimeout
API.
#[wasm_bindgen] extern "C" { fn setTimeout(closure: &Closure<FnMut()>, time: u32); #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } #[wasm_bindgen] pub struct ClosureHandle(Closure<FnMut()>); #[wasm_bindgen] pub fn run() -> ClosureHandle { // First up we use `Closure::wrap` to wrap up a Rust closure and create // a JS closure. let cb = Closure::wrap(Box::new(move || { log("timeout elapsed!"); }) as Box<FnMut()>); // Next we pass this via reference to the `setTimeout` function, and // `setTimeout` gets a handle to the corresponding JS closure. setTimeout(&cb, 1_000); // If we were to drop `cb` here it would cause an exception to be raised // when the timeout elapses. Instead we *return* our handle back to JS // so JS can tell us later when it would like to deallocate this handle. ClosureHandle(cb) }
Sample usage of the same example as above except using web_sys
instead
extern crate wasm_bindgen; extern crate web_sys; use wasm_bindgen::JsCast; #[wasm_bindgen] pub struct ClosureHandle(Closure<FnMut()>); #[wasm_bindgen] pub fn run() -> ClosureHandle { let cb = Closure::wrap(Box::new(move || { web_sys::console::log_1(&"timeout elapsed!".into()); }) as Box<FnMut()>); let window = web_sys::window().unwrap(); window.set_timeout_with_callback_and_timeout_and_arguments_0( // Note this method call, which uses `as_ref()` to get a `JsValue` // from our `Closure` which is then converted to a `&Function` // using the `JsCast::unchecked_ref` function. cb.as_ref().unchecked_ref(), 1_000, ); // same as above ClosureHandle(cb) }
Methods
impl<T> Closure<T> where
T: WasmClosure + ?Sized,
[src]
T: WasmClosure + ?Sized,
pub fn new<F>(t: F) -> Closure<T> where
F: Unsize<T> + 'static,
[src]
F: Unsize<T> + 'static,
Creates a new instance of Closure
from the provided Rust closure.
Note that the closure provided here, F
, has a few requirements
associated with it:
- It must implement
Fn
orFnMut
- It must be
'static
, aka no stack references (use themove
keyword) - It can have at most 7 arguments
- Its arguments and return values are all wasm types like u32/f64.
This is unfortunately pretty restrictive for now but hopefully some of these restrictions can be lifted in the future!
This method requires the nightly
feature of the wasm-bindgen
crate
to be enabled, meaning this is a nightly-only API. Users on stable
should use Closure::wrap
.
pub fn wrap(data: Box<T>) -> Closure<T>
[src]
A mostly internal function to wrap a boxed closure inside a Closure
type.
This is the function where the JS closure is manufactured.
pub fn forget(self)
[src]
Leaks this Closure
to ensure it remains valid for the duration of the
entire program.
Note: this function will leak memory. It should be used sparingly to ensure the memory leak doesn't affect the program too much.
When a Closure
is dropped it will invalidate the associated JS
closure, but this isn't always desired. Some callbacks are alive for
the entire duration of the program, so this can be used to conveniently
leak this instance of Closure
while performing as much internal
cleanup as it can.
Trait Implementations
impl<T> Drop for Closure<T> where
T: ?Sized,
[src]
T: ?Sized,
impl<T> AsRef<JsValue> for Closure<T> where
T: ?Sized,
[src]
T: ?Sized,
impl<'a, T> IntoWasmAbi for &'a Closure<T> where
T: WasmClosure + ?Sized,
[src]
T: WasmClosure + ?Sized,
Auto Trait Implementations
Blanket Implementations
impl<T> From for T
[src]
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = !
try_from
)The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,