-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
187 additions
and
245 deletions.
There are no files selected for viewing
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,13 @@ | ||
# Exercises | ||
|
||
There are two exercises for Webassembly, they both live in their own repository inside of | ||
[rust-wasm-template](../rust-wasm-template). | ||
|
||
- [The Camera Exercise](camera.md) will give you access to the camera on your computer and offer you to | ||
apply transformations on the frames it captures. | ||
- [The Game Of Life Exercise](game-of-life.md) will have you implement _John Conway's Game Of Life_ using Webassembly. | ||
|
||
You can find the solutions here: | ||
|
||
- [Camera](solutions-camera.md) | ||
- [Game Of Life](solutions-game-of-life.md) |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,15 @@ | ||
extern crate console_error_panic_hook; | ||
|
||
use wasm_bindgen::prelude::*; | ||
|
||
#[wasm_bindgen] | ||
extern "C" { | ||
fn alert(s: &str); | ||
|
||
#[wasm_bindgen(js_namespace = console)] | ||
pub fn log(s: &str); | ||
} | ||
|
||
#[wasm_bindgen] | ||
pub fn set_panic_hook() { | ||
// Generates better error messages if our code ever panics. | ||
// | ||
// For more details see | ||
// https://github.com/rustwasm/console_error_panic_hook#readme | ||
console_error_panic_hook::set_once(); | ||
} | ||
|
||
#[wasm_bindgen] | ||
pub fn add(a: i32, b: i32) -> i32 { | ||
a + b | ||
pub type OutputBox; | ||
#[wasm_bindgen(constructor)] | ||
pub fn new(element: web_sys::HtmlElement) -> OutputBox; | ||
#[wasm_bindgen(method)] | ||
pub fn setText(this: &OutputBox, text: &str); | ||
#[wasm_bindgen(method, getter)] | ||
pub fn lastText(this: &OutputBox) -> Option<String>; | ||
#[wasm_bindgen(method, setter)] | ||
pub fn set_lastText(this: &OutputBox, text: Option<String>); | ||
#[wasm_bindgen(method, getter)] | ||
pub fn currentText(this: &OutputBox) -> String; | ||
} |
24 changes: 24 additions & 0 deletions
24
src/rust-wasm-template/static/exercises/game_of_life/index.mjs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import init, {setup, GameOfLife} from '/wasm/project.js'; | ||
|
||
|
||
(async () => { | ||
// Run the init method to initiate the WebAssembly module. | ||
await init(); | ||
setup(); | ||
const canvas = document.getElementById('game-of-life-canvas'); | ||
const ctx = canvas.getContext('2d'); | ||
const game = new GameOfLife(ctx, canvas.width, canvas.height); | ||
const startButton = document.querySelector('#start-button'); | ||
let handle = null; | ||
let playing = false; | ||
startButton.addEventListener('click', () => { | ||
if (handle === null) { | ||
handle = game.start(); | ||
playing = true; | ||
} else { | ||
handle.stop_or_start(); | ||
playing = !playing; | ||
} | ||
startButton.textContent = playing ? 'STOP' : 'START'; | ||
}); | ||
})(); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,7 @@ | ||
import init, {set_panic_hook, add} from '/wasm/project.js'; | ||
import init, { get_current_page} from '/wasm/project.js'; | ||
|
||
(async () => { | ||
// Run the init method to initiate the WebAssembly module. | ||
await init(); | ||
set_panic_hook(); | ||
document.querySelector("#wasmoutput").innerHTML = add(1, 2); | ||
console.log(await get_current_page()); | ||
})(); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,36 @@ | ||
# Async | ||
|
||
Rust methods in WebAssembly can be declared async. Once called, they will be scheduled on the browser's event loop. | ||
An event handler can for instance be implemented with a tokio channel. | ||
|
||
Instead of `tokio::spawn`, `wasm_bindgen` provides `wasm_bindgen_futures::spawn_local`. | ||
|
||
Let's create a class that waits for messages on a channel to rotate an HTML element: | ||
Rust methods in WebAssembly can be declared async. | ||
|
||
```rust | ||
use wasm_bindgen::prelude::*; | ||
use wasm_bindgen_futures::spawn_local; | ||
use tokio::sync::mpsc::{channel, Sender}; | ||
|
||
#[derive(Debug)] | ||
enum RotateSide { | ||
Left, | ||
Right, | ||
} | ||
|
||
#[wasm_bindgen] | ||
pub struct Rotator { | ||
sender: Sender<RotateSide>, | ||
} | ||
use wasm_bindgen_futures::JsFuture; | ||
use web_sys::Response; | ||
|
||
#[wasm_bindgen] | ||
impl Rotator { | ||
#[wasm_bindgen(constructor)] | ||
pub fn new(element: web_sys::HtmlElement) -> Rotator { | ||
let (sender, mut receiver) = channel::<RotateSide>(1); | ||
spawn_local(async move { | ||
let mut rotation = 0; | ||
while let Some(rotate_side) = receiver.recv().await { | ||
match rotate_side { | ||
RotateSide::Left => rotation -= 45, | ||
RotateSide::Right => rotation += 45, | ||
} | ||
element.set_inner_html(&rotation.to_string()); | ||
let style = element.style(); | ||
style | ||
.set_property("transform", &format!("rotate({rotation}deg)")) | ||
.expect("Failed to rotate"); | ||
} | ||
}); | ||
Rotator { sender } | ||
} | ||
|
||
#[wasm_bindgen] | ||
pub async fn rotate(&self, msg: String) -> Result<(), JsValue> { | ||
let rotate_side = match msg.as_str() { | ||
"ArrowLeft" => RotateSide::Left, | ||
"ArrowRight" => RotateSide::Right, | ||
_ => return Ok(()), | ||
}; | ||
self.sender | ||
.send(rotate_side) | ||
.await | ||
.map_err(|e| JsValue::from_str(&format!("Receiver dropped {:?}", e))) | ||
} | ||
pub async fn get_current_page() -> Result<JsValue, JsValue> { | ||
let window = web_sys::window().unwrap(); | ||
let resp_value = JsFuture::from(window.fetch_with_str("")).await?; | ||
let resp: Response = resp_value.dyn_into().unwrap(); | ||
let text = JsFuture::from(resp.text()?).await?; | ||
Ok(text) | ||
} | ||
``` | ||
|
||
Let's call it from Javascript | ||
|
||
```javascript | ||
import init, {Rotator} from '/wasm/project.js'; | ||
import init, { get_current_page} from '/wasm/project.js'; | ||
|
||
(async () => { | ||
// Run the init method to initiate the WebAssembly module. | ||
await init(); | ||
const wasmoutput = document.querySelector('#wasmoutput'); | ||
const rotator = new Rotator(wasmoutput); | ||
document.body.addEventListener('keydown', async (e) => { | ||
await rotator.rotate(e.key); | ||
}); | ||
console.log(await get_current_page()); | ||
})(); | ||
|
||
``` | ||
|
||
<details> | ||
|
||
- Async methods are scheduled on the Javascript event loop. | ||
- Instead of `tokio::spawn`, `wasm_bindgen` provides `wasm_bindgen_futures::spawn_local`. | ||
- We use `JsFuture::from` to convert Javascript futures to Rust futures that we can `.await`. | ||
|
||
</details> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Error handling | ||
|
||
In this chapter we cover error handling both on the Rust side for imported Javascript methods | ||
and on the Javascript side for imported Rust methods. | ||
|
||
- [Error handling for imported methods](error-handling/imported-methods.md) | ||
- [Error handling for exported methods](error-handling/exported-methods.md) |
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
File renamed without changes.
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
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
Oops, something went wrong.