RustとWebAssemblyで、四角いマスの中にランダムな数字を表示する。
環境
rustとwasmの開発環境はdocker。その中に、cargo-generateで wasm-packを利用してプロジェクトを作っています。
Dockerfile
FROM rustlang/rust:nightly
ENV PATH=/usr/local/cargo/bin:$PATH
RUN cargo install wasm-pack && cargo install cargo-generate
RUN set -x \
&& curl -sL https://deb.nodesource.com/setup_11.x | bash - \
&& apt-get install -y nodejs \
&& npm install npm@latest -g
build
docker build -t eg-rust .
run
docker run -it --rm -p 8080:8080 -e USER=$USER -v "$PWD":/usr/src/ -w /usr/src eg-rust /bin/bash
generate project
cargo generate --git https://github.com/rustwasm/wasm-pack-templa
te --name numbers
npm init
cd numbers
npm init wasm-app www
cd www
npm install
実装
Cargo.toml
dependenciesに wasm-bindgen対応の rand を追加
...
[dependencies]
rand = { version = "0.6", features = ["wasm-bindgen"] }
...
src/lib.rs
mod utils;
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
pub struct NumberMatrix {
width: u32,
height: u32,
numbers: Vec<u8>,
}
use rand::Rng;
#[wasm_bindgen]
impl NumberMatrix {
pub fn tick(&mut self) {
let mut rng = rand::thread_rng();
let numbers = (0..self.width * self.height)
.map(|_i|{
rng.gen_range(0, 9) as u8
})
.collect();
self.numbers = numbers;
}
pub fn new() -> NumberMatrix {
let width = 32;
let height = 32;
let numbers = (0..width * height)
.map(|_i| { 0 })
.collect();
NumberMatrix {
width,
height,
numbers,
}
}
pub fn width(&self) -> u32 {
self.width
}
pub fn height(&self) -> u32 {
self.height
}
pub fn numbers(&self) -> *const u8 {
self.numbers.as_ptr()
}
}
www/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello wasm-pack!</title>
</head>
<body>
<canvas id="mycanvas"></canvas>
<script src="./bootstrap.js"></script>
</body>
</html>
www/index.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello wasm-pack!</title>
</head>
<body>
<canvas id="mycanvas"></canvas>
<script src="./bootstrap.js"></script>
</body>
</html>
webpack.config.js
テスト用にdevServerを入れる。
module.exports = {
... 省略 ...
devServer: {
host: "0.0.0.0",
disableHostCheck: true
}
};
ビルド
(いらないかも)rustupの targetが足りなかったので。
rustup target add wasm32-unknown-unknown
wasm-pack
npm用のライブラリを作ってリンクさせる
wasm-pack build
cd pkg
npm link
cd ../www
npm link numbers
Run
cd www
npm start
こんな感じで数字が表示されて。高速で変わっていけばOK.
