haXeでオリジナルコンポーネント作り WCAN mini Vol.10 2009.03.14 小笠原 啓@(有)ITプランニング
自己紹介 有限会社ITプランニング所属のプログラマー。 haXeとかObjective CamlとかActionScriptとかやってます。 GUIとかマルチスレッドとか言語とかに興味持ってます。 Page 2
仕事:リッチインターネットアプリケーション Page 3
話したいこと swfファイルを生成できるhaXeという言語の紹介。すばらしい言語だよ! コンポーネント(GUI部品)について。 Page 4
まずは簡単にhaXe(へっくす)の紹介 swf, javascript, neko, phpにコンパイルできるマルチプラットフォーム言語。 静的型付け(型推論)、高階関数、列挙型、型パラメータ、構造的部分型。 オープンソース。http://haxe.org/?lang=jp Page 5
こんにちは世界(みかけはAS3によく似ています) import flash.text.TextField; class Test { public static function main() { var msg = new TextField(); msg.txt = “こんにちは” + “世界!”; flash.Lib.current.addChild( msg ); } Page 6
haXeのすごいところ[1] 型付けされた高階関数と型推論。 高階関数 function reduce( f : T → T→T, init : T, ary : Array<T> ) : T { var result = init; for( elm in ary ) { result = f ( result, elm ); } return result; 型推論 Page 7
haXeのすごいところ[2] 列挙型 enum Card { Number ( n : Int ); 構造的部分型 enum Card { Number ( n : Int ); Jocker; } トランプは、数字を持つカードかジョーカーのどちらかという表現。 typedef Point = { x : int; y : int }; class Point3D = { var x : int; var y : int; var z: int; } function move( p : Point ) : Void { p.x++; p.y++; } move( new Point3D() ) 型チェックOK! Page 8
haXeのすごいところ[3] クライアント・サーバーの両方が記述できて、連携が取れる。 例えばサーバーサイドはneko, クライアントサイドはFlash。 haxe.remoting.HttpConnectionなどを使ってデータの授受。同じ言語でやり方 が同じなので、連携が容易。 Page 9
GUI部品について[1] イベントの上がり方を変えたい。 無理。 動きを変えたい。 ~をしたい。 用意されているものがあれば。 イベントとかプロパティとかメソッドとか多すぎ。 Page 10
GUI部品について[2] なぜそうなっているのか? 下手にクラスの中身をプログラマーに公開すると破壊するので、隠蔽工作を している。 Model-View-Controlというクラス間の相互依存関係をうまく回避する歴史的 な(?)テクニックを鵜呑みにして使っている。 Page 11
どうすれば柔軟なGUI部品が作れるのか? 1. ~というイベントが起きたときに、 2. ~という条件を調べて、 3. ~というフィードバックを表示して、 4. ~を実行する。 Page 12
インタラクションという名前でまとめてみた class UXInteraction<S> { var name : String; var events : Array<String>; var acts : Array<S → Void>; var judge : S → Bool; var work : S → UXInteractionParameter → Void; } インタラクションを発動させる(低レベル)イベント フィードバック イベントを挙げるかどうか? イベントが起きたときに実行する事 Page 13
インタラクションの使い方(作る) class SomeInteraction extends Interaction<State> { public function new( ?c : Controller<State> ) { super(c); name = "SomeInteraction"; events.push( MouseEvent.CLICK ); judge = function ( state : State ) { return state.enable; }; work = function ( state : State, param : Null<InteractionParameter> ) { state.enable = !state.enable; }; acts.push( function ( state : State ) { for( c in state.children ) { c.x ++ ; c.y ++;} } ); } Page 14
インタラクションの使い方(変更する) 1. クリックを無効にして、エンターキーにのみ反応するボタン。 button.getInteraction(“push”).clearEvents(); button.getInteraction(“push”).addEvent(“UXKeyboard.ENTER”); 2. リストボックスの出現の仕方を変更する。 button.getInteraction(“drop”).addAct( function( s ) { s.dropbox.alpha = 0.; Tweener.add(s.dropbox, { alpha = 1.; time = 1.; }); }): Page 15
デモンストレーション Page 16
UX-Frameworkとして公開中 Subversionリポジトリ: http://ux-framework.googlecode.com/svn/trunk Blog: http://ocaml-nagoya.g.hatena.ne.jp/uxtk/ Page 17
Web Site: www.itpl.co.jp Email: info@itpl.co.jp Page 18