From 2dfa2a10f71ec2dfa487dc977d7ad5e9db8df05f Mon Sep 17 00:00:00 2001 From: zzq Date: Fri, 5 Jul 2024 17:49:43 +0800 Subject: [PATCH] add wasm example --- examples/wasm/.gitignore | 2 + examples/wasm/Cargo.lock | 161 +++++++++++++++++++++++++++++++++++++++ examples/wasm/Cargo.toml | 17 +++++ examples/wasm/index.html | 27 +++++++ examples/wasm/index.js | 3 + examples/wasm/src/lib.rs | 117 ++++++++++++++++++++++++++++ 6 files changed, 327 insertions(+) create mode 100644 examples/wasm/.gitignore create mode 100644 examples/wasm/Cargo.lock create mode 100644 examples/wasm/Cargo.toml create mode 100644 examples/wasm/index.html create mode 100644 examples/wasm/index.js create mode 100644 examples/wasm/src/lib.rs diff --git a/examples/wasm/.gitignore b/examples/wasm/.gitignore new file mode 100644 index 0000000..e4113ef --- /dev/null +++ b/examples/wasm/.gitignore @@ -0,0 +1,2 @@ +/target +/pkg \ No newline at end of file diff --git a/examples/wasm/Cargo.lock b/examples/wasm/Cargo.lock new file mode 100644 index 0000000..257c87c --- /dev/null +++ b/examples/wasm/Cargo.lock @@ -0,0 +1,161 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "button-driver" +version = "0.2.1" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasm" +version = "0.1.0" +dependencies = [ + "button-driver", + "log", + "wasm-bindgen", + "wasm-logger", + "web-sys", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml new file mode 100644 index 0000000..d45c0fd --- /dev/null +++ b/examples/wasm/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wasm" +version = "0.1.0" +edition = "2021" + +[dependencies] +wasm-bindgen = { version = "0.2" } +web-sys = { version = "0.3.69", features = ["Window", "Document", "Element", "MouseEvent"] } +button-driver = { path = "../../" } +log = "0.4.22" +wasm-logger = "0.2.0" + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib"] + +[features] diff --git a/examples/wasm/index.html b/examples/wasm/index.html new file mode 100644 index 0000000..acdd9b4 --- /dev/null +++ b/examples/wasm/index.html @@ -0,0 +1,27 @@ + + + + Button example + + + + +
+ Press Area +
+
+

+ Please open developer tools console to view log. +

+ + diff --git a/examples/wasm/index.js b/examples/wasm/index.js new file mode 100644 index 0000000..761a6b4 --- /dev/null +++ b/examples/wasm/index.js @@ -0,0 +1,3 @@ +import init from "./pkg/wasm.js"; + +init(); diff --git a/examples/wasm/src/lib.rs b/examples/wasm/src/lib.rs new file mode 100644 index 0000000..36e7163 --- /dev/null +++ b/examples/wasm/src/lib.rs @@ -0,0 +1,117 @@ +use std::{cell::RefCell, ops::Sub, rc::Rc, time::Duration}; + +use button_driver::{Button, ButtonConfig, InstantProvider, Mode, PinWrapper}; +use log::info; +use wasm_bindgen::{closure::Closure, JsCast}; +use web_sys::{js_sys::Date, MouseEvent}; + +#[derive(PartialEq, Clone)] +struct WasmInstant(u64); + +impl WasmInstant { + fn now() -> WasmInstant { + WasmInstant(Date::now() as u64) + } +} + +impl Sub for WasmInstant { + type Output = Duration; + + fn sub(self, rhs: Self) -> Self::Output { + let delta_ms = self.0 - rhs.0; + return Duration::from_millis(delta_ms); + } +} + +impl InstantProvider for WasmInstant { + fn now() -> Self { + WasmInstant::now() + } +} + +#[derive(Clone, Default)] +struct MockButtonPin(Rc>); + +impl PinWrapper for MockButtonPin { + fn is_high(&mut self) -> bool { + *self.0.borrow() + } +} + +#[wasm_bindgen::prelude::wasm_bindgen(start)] +pub fn main() { + wasm_logger::init(wasm_logger::Config::default()); + let document = web_sys::window().unwrap().document().unwrap(); + let clickable_area = document.query_selector(".clickable-area").unwrap().unwrap(); + let pin_state = MockButtonPin::default(); + { + let pin_state_ref = pin_state.clone(); + let mouse_down_handler = Closure::wrap(Box::new(move |_: MouseEvent| { + *pin_state_ref.0.borrow_mut() = true; + }) as Box); + clickable_area + .add_event_listener_with_callback( + "mousedown", + mouse_down_handler.as_ref().unchecked_ref(), + ) + .unwrap(); + mouse_down_handler.forget(); + } + { + let pin_state_ref = pin_state.clone(); + let mouse_up_handler = Closure::wrap(Box::new(move |_: MouseEvent| { + *pin_state_ref.0.borrow_mut() = false; + }) as Box); + + clickable_area + .add_event_listener_with_callback("mouseup", mouse_up_handler.as_ref().unchecked_ref()) + .unwrap(); + mouse_up_handler.forget(); + } + { + let mut button = Button::<_, WasmInstant>::new( + pin_state, + ButtonConfig { + mode: Mode::PullDown, + ..Default::default() + }, + ); + let callback = Closure::wrap(Box::new(move || { + button.tick(); + + if let Some(dur) = button.held_time() { + info!("Total holding time {:?}", dur); + if button.is_clicked() { + info!("Clicked + held"); + } else if button.is_double_clicked() { + info!("Double clicked + held"); + } else if button.holds() == 2 && button.clicks() > 0 { + info!("Held twice with {} clicks", button.clicks()); + } else if button.holds() == 2 { + info!("Held twice"); + } + } else { + if button.is_clicked() { + info!("Click"); + } else if button.is_double_clicked() { + info!("Double click"); + } else if button.is_triple_clicked() { + info!("Triple click"); + } else if let Some(dur) = button.current_holding_time() { + info!("Held for {:?}", dur); + } + } + + button.reset(); + }) as Box); + + web_sys::window() + .unwrap() + .set_interval_with_callback_and_timeout_and_arguments_0( + callback.as_ref().unchecked_ref(), + 20, + ) + .unwrap(); + callback.forget(); + } +}