Created
April 19, 2020 10:04
-
-
Save tuzz/b44c0603e740a3bb62707c9449295cc1 to your computer and use it in GitHub Desktop.
A convenience wrapper for handling events in Rust using web_sys
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The EventHandler::new method takes three arguments: | |
// | |
// 1) The Rust function to call to handle the event | |
// 2) The registration function | |
// 3) The deregistration function | |
// | |
// The deregistration function is called when the EventHandler is dropped. | |
// This is similar to React's useEffect cleanup pattern. | |
pub struct EventHandler { | |
closure: Closure<dyn Fn(JsValue)>, | |
deregister: Box<dyn Fn(&Function)>, | |
} | |
impl EventHandler { | |
#[must_use = "the handler must be owned, otherwise it will be immediately deregistered"] | |
pub fn new<H: Fn(JsValue) + 'static, R: Fn(&Function), D: Fn(&Function) + 'static>(handler: H, register: R, deregister: D) -> Self { | |
let boxed = Box::new(handler) as Box<dyn Fn(_)>; | |
let closure = Closure::wrap(boxed); | |
let js_func = closure.as_ref().unchecked_ref(); | |
register(js_func); | |
Self { closure, deregister: Box::new(deregister) } | |
} | |
} | |
impl Drop for EventHandler { | |
fn drop(&mut self) { | |
let js_func = self.closure.as_ref().unchecked_ref(); | |
(self.deregister)(js_func); | |
} | |
} | |
pub struct KeyboardInput { | |
event_handler: EventHandler, | |
} | |
impl KeyboardInput { | |
pub fn new() -> Self { | |
let event_handler = EventHandler::new(Self::handle_click, |h| { | |
web_sys::window().unwrap() | |
.add_event_listener_with_callback("keydown", h).unwrap(); | |
}, |h| { | |
web_sys::window().unwrap() | |
.remove_event_listener_with_callback("keydown", h).unwrap(); | |
}); | |
Self { event_handler } | |
} | |
fn handle_click<E: Into<KeyboardEvent>>(event: E) { | |
let event = event.into(); | |
let key = event.key_code(); | |
log!("pressed {}", key); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment