2009-09-29 ブログ移転みたいなご報告

基本的にこちらの記事はそのままの予定です。
移転先に記事を移す予定はないですが、まとめ直す事はあるかもしれません。
- flash系の記事は、http://fla.la
- その他技術系の記事やらメモは、http://koshikawa.net/tp
どうぞ、よろしくお願います。
2009-07-30
■[spark] Spark勉強会#11
Spark勉強会#11のメモ。今回は19:00に会社出たので19:30ぐらいから参加しました。
機材トラブルで色々大変そうでしたが、お疲れ様でした!
ZIPライブラリ(http://nochump.com/blog/?p=15)の拡張した話など
発表者はhidehitoさん。
nochump.util.zipのZipEntry, ZipFile, ZipOutputを駆使してzipの圧縮・解凍を行うお話。
THiNQにおいて、以下のような機能を追加した。
近々Sparkにコミット予定。
複数Zipから新たなZipを作成するデモを見る限り、あっさり作成出来ていて良さげ。
ビュアーにFLARToolKitを使ったお絵かきコンテンツの話など
発表者はnoenoeさん。
放送大学の近藤智嗣先生の複合現実感による推定支援型展示手法の実用化という研究のお手伝い。
- Papervision3DとColladaファイルのアニメーション制御の相性が良い感じ
- FLARToolKitを使っているので近々Sparkにコミット予定。
お絵かきコンテンツはUIのほうが気になった。Papervision3DとFLARToolKitはそろそろ触ってみたいなぁ。
Gaia Framework
発表者はSteven Sacksさん。
Gaia Frameworkの解説。Ruby on Railsにインスパイアされたらしいよ。
盛りだくさんなのでまずはWebサイトをちゃんと読んでみよう。
Progression 4 Fast Preview
発表者はtaka:niumさん。
- ver.4は基本今までどおり使える
- シーン構造を外部化出来る。
- 単独でも、組み込んでも何も変えずに動作する。
- 作成するアプリケーションの目的別にConfigurationを適用することで機能を最適化できる。
- コンポーネントの新機能
今後の予定は
2009-07-03
■[FLASH][Actionscript3] Advanced ActionScript3.0 with Design Patternsの邦訳版を読んだメモ
ついに邦訳版が出ましたので、購入。

薄い本なのでサラッと読めそうな気がします。読みながらのメモです。良く分からなかったので調べたこととかも書いておきます。
一部、訳が若干残念な感じなので英語版と一緒に読むことで理解が深まります。商売上手ですね。
- ActionScript 3.0 : デザインパターン (ADOBE TECH LAB)
- http://www.amazon.co.jp/dp/4798118362
- Advanced ActionScript3.0 with Design Patterns
- http://www.amazon.co.jp/dp/0321426568
Chapter3 MVCパターン
モデル
ビュー
コントローラ
図にするとこんな感じ

ClockDataの例(053)
モデルでは、元データへの直接参照を避けるためにcloneメソッドを通してデータを受け取る直接オブジェクト参照をすると、モデル外での操作がデータモデルに影響してしまう。
public function clone():Hoge { return new Hoge(); // 現在の状態の複製が必要な際はnewだけじゃだめだと思う }
Eventのハンドラを直接呼び出したい場合、ハンドラの引数の初期値をnullにしておく
public function Hoge() { addEventListener(Event.CHANGE, changeHandler); changeHandler(); // 初回分を実行 } private function changeHandler(event:Event=null):void { }
コントローラの追加の例(068)
自動で更新される時計の処理
ユーザが入力した時刻に更新される時計の処理
- ユーザの入力でモデルを更新する
- ビューがそのイベントをリッスンしているのでビューが更新される
- コントローラがそのイベントをリッスンしているので、コントローラに定義されているUIが更新される(但し、ユーザの入力で既に変わっているの効果はない)
この例では、コントローラにUIのビューが混じっているので混乱しやすいかも知れません。私はもちろん混乱しました。
Chapter4 シングルトンパターン
075の以下の文章の意味が分かりません。
ActionScript3.0のひとつの特徴は、メソッドのすべての引数は、デフォルト設定が不要であるというものがあります。
原文は
One feature of ActionScript 3.0 is that all parameters of a method are now required unless a default value is provided.
私の怪しい英語力で訳すと
ActionScript3.0では、メソッドの引数にデフォルト値がない場合、その引数は必須となる。
といった感じですかね。それだと前後の文章が理解できます。
Settingsクラスの構築の例(081)
flash.utils.Proxyクラスの使いどころを、これで知りました。未定義のプロパティやメソッドを捕捉するために使うわけですね。
コンポジション経由でEventDispatcherを追加(082)
他のクラスをすでに継承しているけど、あのクラス(EventDispatcher)の機能も欲しい!という場合の解決策です。
public class Hoge extends Fugo implements IEventDispatcher { private var _dispatcher:EventDispatcher; public function Hoge() { _dispatcher = new EventDispatcher(); } public function addEventListener(type:String, handler:Function, useCapture:Boolean, priority:int = 0, weakRef:Boolean = false):void { _dispatcher.addEventListener(type, handler, useCapture, priority, weakRef); } // ... IEventDispatcherに必要なメソッドを実装 }
Chapter5 テンプレートメソッドパターンとファクトリーメソッドパターン
ActionScript3.0はasbstractがないので、抽象メソッド内で例外を発生させる方法がありますと書いてありますが例がないので、例はこんな感じ。
package { public class AbstractClass { /** * constructor */ public function AbstractClass() { if (Object(this).constructor == AbstractClass) throw(new Error("you can't create instance of AbstractClass.")); } } }
本書で指摘されているように、これだと実行時にエラーを発生させるだけなんですよね。なので、命名規則をちゃんとして間違えてnewしちゃったらコンパイル時に気づいてね、みたいな感じで。
Chapter6 プロキシパターン
イメージローダの件が例として挙げられていますが、イメージの幅や高さはEvent.INITイベントが発生するまで取得出来ないので注意が必要です。(当たり前?)
flash.events.DataEventって何?
DataEvent オブジェクトは、生データのロードが完了したときにオブジェクトによって送出されます。 次の 2 種類のデータイベントがあります。
とのこと。このデザパタ本の中では下記のように使っています。
dispatchEvent(new DateEvent(Event.COMPLETE, false, false, <<渡したいデータ>>);
これでhandler側から「渡したいデータ」にアクセス出来ます。私は普段、dispatchEventを送出する側にプロパティを持たせて、handler側からはevent.target.propertyNameを参照するようなやり方が多いです。でもこうやってデータ渡せるのは便利ですね。しかも組み込みイベント。どっかで使ってみたいと思います。
flash.utils.Proxy
AS1, 2に存在したObjectクラスの_resolveメソッドは未定義オブジェクトの呼び出しを捕捉することが出来ました。
この機能はAS3から、flash.utils.Proxyに組み込まれました。flash.utils.Proxyクラスを継承することで未定義オブジェクトの呼び出しを捕捉します。
AS3では多重継承が出来ないため、Proxyクラスを継承したクラスで他のクラスも継承したい場合には、コンポジションによって機能を追加します。先の「コンポジション経由でEventDispatcherを追加」はこれです。
アダプタパターンとファサードパターン
アダプタパターンは、対象のAPIを変換すること。ファサードパターンは、呼び出しを単純化することです。めもめも。
Chapter7 イテレータパターン
コレクションとイテレータの役割分担が大事。いままでちゃんと分けていなかったので反省です。
Chapter8 コンポジットパターン
インターフェースの実装を書く際に、毎回冗長なコードを書く可能性がある場合は、基本クラスを実装する。そして差分を継承先のクラスで書いていくようにしましょう。
インターフェースを使い始めのころは、まじめに1つ1つのメソッドを実装していて気づくのですが、共通部分があったりするんですよね。だったら、まずは抽象クラスで実装してそっから継承しようという話です。
ところで、126の以下の文章の意味が分かりません。
リーフエレメントはコンポジットエレメントになることができますが、コンポジットエレメントはリーフエレメントになることはできません。
原文は
Leaf elements can be placed in composite elements, but composite elements cannot be placed in leaf elements.
私の怪しい英語力で訳すと
リーフエレメントはコンポジットエレメントの中に配置できます。逆にコンポジットエレメントはリーフエレメントの中に配置出来ません。
といった感じですかね。つまり逆の意味になってしまっていますので注意。
Chapter9 デコレータパターン
デコレートパターンは、「マトリョーシカ」に例えることが可能とはいえ、マトリョーシカって?
本チャプターで登場する「デコレート」は原書では「Decorated」と書かれています。つまり、デコレータがデコレーションする対象を指します。デコレータがデコーレトをなんやかんやという記述が繰り返されていると何が何やら分からなくなりそうです。上記のwikipediaにある図のComponentが本書の「デコレートオブジェクト」に当たります。
Chapter10 コマンドパターン
CommandStackのputCommandでなぜspliceするのか疑問でしたが、nextメソッドとprevメソッドを見たら分かりました。prevとnextで_indexが変わるので、prevしている最中にputCommandした場合には、それ以降に存在していた履歴を全部消す必要がありますね。
図にすると、こんな感じ。

本章後半にプロキシミティゲームの構築という節があるのですが、何故か理解できなくて何だろうと思っていたら、肝心なGameboardDataクラスの説明がすっぽり抜け落ちているではありませんか。各所に突然、GameboardDataクラスが登場していますが、定義が載っていません。
Chapter11 メメントパターン
Chapter12 ステートパターン
Chapter13 イベント処理
イベント処理に関しては詳説 ActionScript 3.0を読んでおけば良い感じです。特筆することはありませんでした。
252の以下の表現がちょっと気になりました。
stopPropagation()はcurrentTargetのリスナへのイベント通知は終了させますが、それ以上のディスプレイリスト探索を中止します。
これは原文
If you call stopPropagation(), the event is not allowed to continue up the display list , but the currentTarget is allowed to finish dispatching the event to its listeners.
を直訳した感じなのですが、イベント通知は終了の意味がちょっと分かりづらいですね。
stopPropagation()はcurrentTargetに登録されたリスナへのイベント通知は送出します。但し、それ以降のイベントフローに存在するDisplayObject Listのイベント送出を中止します。
という意味だと思います。
Chapter14 データの転送
Flash Remoting
NetConnectionを使う。call時の第二引数でRespoderインスタンスを指定することで、サービス側でreturnする値を受け取ることが可能。コールバック関数は
が呼ばれる。
var nc:NetConnection = new NetConnection(); nc.connect("<<gateway URL>>"); nc.call("<<service name>>.<<method name>>", new Responder(result, error); // result, errorはコールバック
Chapter15 E4X
E4Xに関しては詳説 ActionScript 3.0を読んでおけば良い感じです。特筆することはありませんでした。
意外なE4Xの使いどころといえば、CDATA SectionでJavaScript APIなんかもあります。
Chapter16 正規表現
コンストラクタでのバックスラッシュ(\)
コンストラクタでバックスラッシュ(\)を扱う場合、エスケープが必要となります。
var regexp1:RegExp = new RegExp("^\d+$"); // \dという文字列でマッチ var regexp2:RegExp = new RegExp("^\\d+$"); // \dは数値を表す文字クラスなので数値にマッチ var regexp3:RegExp = /^\d$/; // \dは数値を表す文字クラスなので数値にマッチ
感想
デザインパターンの知識が多少なりともあるほうが読みやすいと思います。デザインパターンの書籍として以下のような書籍を読んでから望むと良いかもしれません。
- 増補改訂版Java言語で学ぶデザインパターン入門
- http://www.amazon.co.jp/dp/4797327030
- Head Firstデザインパターン―頭とからだで覚えるデザインパターンの基本
- http://www.amazon.co.jp/dp/4873112494
- PHPによるデザインパターン入門
- http://www.amazon.co.jp/dp/4798015164
その他、AS3の知識ももちろん必要です。AS3の書籍は以下のものがおすすめです。
おまけ
おれおれ正誤表を書いておきます。公式のものではないので参考程度にとどめて下さい。
正誤表
| page | 誤 | 正 |
| 056 | まず、Clockという抽象ベースクラス | まず、AbstractClockViewという抽象ベースクラス |
| 057 | public function Clock | public function AbstractClockView |
| 066 | date.milliseconds = getTimer()._startTime; | date.milliseconds = getTimer() - _startTime; |
| 070 | view.y = 40.view.getBounds(view).top; | view.y = 40 - view.getBounds(view).top; |
| 075 | ActionScript3.0のひとつの特徴は、メソッドのすべての引数は、デフォルト設定が不要であるというものがあります。 | ActionScript3.0では、メソッドの引数にデフォルト値がない場合、その引数は必須となります。 |
| 098 | プロキシとしてLloaderを生成 | プロキシとしてLoaderを生成 |
| 126 | リーフエレメントはコンポジットエレメントになることができますが、コンポジットエレメントはリーフエレメントになることはできません。 | リーフエレメントはコンポジットエレメントの中に配置できます。逆にコンポジットエレメントはリーフエレメントの中に配置出来ません。 |
| 144 | public function ReaderDecorator | public function AbstractReaderDecorator |
| 145 | extends ReaderDecorator | extends AbstractReaderDecorator(本書ではこうあるべきですが、DL出来るサンプルファイルはすべてReaderDecoratorになってます。) |
| 210 | 11.1.5.mailクラス | 11.1.5 mainクラス |
| 252 | stopPropagation()はcurrentTargetのリスナへのイベント通知は終了させますが、それ以上のディスプレイリスト探索を中止します。 | stopPropagation()はcurrentTargetに登録されたリスナへのイベント通知は送出します。但し、それ以降のイベントフローに存在するDisplayObject Listのイベント送出を中止します。 |
| 309 | ^ その行の先頭(mフラグ設定時) | ^ mフラグ未設定時には文字列の先頭、mフラグ設定時にはその行の先頭 |
| 309 | $ その行の末尾(mフラグ設定時) | $ mフラグ未設定時には文字列の末尾、mフラグ設定時にはその行の末尾 |
その他
| page | 誤 |
| 062 | return value.toString();がインデントされていない |
| 115 | UIntCollectionコンストラクタの_index = 0;がインデントされていない |
| 120 | addElementメソッドブロックの終わりの}がインデントされていない |
| 191 | GameboardDataクラスが突然登場するが紙面にGameboardDataクラスが掲載されていない |
| 196 | private var _pieces:Spriteが定義されていない |
2009-06-24
■[spark] Spark勉強会#10
初めてのSpark勉強会へ参加してきました。とりあえずメモ書き。
発表者の方々のお名前間違っていたらごめんなさい。その他にも間違いあれば、ご指摘お願いします。
Adobe最新情報
Adobe MAXの件
- 2009-10-04〜2009-10-07でAdobe MAX in ロサンゼルスやるよ。
- 日本からのツアーは2009-10-04〜2009-10-10。お酒を一ヶ月我慢すれば行ける金額だよ!(30万ぐらい?)
- スマートフォン向けのFlash Player 10もこのタイミングで発表予定。
FLASH xxxなアプリたち
Flash Catalystはあまりイメージがわかないのでbeta版使ってみるかなぁ。
よくわからん。Flexコンポーネントが色々変わったらしい。ロジックとビヘイビアの分離とか。
骨展とかAlchemyとか
Hisato Ogata さん
骨展のあれ
Alcemyの開発環境
ちゃんとメモれませんでした。。。
C/C++が出来ると
いろいろ生かせるから、勉強すると良いよ。
RTMP
ありかわ(arkw)さん
- 先日の仕様公開の件
Sparkの近況
yossyさん
Air Dao
Seacolorさん
Adobe AirのOR/Mapper
Union Platform
kenoさん
Colin MoockとDerek Claytonが開発している
- MegaPhonで使った実績あり
- UnionServer(Java)とReactor(swc)を組み合わせて使う
- NetConnectionみたいなUConenctionを使ってアクセス
- APIがとても直感的
- testサーバはtryunion.com:9100使えばいいさ
Colin Moockコーナー
感想
2009-06-10
■[flash][javascript][opensocial][mixiアプリ] CDATA SectionでJavaScript APIを使う
先日、twitter上で
とか呟いておりましたら、muta244さんから素敵なライブラリを紹介して頂きました。
muta244さんのas3ライブラリ集にASからJavaScriptを簡単に操れるクラスが含まれています。とても便利なライブラリなのでみんな使うといいと思います。
と、紹介しつつ今回そのライブラリの使い方は書かないという。
CDATA Sectionでヒアドキュメントみたいな何か
さて、先のソースの下記部分を読んでいて、驚きました。as3のソース内にJavaScriptがふつうに書いてあるのです。
知らなかったのですが、as3ではE4Xが使えるのでCDATA Sectionを使えばヒアドキュメントみたいなことが出来るんですね。なんていうか以下みたいな感じです。
var hogeString:String = <![CDATA[ あのイーハトーヴォの すきとおった風、 夏でも底に冷たさをもつ青いそら、 うつくしい森で飾られたモリーオ市、 郊外のぎらぎらひかる草の波。 ]]; trace(hogeString);
これをtraceした結果は以下になります。
あのイーハトーヴォの すきとおった風、 夏でも底に冷たさをもつ青いそら、 うつくしい森で飾られたモリーオ市、 郊外のぎらぎらひかる草の波。
改行が1つ多くなってしまうのは、改行コードの問題と思われ、以下に示す改行コードの変換処理をソースに追加してみます。
var CR:String = String.fromCharCode(13); var LF:String = String.fromCharCode(10); hogeString = hogeString.replace(new RegExp(CR + LF, "gm"), LF);
これで改行コードをLFに変換出来ました。as3にはヒアドキュメントはないと思っていたのですが、CDATA Sectionを使っていわゆるヒアドキュメントような使い方が出来る事がわかりました。
CDATA SectionとExternalInterfaceでJavaScript
今まで、asとjsの連携というと、swfを読み込んだhtml上にjavascriptを書いておく(もちろん外部読み込みでも良い)ものだと思っていたで以下のような感じで実装してました。
htmlソース
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>demo</title> <script type="text/javascript" src="path_to/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="path_to/swfobject.js"></script> <script type="text/javascript"> swfobject.embedSWF( "demo.swf", "swf_container", "550", "400", "9.0.0", undefined, {}, // flashvars { quality : 'high', allowScriptAccess : 'always' }, // params { id : "externalswf", name : "externalswf" } // attributes ); function getExternalAPI() { $.ajax({ url: 'path_to_external_API', dataType: 'text', cache: false, success: function(data, status) { $('#externalswf').get(0).getExternalAPI_Result(data); }, error: function(xhr, status, e) { } }); } </script> </head> <body> <div id="swf_container">FLASH content</div> </body> </html>
demo.swfのDocumentClassに指定したASソース
package { import flash.display.Sprite; import flash.external.ExternalInterface; import flash.system.Security; public class Main extends Sprite { //---------------------------------------------------------------------- // method //---------------------------------------------------------------------- //------------------------------ // public method //------------------------------ /** * constructor */ public function Main() { // ExternalInterfaceの使用可否を確認 if (!ExternalInterface.available) throw Error("ExternalInterface is unavailable"); // swfを読み込んだhtmlが置いてあるドメインのjs -> asアクセスを許可する Security.allowDomain(ExternalInterface.call("function() { return location.hostname }")); // js からgetExternalAPI_Resultの名前でrenderExternalAPIResultメソッドを呼び出せるようにする ExternalInterface.addCallback("getExternalAPI_Result", renderExternalAPIResult); // jsのgetExternalAPIを実行 ExternalInterface.call("getExternalAPI"); } //------------------------------ // private method //------------------------------ /** * render external API result via javascript */ private function renderExternalAPIResult(data:*):void { // dataを使って何かする } } }
このようなソースを先ほどのCDATA Sectionを使って、htmlソースをちょっとすっきりさせてみました。
すっきりした(そうでもない?)htmlソース
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>demo</title> <script type="text/javascript" src="path_to/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="path_to/swfobject.js"></script> <script type="text/javascript"> swfobject.embedSWF( "demo.swf", "swf_container", "550", "400", "9.0.0", undefined, {}, // flashvars { quality : 'high', allowScriptAccess : 'always' }, // params { id : "externalswf", name : "externalswf" } // attributes ); </script> </head> <body> <div id="swf_container">FLASH content</div> </body> </html>
jsコードを内包したASソース
package { import flash.display.Sprite; import flash.external.ExternalInterface; import flash.system.Security; public class Main extends Sprite { //---------------------------------------------------------------------- // method //---------------------------------------------------------------------- //------------------------------ // public method //------------------------------ /** * constructor */ public function Main() { // ExternalInterfaceの使用可否を確認 if (!ExternalInterface.available) throw Error("ExternalInterface is unavailable"); // swfを読み込んだhtmlが置いてあるドメインのjs -> asアクセスを許可する Security.allowDomain(ExternalInterface.call("function() { return location.hostname }")); // js からgetExternalAPI_Resultの名前でrenderExternalAPIResultメソッドを呼び出せるようにする ExternalInterface.addCallback("getExternalAPI_Result", renderExternalAPIResult); // jsのgetExternalAPIを実行 executeJS(); } //------------------------------ // private method //------------------------------ /** * execute JavaScript via ExternalInterface * @param data */ private function executeJS():void { // 本当は改行とか空行を置換してから実行するほうが素敵 ExternalInterface.call(<![CDATA[ function getExternalAPI() { $.ajax({ url: 'path_to_external_API', dataType: 'text', cache: false, success: function(data, status) { $('#externalswf').get(0).getExternalAPI_Result(data); }, error: function(xhr, status, e) { } }); } ]]>); } /** * render external API result via javascript */ private function renderExternalAPIResult(data:*):void { // dataを使って何かする } } }
おおざっぱに書くとこんな感じです。as側だけいじればいいってのは楽でいいですね。
opensocialの話(たったの1行!)
as側にjsがかけるので同じように、opensocialのJavaScript APIを叩けばOKです。opensocial-jqueryであれば、外部APIを参照する処理とかはこのまま使えそうですね。
ExternalInterface.objectID
$('#externalswf').get(0).getExternalAPI_Result(data);
という箇所があって、「externalswf」がハードコードじゃん、うげ。という感じがします。
この辺は、ExternalInterface.objectIDを使えばすっきりです。ただし、このExternalInterface.objectIDをfirefoxで使う際にはswfobjectでidだけでなくnameにも同じ値を与えてあげることを忘れないようにしましょう。
swfobject.embedSWF( "demo.swf", "swf_container", "550", "400", "9.0.0", undefined, {}, // flashvars { quality : 'high', allowScriptAccess : 'always' }, // params { id : "externalswf", name : "externalswf" // ここね } // attributes );
そして、as側はこんな感じですかね。
private function executeJS():void { ExternalInterface.call(<![CDATA[ function getExternalAPI() { var objectId = "]]> + ExternalInterface.objectID + <![CDATA["; $.ajax({ url: 'path_to_external_API', dataType: 'text', cache: false, success: function(data, status) { $('#' + objectId).get(0).getExternalAPI_Result(data); }, error: function(xhr, status, e) { } }); } ]]>); }
