hassium_input_device_web/
keyboard.rs1use input::{device::InputDevice, Scalar};
2use std::{any::Any, cell::RefCell, collections::HashSet, rc::Rc};
3use wasm_bindgen::{prelude::*, JsCast};
4use web_sys::*;
5
6pub type KeyCode = (char, String);
8
9pub struct WebKeyboardInputDevice {
10 element: EventTarget,
11 keys: Rc<RefCell<HashSet<String>>>,
12 sequence: Rc<RefCell<Vec<KeyCode>>>,
13 last_sequence: Vec<KeyCode>,
14}
15
16unsafe impl Send for WebKeyboardInputDevice {}
17unsafe impl Sync for WebKeyboardInputDevice {}
18
19impl WebKeyboardInputDevice {
20 pub fn new(element: EventTarget) -> Self {
21 Self {
22 element,
23 keys: Default::default(),
24 sequence: Rc::new(RefCell::new(Vec::with_capacity(128))),
25 last_sequence: Vec::with_capacity(128),
26 }
27 }
28
29 pub fn last_sequence(&self) -> &[KeyCode] {
30 &self.last_sequence
31 }
32}
33
34impl InputDevice for WebKeyboardInputDevice {
35 fn name(&self) -> &str {
36 "keyboard"
37 }
38
39 fn on_register(&mut self) {
40 {
41 let keys = self.keys.clone();
42 let sequence = self.sequence.clone();
43 let closure = Closure::wrap(Box::new(move |event: KeyboardEvent| {
44 let code = event.code();
45 let key = event.key();
46 keys.borrow_mut().insert(code.clone());
47 if key.len() > 1 {
48 sequence.borrow_mut().push((0 as char, code));
49 } else if key.len() == 1 {
50 sequence
51 .borrow_mut()
52 .push((key.chars().next().unwrap(), code));
53 }
54 }) as Box<dyn FnMut(_)>);
55 self.element
56 .add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref())
57 .unwrap();
58 closure.forget();
59 }
60 {
61 let keys = self.keys.clone();
62 let closure = Closure::wrap(Box::new(move |event: KeyboardEvent| {
63 keys.borrow_mut().remove(&event.code());
64 }) as Box<dyn FnMut(_)>);
65 self.element
66 .add_event_listener_with_callback("keyup", closure.as_ref().unchecked_ref())
67 .unwrap();
68 closure.forget();
69 }
70 }
71
72 fn on_unregister(&mut self) {
73 }
75
76 fn process(&mut self) {
77 self.last_sequence.clear();
78 self.last_sequence.append(&mut self.sequence.borrow_mut());
79 }
80
81 fn query_axis(&self, name: &str) -> Option<Scalar> {
82 Some(if self.keys.borrow().contains(name) {
83 1.0
84 } else {
85 0.0
86 })
87 }
88
89 fn query_trigger(&self, name: &str) -> Option<bool> {
90 Some(self.keys.borrow().contains(name))
91 }
92
93 fn as_any(&self) -> &dyn Any {
94 self
95 }
96}