Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RustでWebブロック崩し作ってみた

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 RustでWebブロック崩し作ってみた

【とらのあな主催】オタクが最新技術を追うライトニングトークイベント9回目 in渋谷で発表した資料です。

Avatar for 虎の穴ラボ株式会社

虎の穴ラボ株式会社

October 30, 2019
Tweet

More Decks by 虎の穴ラボ株式会社

Other Decks in Technology

Transcript

  1. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. アジェンダ

    • 自己紹介 • 動機と話すこと • なぜRust • 作ったもの • Rust • wasm-bindgen • まとめ 2
  2. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 自己紹介

    3 let user = User { name: "藤原 佳顕".to_string(), age: 29, work: "Fantia開発(フロントエンド中心になんでも)".to_string(), tech: vec!["TypeScript","React", “Vue”,"RoR","(Rust)"], anime: "無限の住人".to_string(), hobby: vec!["Hellsinker.","ダライアス外伝","レイストーム"] };
  3. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 動機と話すこと

    • Rust+WebAssemblyでブロック崩し作ってみたので紹介 • 話すこと – Rustの概要 – wasm-bindgenについて – 書いたソース • 話さないこと – WebWorkerについて – JavaScript/TypeScript側の細かいあれこれ – Rustの細かい文法 – ビルドツールについて 4
  4. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. なぜRust

    • Rust使いたかった(趣味) • 自分→フロントエンド得意ななんでも屋 – React.js、TypeScriptとか好きです • 得意分野を消さないための種まきとしてWebAssembly • Rustは公式でWebAssemblyのサポートがある – wasm32-unknown-unknownターゲット • C/C++→Emscripten • Go→バイナリでかい問題 • 他 – Blazor、AssemblyScript 5
  5. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 作ったもの

    ・MDNのCanvasブロック崩しのRust移植+α (https://yumenosora.co.jp/archives/tora-lab/1575) 6
  6. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 作ったもの

    採用サイトのトップからも飛べます (https://yumenosora.co.jp/tora-lab) 7
  7. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. Rust

    • C++の代替を狙う低レイヤ言語 • 速度 – (LLVMなので)C/C++と同程度 • パラダイム – マルチパラダイム – 関数型言語っぽくもオブジェクト指向っぽくも書ける • 難しい? – コンパイラが優秀なので適当に怒られておけば良いと思います • 言語が出てきた当初からWebAssemblyのサポートを謳っている • WebAssemblyまつわる周辺ツール: wasm-bindgen 8
  8. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. wasm-bindgen

    • wasm-bindgen – 要するにRust↔JSをやってくれるクレート(ライブラリ) – Mozilla肝いり • web_sys – browser APIとのつなぎ込み(DOM含む) • js_sys – JSとのつなぎ込み 9
  9. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 中身(wasm-bindgen)

    10 #[wasm_bindgen] #[derive(Debug, Clone, Copy, Serialize)] pub struct Brick { x: f64, y: f64, status: BrickStatus, life: u32 } #[wasm_bindgen] impl Brick { pub fn new(x: f64, y: f64, status: BrickStatus) -> Brick { Brick { x: x, y: y, status: status, life: 1 } } } • wasm_bindgen attributeが付いている部 分がJS側にエクスポートされる • メソッドも同様にエクスポートできる import { Brick } from "mdn-breaking-blocks-wasm"; const brick = Brick.new(1, 1, 0); (Rust側) (JavaScript側)
  10. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 中身(web_sys)

    11 Web APIのインターフェース定義である WebIDLままのI/Fが用意されている // windowがそもそも存在しない場合は unwrapでpanic let _ = web_sys::window().unwrap() .alert_with_message("YOU WIN, CONGRATULATIONS!"); let _ = web_sys::window().unwrap().location().reload(); // dyn_intoでキャスト→キャスト失敗したら map_errでエラー処理 let canvas: web_sys::HtmlCanvasElement = canvas .dyn_into::<web_sys::HtmlCanvasElement>() .map_err(|_| console::log_1(&JsValue::from_str("CanvasElement is invalid"))) .unwrap(); let context = canvas.get_context("2d") .unwrap().unwrap() .dyn_into::<web_sys::CanvasRenderingContext2d>() .unwrap();
  11. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. 中身(js_sys)

    12 JavaScript APIのRustラッパーになる→世界が違うのでうまいこと動くようにされている // JavaScript側からコールバックを引数として受け取る pub fn draw_with_callback(&mut self, callback: &js_sys::Function) { for c in 0..self.bricks.len() { for r in 0..self.bricks[c].len() { if self.bricks[c][r].get_status() == BrickStatus::Live { let brick_x = c as f64 * (BRICK_WIDTH + BRICK_PADDING) + BRICK_OFFSET_LEFT; let brick_y = r as f64 * (BRICK_HEIGHT + BRICK_PADDING) + BRICK_OFFSET_TOP; self.bricks[c][r].set_x(brick_x); self.bricks[c][r].set_y(brick_y); let this = JsValue::NULL; // JavaScriptと違ってRustではコンパイル時に引数の数と型がわかっている必要がある // したがってJSの関数をそのまま呼べない (最悪applyを使う) let _ = callback.call2(&this, &JsValue::from(brick_x), &JsValue::from(brick_y)); } } } }
  12. 虎の穴 虎の穴 虎の穴 虎の穴 Copyright © 2019 Toranoana Inc. All Rights Reserved. まとめ

    13 • wasm-bindgenを使うことで本来は難しいWebAssemblyとJavaScriptの相互 運用を行うことができます • Rustは難しいと言われていますが、基本知識+コンパイラに従うことで書ける ようになるきがします • 今日の内容に近い内容はブログにも上げているのでぜひお読みください (http://toranoana-lab.hatenablog.com/entry/2019/08/14/190159 )