1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
//! A wrapper library around `hotdrink-rs` for compilation to WebAssembly. //! //! [![Crates.io][crates-badge]][crates-url] //! [![docs.rs](https://docs.rs/hotdrink-wasm/badge.svg)](https://docs.rs/hotdrink-wasm) //! //! [crates-badge]: https://img.shields.io/crates/v/hotdrink-wasm.svg //! [crates-url]: https://crates.io/crates/hotdrink-wasm //! //! # Prerequisites //! //! The project uses multiple nightly features, and must be built using nightly Rust. //! I recommend using `rustup`, which can be downloaded [here](https://rustup.rs/), //! //! You also need `wasm-pack` to compile your project to WebAssembly, which can be downloaded [here](https://rustwasm.github.io/wasm-pack/installer/). //! //! The standard library must be recompiled with atomics enabled to use Web Workers as threads, //! which means that we need the standard library source code. //! This can be downloaded with `rustup component add rust-src`. //! //! # Usage //! //! Add the following to your `Cargo.toml`: //! //! ```toml //! hotdrink-wasm = "0.1.1" //! ``` //! //! ## Single threaded //! //! ```rust //! use hotdrink_rs::{component, model::ConstraintSystem}; //! use hotdrink_wasm::{component_type_wrapper, constraint_system_wrapper}; //! use wasm_bindgen::{JsValue, prelude::wasm_bindgen}; //! //! component_type_wrapper! { //! pub struct ValueWrapper { //! #[derive(Clone, Debug)] //! pub enum Value { //! i32, //! String //! } //! } //! } //! //! constraint_system_wrapper!(MyCs, ValueWrapper, Value); //! //! #[wasm_bindgen] //! pub fn make_cs() -> Result<MyCs, JsValue> { //! let mut cs = ConstraintSystem::new(); //! cs.add_component(component! { //! component MyComponent { //! let a: i32 = 0, b: String = ""; //! // <contraints> //! } //! }); //! MyCs::wrap(cs) //! } //! ``` //! //! After producing a JavaScript module in www/pkg with //! ```bash //! wasm-pack build --out-dir www/pkg --release //! ``` //! you can use the wrapper like this: //! //! ```javascript //! let cs = wasm.make_cs(); //! cs.subscribe("MyComponent", "a", //! new_value => console.log("a =", new_value), //! () => console.log("a is pending"), //! err => console.log("a failed:", err) //! ); //! cs.set_variable("MyComponent", "a", wasm.ValueWrapper.i32(5)); //! cs.set_variable("MyComponent", "b", wasm.ValueWrapper.String("Hello")); //! cs.update(); //! ``` //! //! ## Multithreaded //! //! Remember to add the `thread` feature flag in your `Cargo.toml`. //! //! ```toml //! hotdrink-wasm = { version = "0.1.1", features = ["thread"] } //! ``` //! //! To use a multithreaded constraint system, you would create it like this instead: //! //! ```rust //! use hotdrink_wasm::{component_type_wrapper}; //! #[cfg(feature = "thread")] //! use hotdrink_wasm::{constraint_system_wrapper_threaded, thread::{StaticPool, TerminationStrategy}}; //! //! component_type_wrapper! { //! pub struct ValueWrapper { //! #[derive(Clone, Debug)] //! pub enum Value { //! i32, //! String //! } //! } //! } //! //! #[cfg(feature = "thread")] //! constraint_system_wrapper_threaded!( //! MyCs, //! ValueWrapper, //! Value, //! StaticPool, // Or DynamicPool //! 4, // Number of threads //! TerminationStrategy::UnusedResultAndNotDone //! ); //! ``` //! //! To use Web Workers from Rust, the we must compile with `--target no-modules`. //! //! ```bash //! wasm-pack build --out-dir www/pkg --target no-modules --release //! ``` //! //! This will produce WebAssembly code and JS wrappers in www/pkg, which can then be imported there. //! See wasm-pack's documentation for more information. #![warn( missing_copy_implementations, missing_debug_implementations, rust_2018_idioms, missing_docs )] #![feature(test)] #![feature(result_flattening)] #![feature(stmt_expr_attributes)] #![feature(drain_filter)] #![feature(concat_idents)] pub mod event; pub mod macros; pub mod thread; pub mod util; /// Check how long it takes for a web worker running Wasm to start. #[cfg(feature = "thread")] #[wasm_bindgen::prelude::wasm_bindgen] pub fn bench_web_worker_init() { use js_sys::Date; use thread::worker::generic_worker::GenericWorker; let start = Date::now(); let worker = GenericWorker::new("TestWorker").unwrap(); worker .execute(Box::new(move |_| { let end = Date::now(); log::info!("Spawning web worker took {}ms", end - start); })) .unwrap(); }