初めてexternを書いてみて、色々覚えることがあったのと、日本語のドキュメントがあまりなさそうなので忘備録的に書き留めようかと思います。
ちなみに使用したHaxeのバージョンは3.0です。
とりあえず、SDKに付属していたコード例で一番楽そうな
var controller = new Leap.Controller();
// for the frame event
controller.on('frame', function() {
console.log("hello frame")
})
// for the animationFrame event. this is only supported from within the browser
controller.on('animationFrame', function() {
console.log("hello frame")
})
controller.connect()
このコードをHaxeで書いてコンパイル出来るようにすることを目指します。
ディレクトリ構造
.
├── main.html
└── static
├── haxe
│ ├── Main.hx
│ ├── build.hxml
│ └── leap
│ └── Controller.hx
└── js
└── leap.js
とりあえずbuild.hxmlの定義をしてしまいましょう。
-cp leap
-js ../js/main.js
-main Main
-debug
-cpはファイルを検索したいディレクトリのことです。
Controllerの型定義の前に、先にMain.hxの定義をすませてしまいます。
package ;
import leap.Controller;
class Main {
static function main() {
var controller = new Controller();
controller.on('frame', function() {
trace("hello frame");
});
controller.on('animationFrame', function() {
trace("hello frame");
});
controller.connect();
}
}
こうですね。このくらいですとコードの見た目はJavaScriptのものとほとんど違いはありませんね。
では、これからこれをコンパイルが通るようにしましょう。
が、ここで問題が発生します。
Haxeからjsの外部ライブラリを呼び出す場合、その定義ファイルは元のjsと同じモジュール階層を持つ必要があります。
この場合、ControllerはLeap以下に配置されているので、Haxeでも同様にしなければなりませんが、Haxeではモジュール名の先頭を大文字にすることは許されていません。どうすれば良いでしょう?
コンパイル時用のメタデータを使う
公式ドキュメントの 外部ライブラリの利用法 によると、パッケージの構造を外部ライブラリの構造に対応させるのに、メタデータを使うこともできます。
とあります。
Tips and Tricks の@:native
の部分によれば、こいつの引数に好きな文字列を与えれば This makes it more easy to bind "extern" classes that might have a different name. という雰囲気らしいので、こいつを使えば、いい感じにHaxeのルールを守りつつコンパイル後はLeapという名前のパッケージに所属させることが出来そうです。
やってみましょう。
package leap;
@:native("Leap.Controller")
extern class Controller {
public function new(opts : Map<String, Dynamic>={});
public function on(event_type : String, func : Void -> Void): Void;
public function connect(): Void;
}
とりあえず、今必要になりそうなメソッドだけ定義しておきます。
@:native("Leap.Controller")
の部分で、展開後のモジュール名を定義しています。
ちなみに、3.0以前のHashはJavaScriptの連想配列と互換性がなかったようですが、新しく出来たMap<T, U>
はちゃんとクロスプラットフォームで動作してくれるそうです。ウレシイ!
コンパイルしてみましょう。出来ましたね(多分)。
あとはhtmlファイルに
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>LeapHx test</title>
<script src="./static/js/leap.js"></script>
<script src="./static/js/main.js"></script>
</head>
<body>
<h1>haxe</h1>
</body>
</html>
みたいに書いて、jsのコンソールを開けば凄い勢いでhello frameの文字がカウントされていくかと思います。
あとは必要に応じてexternを増やしていったりとか、gestureのenum定義したりとかしていって快適にコーディングしたいなぁとか、そういう感じですね。