👻
Rust + Web Worker(TypeScript + Vite)を試してみたメモ
概要
前回は「RustとWebAssemblyによるゲーム開発」の写経をした。
今回はRustとWeb Workerをつなげてみる。
ソースコード
package.json
{
"name": "@kartagraph/worker",
"type": "module",
"scripts": {
"build": "rimraf dist pkg && wasm-pack build --target web && tsc",
"watch-build": "cargo watch -w rust -s \"npm run build\""
},
"devDependencies": {
"rimraf": "^6.0.1",
}
}
lib.rs
use gloo_utils::format::JsValueSerdeExt;
use serde::{Deserialize, Serialize};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen]
pub fn console_log(message: &str) {
log(message)
}
#[derive(Serialize, Deserialize)]
pub struct Monster {
name: String,
value: String,
}
#[wasm_bindgen]
pub fn return_new_monster(val: &JsValue) -> JsValue {
let mut m: Monster = val.into_serde().unwrap();
m.value = "new value!!!".to_string();
JsValue::from_serde(&m).unwrap()
}
#[wasm_bindgen]
pub fn return_js_value() -> JsValue {
JsValue::NULL
}
sample.worker.ts
import init, { console_log, return_js_value, return_new_monster } from '../pkg/test_wasm';
import { GameCoreWorkerMessage } from './types';
(async () => {
await init();
console_log('hello from rust worker');
})();
self.addEventListener('message', (event: MessageEvent<GameCoreWorkerMessage>) => {
console.log('test web worker');
console_log('test from rust worker');
const wasmRet = return_js_value();
console.log(wasmRet);
const monster = return_new_monster({ name: 'test', value: 'てすと' });
console.log('monster', monster);
self.postMessage(event.data); // テストなのでそのまま返す
});
export default {};
sample.ts
import GameCoreWorker from '@kartagraph-worker/gameCore.worker?worker'; // ?workerをつける
export function atomWithGameCoreWorker() {
const worker = new GameCoreWorker(); // worker読み込み
worker.onmessage = (event) => {
const data = event.data;
console.log('message from worker', data);
};
worker.postMessage({test:'data'});
}
試してみた結果
ログが表示されることが確認できた。
watchを使ったとき、rustのソースを更新して自動再読み込みされたときはJSが壊れてしまい、ブラウザをリロードする必要があった。
参考
Worker → WASM / WASM → Worker
Github Game-Development-with-Rust-and-WebAssembly サンプルコード
MyIssue
RustのCargo.tomlの場所がrootに無い時にVSCodeでrust-analyzerのエラーを回避する方法
The Rust Programming Language
cargo watch
wasm-bindgen
JSValue
WebAssmbly開発環境構築の本
formatter
Rust の学習に役立つサイト
Discussion