mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-25 14:12:13 +00:00
Add a smorgasboard example
This commit is contained in:
parent
4aa6793b9e
commit
4ebb3df330
@ -17,4 +17,5 @@ test-support = { path = "crates/test-support" }
|
||||
members = [
|
||||
"crates/wasm-bindgen-cli",
|
||||
"examples/hello_world",
|
||||
"examples/smorgasboard",
|
||||
]
|
||||
|
@ -223,6 +223,12 @@ $ npm run serve
|
||||
If you open https://localhost:8080 in a browser you should see a `Hello, world!`
|
||||
dialog pop up!
|
||||
|
||||
If that was all a bit much, no worries! You can [follow along
|
||||
online][hello-tree] to see all the files necessary as well as a script to set it
|
||||
all up.
|
||||
|
||||
[hello-tree]: https://github.com/alexcrichton/wasm-bindgen/tree/master/examples/hello_world
|
||||
|
||||
## What just happened?
|
||||
|
||||
Phew! That was a lot of words and a lot ended up happening along the way. There
|
||||
@ -329,7 +335,7 @@ extern {
|
||||
#[wasm_bindgen]
|
||||
impl Bar {
|
||||
pub fn from_str(s: &str, opaque: JsValue) -> Bar {
|
||||
let contents = s.parse().unwrap_or_else(|| {
|
||||
let contents = s.parse().unwrap_or_else(|_| {
|
||||
Awesome::new().get_internal()
|
||||
});
|
||||
Bar { contents, opaque }
|
||||
|
@ -9,3 +9,6 @@ The examples here are:
|
||||
|
||||
* `hello_world` - the "hello world" of `#[wasm_bindgen]`, aka throwing up a
|
||||
dialog greeting you
|
||||
* `smorgasboard` - a bunch of features all thrown into one, showing off the
|
||||
various capabilities of the `#[wasm_bindgen]` macro and what you can do with
|
||||
it from JS
|
||||
|
3
examples/smorgasboard/.gitignore
vendored
Normal file
3
examples/smorgasboard/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
package-lock.json
|
||||
smorgasboard.js
|
||||
smorgasboard_wasm.wasm
|
14
examples/smorgasboard/Cargo.toml
Normal file
14
examples/smorgasboard/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "smorgasboard"
|
||||
version = "0.1.0"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
# Here we're using a path dependency to use what's already in this repository,
|
||||
# but you'd use the commented out version below if you're copying this into your
|
||||
# project.
|
||||
wasm-bindgen = { path = "../.." }
|
||||
#wasm-bindgen = { git = "https://github.com/alexcrichton/wasm-bindgen" }
|
16
examples/smorgasboard/README.md
Normal file
16
examples/smorgasboard/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Smorgasboard of examples
|
||||
|
||||
This directory is an smattering of examples using the `#[wasm_bindgen]` macro.
|
||||
Here we see passing strings back and for, exporting classes from Rust to JS,
|
||||
importing classes from JS to Rust, etc.
|
||||
|
||||
You can build the example with:
|
||||
|
||||
```
|
||||
$ ./build.sh
|
||||
```
|
||||
|
||||
(or running the two commands on Windows manually)
|
||||
|
||||
and then opening up `index.html` in a web browser should show a dialog saying
|
||||
"all passed" as well as some console output.
|
32
examples/smorgasboard/app.js
Normal file
32
examples/smorgasboard/app.js
Normal file
@ -0,0 +1,32 @@
|
||||
import { Foo, Bar, concat } from "./smorgasboard";
|
||||
|
||||
function assertEq(a, b) {
|
||||
if (a !== b)
|
||||
throw new Error(`${a} != ${b}`);
|
||||
console.log(`found ${a} === ${b}`);
|
||||
}
|
||||
|
||||
assertEq(concat('a', 'b'), 'ab');
|
||||
|
||||
// Note the `new Foo()` syntax cannot be used, static function
|
||||
// constructors must be used instead. Additionally objects allocated
|
||||
// corresponding to Rust structs will need to be deallocated on the
|
||||
// Rust side of things with an explicit call to `free`.
|
||||
let foo = Foo.new();
|
||||
assertEq(foo.add(10), 10);
|
||||
foo.free();
|
||||
|
||||
// Pass objects to one another
|
||||
let foo1 = Foo.new();
|
||||
let bar = Bar.from_str("22", { opaque: 'object' });
|
||||
foo1.add_other(bar);
|
||||
|
||||
// We also don't have to `free` the `bar` variable as this function is
|
||||
// transferring ownership to `foo1`
|
||||
bar.reset('34');
|
||||
foo1.consume_other(bar);
|
||||
|
||||
assertEq(foo1.add(2), 22 + 34 + 2);
|
||||
foo1.free();
|
||||
|
||||
alert('all passed!')
|
14
examples/smorgasboard/awesome.js
Normal file
14
examples/smorgasboard/awesome.js
Normal file
@ -0,0 +1,14 @@
|
||||
export function bar_on_reset(s, token) {
|
||||
console.log(token);
|
||||
console.log(`this instance of bar was reset to ${s}`);
|
||||
}
|
||||
|
||||
export class Awesome {
|
||||
constructor() {
|
||||
this.internal = 32;
|
||||
}
|
||||
|
||||
get_internal() {
|
||||
return this.internal;
|
||||
}
|
||||
}
|
15
examples/smorgasboard/build.sh
Executable file
15
examples/smorgasboard/build.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
cargo +nightly build --target wasm32-unknown-unknown --release
|
||||
|
||||
# Here we're using the version of the CLI in this repository, but for external
|
||||
# usage you'd use the commented out version below
|
||||
cargo +nightly run --manifest-path ../../crates/wasm-bindgen-cli/Cargo.toml \
|
||||
--bin wasm-bindgen -- \
|
||||
../../target/wasm32-unknown-unknown/release/smorgasboard.wasm --out-dir .
|
||||
# wasm-bindgen ../../target/wasm32-unknown-unknown/hello_world.wasm --out-dir .
|
||||
|
||||
npm install
|
||||
npm run serve
|
8
examples/smorgasboard/index.html
Normal file
8
examples/smorgasboard/index.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
|
||||
</head>
|
||||
<body>
|
||||
<script src='./index.js'></script>
|
||||
</body>
|
||||
</html>
|
1
examples/smorgasboard/index.js
Normal file
1
examples/smorgasboard/index.js
Normal file
@ -0,0 +1 @@
|
||||
import("./app");
|
10
examples/smorgasboard/package.json
Normal file
10
examples/smorgasboard/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.0.1",
|
||||
"webpack-cli": "^2.0.10",
|
||||
"webpack-dev-server": "^3.1.0"
|
||||
}
|
||||
}
|
79
examples/smorgasboard/src/lib.rs
Normal file
79
examples/smorgasboard/src/lib.rs
Normal file
@ -0,0 +1,79 @@
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
// Strings can both be passed in and received
|
||||
#[wasm_bindgen]
|
||||
#[no_mangle]
|
||||
pub extern fn concat(a: &str, b: &str) -> String {
|
||||
let mut a = a.to_string();
|
||||
a.push_str(b);
|
||||
return a
|
||||
}
|
||||
|
||||
// A struct will show up as a class on the JS side of things
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
contents: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
pub fn new() -> Foo {
|
||||
Foo { contents: 0 }
|
||||
}
|
||||
|
||||
// Methods can be defined with `&mut self` or `&self`, and arguments you
|
||||
// can pass to a normal free function also all work in methods.
|
||||
pub fn add(&mut self, amt: u32) -> u32 {
|
||||
self.contents += amt;
|
||||
return self.contents
|
||||
}
|
||||
|
||||
// You can also take a limited set of references to other types as well.
|
||||
pub fn add_other(&mut self, bar: &Bar) {
|
||||
self.contents += bar.contents;
|
||||
}
|
||||
|
||||
// Ownership can work too!
|
||||
pub fn consume_other(&mut self, bar: Bar) {
|
||||
self.contents += bar.contents;
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Bar {
|
||||
contents: u32,
|
||||
opaque: JsValue, // defined in `wasm_bindgen`, imported via prelude
|
||||
}
|
||||
|
||||
#[wasm_bindgen(module = "./awesome")] // what ES6 module to import from
|
||||
extern {
|
||||
fn bar_on_reset(to: &str, opaque: &JsValue);
|
||||
|
||||
// We can import classes and annotate functionality on those classes as well
|
||||
type Awesome;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Awesome;
|
||||
#[wasm_bindgen(method)]
|
||||
fn get_internal(this: &Awesome) -> u32;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Bar {
|
||||
pub fn from_str(s: &str, opaque: JsValue) -> Bar {
|
||||
let contents = s.parse().unwrap_or_else(|_| {
|
||||
Awesome::new().get_internal()
|
||||
});
|
||||
Bar { contents, opaque }
|
||||
}
|
||||
|
||||
pub fn reset(&mut self, s: &str) {
|
||||
if let Ok(n) = s.parse() {
|
||||
bar_on_reset(s, &self.opaque);
|
||||
self.contents = n;
|
||||
}
|
||||
}
|
||||
}
|
10
examples/smorgasboard/webpack.config.js
Normal file
10
examples/smorgasboard/webpack.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: "./index.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "index.js",
|
||||
},
|
||||
mode: "development"
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user