Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
伺か on Browser
Search
Narazaka
October 05, 2016
Programming
0
1.2k
伺か on Browser
デスクトップマスコットをブラウザ移植してみた
利用者視点のEmscriptenとその周辺
Narazaka
October 05, 2016
Tweet
Share
More Decks by Narazaka
See All by Narazaka
UEFIでうごくゲームを作ってみた〜2017年夏休みの自由研究〜
narazaka
0
7.1k
真のrequire()をブラウザで
narazaka
0
1.3k
Excelは殺す絶対にだ
narazaka
0
750
VBAナメてた
narazaka
2
1.9k
Other Decks in Programming
See All in Programming
CSC509 Lecture 12
javiergs
PRO
0
160
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.3k
距離関数を極める! / SESSIONS 2024
gam0022
0
280
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
1
100
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
110
レガシーシステムにどう立ち向かうか 複雑さと理想と現実/vs-legacy
suzukihoge
14
2.2k
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
Amazon Qを使ってIaCを触ろう!
maruto
0
400
ふかぼれ!CSSセレクターモジュール / Fukabore! CSS Selectors Module
petamoriken
0
150
「今のプロジェクトいろいろ大変なんですよ、app/services とかもあって……」/After Kaigi on Rails 2024 LT Night
junk0612
5
2.1k
Macとオーディオ再生 2024/11/02
yusukeito
0
370
みんなでプロポーザルを書いてみた
yuriko1211
0
260
Featured
See All Featured
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
31
2.7k
How to train your dragon (web standard)
notwaldorf
88
5.7k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.2k
Facilitating Awesome Meetings
lara
50
6.1k
GitHub's CSS Performance
jonrohan
1030
460k
Designing the Hi-DPI Web
ddemaree
280
34k
Making Projects Easy
brettharned
115
5.9k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
65k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
4
370
Transcript
うかがか 伺か on Browser デスクトップマスコットをブラウザ移植してみた 利用者視点の Emscripten とその周辺
自己紹介 佐藤隆人 ( な ら ざ か 奈良阪 ) Twitter:
@narazaka Github: @Narazaka npm: @narazaka CPAN: NARAZAKA ドリコム 2015 新卒 (2 年目 ) サー バー サイド Ruby 書いてます Perl / JavaScript / Ruby / C# あたりが好き その他 : 伺か / 漫画読み描き / OP アニメ愛好家 / 鉄
※ 注意 1 から 10 まで趣味の話です プロダクションレベルの知見ではありません。 試行錯誤の途中なのでアドバイスなどいただけると幸いです。
近年やってる趣味
うかがか 伺か 2000 年頃に一部で流行ったデスクトップマスコット
デスクトップマスコットのなかま? たち ポストペット ペルソナウェア デスクトップのメイドさん いもうとデスクトップ まいんど・ ふぉ~ かす お座りマルチ
かわいい
かわいい
懐かしい
懐かしい
なんかすごい
キャラクター 表現プラットフォー ム 16 年目の現在もたくさんのキャラの更新がある
しかし…… 世はスマホ全盛
「 キャラクター の居場所 デスクトップ」 の消滅
…… スマホでも使いたい ブラウザにのせて動かせないか?
「 伺か on Browser イカガカ」 プロジェクト コー ド https://github.com/Ikagaka デモ
http://ikagaka.github.io/Ikagaka.demo/
ブラウザに載せるにあたって…… うかがか 伺か はどういうプログラム?
うかがか 伺か (materia.exe) キャラクター デー タを差し替えられる デスクトップマスコットランタイム → クロー ズドソー
スなので JavaScript で新規開発 キャラクター の人格は任意の Windows 用アンマネー ジド DLL をそ のまま動作させる仕様 ( めっちゃ自由 ) extern "C" ̲̲declspec(dllexport) BOOL ̲̲cdecl load(HGLOBAL h, long len); extern "C" ̲̲declspec(dllexport) BOOL ̲̲cdecl unload(); extern "C" ̲̲declspec(dllexport) HGLOBAL ̲̲cdecl request(HGLOBAL h, long *len); →OSS の C++ 製人格 ( 台本 ) 記述用言語 DLL(.so) がいくつか存在
各人格記述用言語 DLL (with Hello, World!) shiori.dll ( 華和梨 8) /
shiori.dll ( 華和梨 7) System.Callback.OnGET: Hello, World! satori.dll ( 里々) * Hello, World! yaya.dll (YAYA) / aya5.dll ( 文 5) request { "Hello World!" }
_ 人人人人人人人_ > Emscripten <  ̄Y^Y^Y^Y^Y^Y  ̄
Linux で依存なくコンパイルできる C++ だった ( 一部 boost はずした ) 既存のコー
ドほぼ変更なし
Makefile もフラグ追加と g++ ‑> em++ rem emsdk1.25.0 on Windows emcmdprompt.bat
D: cd kawari make
各人格記述用言語 DLL 割とすんなり変換できた shiori.dll ( 華和梨 8) ‑> kawari.js shiori.dll
( 華和梨 7) ‑> kawari7.js satori.dll ( 里々) ‑> libsatori.js yaya.dll (YAYA) ‑> yaya.js aya5.dll ( 文 5) ‑> aya5.js
_ 人人人人人人人_ > Emscripten <  ̄Y^Y^Y^Y^Y^Y  ̄ ‑ 完 ‑
! ここからが問題 ! ~Emscripten とその周辺~
今回の最重要要件 = 互換動作 キャラデー タの変更なしに デスクトップと同じ挙動を保証したい キャラデー タは創作畑の人たちが作っていて、 形式変換などが望めるものではない
1. 落ちるキャラデー タがある メモリ関係のエラー で落ちる 任意のキャラデー タを突っ込んで動作させたい……。
1. 落ちるキャラデー タがある ( 解決 ) em++ のデフォルトでは最大メモリサイズが固定値だった。 メモリが足りなくなったら自動的に拡張してくれる ‐s
ALLOW_MEMORY_GROWTH=1 をつけてコンパイル。 ( 実行速度遅くなるよという警告が出る )
2. 複数キャラをたちあげたい 同じ人格 DLL.js を色々 なキャラデー タに適用したい。 しかし→Emscripten はスクリプトをロー ドした時点で、
グロー バ ルの Module とかに色々 入れてそのまま単一インスタンスとして実 行してしまう。
2. 複数キャラをたちあげたい ( 解決 ) 関数で囲って new する ‐‐pre‐js em‐pre.js
‐‐post‐js em‐post.js ( どう見ても正攻法ではない気がする…… → 現在は Worker に隔離 ) var Kawari = function(){ // em‐pre.js (****Emscriptenでコンパイルされたコード...****) this['Module'] = Module; this['FS'] = FS; this['PATH'] = PATH; this['ERRNO_CODES'] = ERRNO_CODES; this['NODEFS'] = NODEFS; this['IDBFS'] = IDBFS; this['WORKERFS'] = WORKERFS; }; // em‐post.js var kawari = new Kawari(); console.log(kawari.ERRNO_CODES);
3. ファイルシステムの取り扱い ユー ザー が投げる任意のキャラデー タ ( ファイルサイズ無制 限の ZIP)
を展開して FS に配置し、 中に入っているスクリプト を動かしたい。 DLL が FS に書き込むセー ブファイル等を保持したい。 追加の前提 ブラウザではロー カルのファイルシステムは読めない。 Worker で IndexedDB にアクセスできないブラウザ (IE) がある。
3. ファイルシステムの取り扱い ( 解決 ) npm install browserfs 1. ZIP
を展開し (FS API をエミュレー トする )BrowserFS で IndexedDB に保存して保持 2. (IndexedDB は非同期 API しかないので同期 API を使う )Emscripten FS にメモリロー ドしてから DLL 実行 3. 実行終了後に FS の中身を IndexedDB に書き戻す 数 MB の ZIP 複数扱う時点で IndexedDB 以外容量足りません Emscripten 付属の IndexedDB の扱いも大して変わらない めちゃくちゃ泥臭いので何かいい方法ないでしょうかね……
3. ファイルシステムの取り扱い ( 願い ) Worker で使える IndexedDB の同期版 API
復活しないかなあ mount みたいに FS の一部だけロー ドできないかなあ IE がサポー ト切れますように ( ♪ )
4. Shift̲JIS 文字列を渡す 人格用言語 DLL が 2000 年代初頭製なので SJIS 前提
ユー ザー から投げられるキャラデー タのソー スも SJIS 。 互換性のため文字コー ド変換かましたコンパイルはしたくない。 Emscripten デフォルトの Pointer̲stringify や intArrayFromString は Unicode 前提なのか正しく動かなかった。
4. Shift̲JIS 文字列を渡す ( 解決 ) npm install encoding‐japanese var
_request = Module.cwrap( // DLLのrequest()関数 'request', 'number', ['number', 'number']); var requestStr = "こんにちは"; // intArrayFromStringではダメだった var unicodeReq = Encoding.stringToCode(requestStr); var sjisReq = Encoding.convert(unicodeReq, 'SJIS', 'UNICODE'); var req = allocString(sjisReq); // 文字列メモリ確保 var len = allocLong(req.size); // 文字列長メモリ確保 var resPtr = _request(req.ptr, len.ptr); // request()! var resHeap = new Uint8Array( // 応答文字列のヒープの参照 Module.HEAPU8.buffer, resPtr, len.heap[0]); // intArrayToStringはOK var sjisResStr = Module.intArrayToString(resHeap); Module._free(len.ptr); Module._free(resPtr); // freeする var sjisRes = Encoding.stringToCode(sjisResStr); var unicodeRes = Encoding.convert(sjisRes, 'UNICODE', 'SJIS'); var response = Encoding.codeToString(unicodeRes);
4. Shift̲JIS 文字列を渡す ( 解決 ) 詳しくは https://github.com/Narazaka/nativeshiori ↓ 実際のコー
ド
5. 人格用言語 DLL から別の DLL を呼ぶ 機能の少ない人格用言語 DLL から別の DLL
を呼んで機能を補 完する SAORI というインター フェー ス規格が流通している extern "C" ̲̲declspec(dllexport) HGLOBAL ̲̲cdecl request(HGLOBAL h, long *len); extern "C" ̲̲declspec(dllexport) BOOL ̲̲cdecl load(HGLOBAL h, long len); extern "C" ̲̲declspec(dllexport) BOOL ̲̲cdecl unload(); 任意の DLL(.so) 呼びたい
5. 人格用言語 DLL から別の DLL を呼ぶ ( 未解決 ) https://github.com/kripken/emscripten/wiki/Linking
2015 年から対応された模様? ( イカガカ初期開発時の 2014 年当時はうやむやだった) 素人が「 ホー ムペー ジ」 に気軽における程度に簡単な対応にした いが、 まだよく調べていません。
( 要件によっては ) コンパイル後の対処が大変 今回の要件 = デスクトップアプリとの互換動作 1. 全部 C++
ではなく、JavaScript で書かれたメインルー チンに任 意個数のコンポー ネント DLL を連携させて動作させる。 2. 任意のスクリプトを言語ランタイムに食わせてデスクトップ と互換の動作・ ファイル操作をする。 3. 入出力は SJIS 。 4. DLL から別の任意 DLL を呼ぶ ( 未解決 ) 。 めぼしい知見がなかったので全部無理矢理解決
知見はまだまだ足りない エミュレー ター で動かしているようなものなので C++ や JavaScript 単体と異なった事情が出てくる。 「 全部
C++ で書いてそのまま実行する」 以外のシナリオ例が あまりない。
まとめ ブラウザでデスクトップマスコット「 伺か」 を動かしてみた DLL があったので Emscripten で JS にした
要求仕様に沿って DLL を扱うにあたって、 複数起動、 ファイル システム、 文字コー ド、 動的リンクの問題があった この様な ( ニッチな ) 需要にみあう知見は ( 当然 ) 充実していない
[PR] イカガカ開発チー ムドリコムはエンジニアを 募集しています!