2014年4月13日日曜日

C++: em++-1.12 でSDL1もGLUTも使わずにC++ソースだけ書いてJavaScript側からキーボードイベントを取得して扱う方法

Emscripten-1.12ではSDL1かGLUTの互換レイヤーがあるので、そちらを使ってJavaScript側からキーボードイベントを回収する事はできます。できますが、SDL1もGLUTも使いたく無いし、.jsも書きたく無い場合にem++にコンパイルさせるC++ソースファイルだけでJavaScript側からキーボードイベントを取得して扱う方法があります。

code:


build:
em++ --bind -o emscripten_keydown_sample.out.html -std=c++11 emscripten_keydown_sample.cxx
C++向けにEmscriptenはembindという仕組みを用意しています。


また、EmscriptenはEM_ASMというEmscriptenにとってのマシン語であるJavaScriptをC++ソースファイル中に直接埋め込むインラインアセンブラー風の使い方のできる機能があります。

コードでは、
  1. global
    1. #include <iostream> ... std::cerr したいだけ
    2. #include <queue> ... キーコードを保持するバッファー用
    3. #include <emscripten/emscripten.h> ... EM_ASM
    4. #include <emscripten/bind.h> ... embind 
  2. namespace { }
    1. キーボードイベント発生時にキーコードを保持するバッファーを定義。
    2. キーボードイベントを受け取るC++関数 cxx_keydown を定義。
    3. embind の機能 emscripten::function によりC++関数 cxx_keydown を cxx_keydown という名前でJavaScriptから利用可能に定義。
  3. auto main() -> int { }
    1. EM_ASMによりJavaScriptで window.addEventListener を実行させ、"keydown" イベントに対して Module.cxx_keydown を呼び出すようセット。
    2. while(true)するとJavaScriptさん死んでしまうので emscripten_set_main_loop によりメインループを生成。
      1. keydown_buffer に値(keydownから受け取ったキーコード群)があればループのステップ事にそれを std::cerr で出力しつつバッファーを空にする。
こんな動作です。



embindではクラスも束縛できるので実際にはもっとオブジェクト指向なコードにもできます。今回はEM_ASMとembindの基礎的な使い方のサンプルに留めました。

0 件のコメント:

コメントを投稿