前回の記事の補足
プロジェクトテンプレートを使った方法
- 前回の記事では素のプロジェクトから Cargo.toml や Rustのコードを書いたが、プロジェクトテンプレートを利用する方法もある。
- まず cargo-generate をインストールしておく。
cargo install cargo-generate
- プロジェクトテンプレートを作成する。プロジェクト名は対話式で入力する。
cargo generate --git https://github.com/rustwasm/wasm-pack-template
- プロジェクトをビルドする。
wasm-pack build
- 詳細は下記の記事を参照。
cargoでWebサーバを導入
- 前回の記事ではVSCodeのLive ServerでWebサーバを起動したが、cargoで簡単なWebサーバを導入することもできる。
- cargo で http-server をインストール。
cargo install http-server
- ポート番号 8080 でWebサーバを起動。
http-server --port 8080
canvasへの描画
- 下記の記事が参考になった。
グローバル変数が使えない
- Rustでは原則的にはグローバル変数のようなものは使えない。ではアプリ全体で共有する状態はどのように持つのか?
- トップの関数で変数を定義して可変参照(&mut)で下位の関数に渡していく。
- この方法では、イベントハンドラに変数を渡したいときに問題が起こる。イベントハンドラをクロージャーで書いて変数を使うと所有権が移動するのだ。そのような場合には 変数を Rc<Cell< >>でくるんで所有権を共有できるようにする。
- ただし、クロージャーもスコープの外に出ると消滅してしまう。それを防ぐために .forget() で所有権を忘れさせる。(JavaScript側のGCに委ねる。)
- 下記の記事が参考になった。
グローバル変数を使いたい (1)
- どうしてもグローバル変数を使いたい場合、static mut で定義できる。
- しかしこれは非推奨であり、static mut な変数を使うときは unsafe{ } で括らなければならない。
- thread_local!( )内で static な RefCell<T> または Rc<Cell<T>> で変数を定義するほうがベターらしい。(未検証)
グローバル変数を使いたい (2)
- thread_local!( )はスレッドセーフだが、スレッドごとに別々のインスタンスになる。(スレッド間で共有できない。)
- once_cell を使えば、いわゆるシングルトンを実現できるらしい。(未検証)
グローバル変数を使いたい (3)
- 生ポインタというものがあるらしい。(未検証)
requestAnimationFrame
- JavaScriptの requestAnimationFrame ループを実現するには、下記のようにする。
→ web-sys: requestAnimationFrame - The `wasm-bindgen` Guide - ちょっと分かりにくい。下記の記事が参考になった。
参考