ProgressionのCommandクラスを使いこなしたいよ(その2)
前回はProgressionのCommandクラスはこんな感じですよ、ということをナンチャッテな人間なりに書いてみましたが、今回は説明はそこそこにして、僕自身イマイチ確信がもてず、おっかなびっくり書いている部分についてお話いたします。
以下は昨日のコードの一部です。
new IfElse(
function():Boolean {
return Boolean(!postID); // URL末尾に投稿記事IDがないかチェック
},
new Func(this, playIntro), // イントロ有
new Trace("イントロを省略") // イントロ無
)
前回の説明と若干重複してしまいますが、ここではディープリンクURLからのswf再生に対し、イントロムービーを表示させないための処理をしています。「ディープリンクURLからのswf再生」と言うのは分かりづらい表現かもしれませんね。具体的に言うと、ブラウザのアドレスバーに直接
[http://www.studio-hedgehog.com/kazekotoba/#/index/post4]
のような個別記事固有のURLを入力し、swfが再生された場合を意図しています。
詳細は割愛しますが、postIDはuint型指定されたプロパティで、ディープリンクURLからのswf再生の場合には1以上の個別記事番号が格納され、それ以外のURLからの再生の場合はデフォルト値である0が格納されています。
IfElseは、条件に応じてコマンドを振り分けてくれるコマンドクラスで、コンストラクタには以下のようなパラメータを指定します。
new IfElse( condition:Function = null, // 論理値を返す条件関数
success:Command = null, // 条件関数の戻り値がtrueの場合に実行させるコマンド
failure:Command = null, // 条件関すの戻り値がtrueの場合に実行させるコマンド
delay:int = 0 // 処理開始までの遅延時間(ミリ秒で指定)
);
今回の僕の例では、successパラメータに任意の関数を実行してくれるFuncというコマンドクラスを、そしてfailureにはflashのtraceメソッドを実行してくれるTraceというコマンドクラスを指定しています。
条件関数はpostIDの値が0の場合は、Funcコマンドで指定したplayIntroというカスタムメソッドを実行し、それ以外の場合はプレビュー時に「イントロを省略」という文字がtraceメソッドにより出力パネルに表示されるようになっています。
さて、ここからが僕のアヤフヤな実装部です。playIntroメソッドをご覧ください。
private function playIntro():void {
addCommand(
new AddChild(progression.container, introPage),
new RemoveChild(progression.container, introPage, false, 3000)
);
}
「あれっ?」って思いませんか?条件関数がtrueの場合に実行するコマンドが1つだけ、つまり今回の例では例えばnew AddChild(progression.container, introPage)だけならば、IfElseコマンドのsuccessに直接このコマンドを指定してやればokなのですが、今回はnew AddChildコマンドでintroPageというオブジェクトを表示し、さらにその3秒後にこのオブジェクトをRemoveChildコマンドで表示リストから削除する、という2つのコマンドを登録したかったわけですね。
ところが、successパラメータには1つのCommandクラスを指定するようになっている。そんなわけで、半ば思いつきでこんなふうにplayIntroメソッド内でさらにaddCommandを実行し、複数のCommandクラスを登録したわけです。
他のやり方がないかと、フガフガ挑戦してみたんですけど、結局この方法しか思い浮かばず、最終的には「とりあえず動いてるからオケイ」ってことにしてしまいました。
さて次回は、外部データの読み込み等に発生するいわゆる非同期処理を、どのようにCommandクラスで行えばいいのかということについて書こうと思います。これについては、すでに前回のエントリーにniumさんから、貴重な情報をいただいたので、これからまた試してみますよと。
【追記!】
エントリーして、吉牛食べて帰ってきたら、早速niumさんがもっとクールな方法をコメントで教えてくれてました。ドキュメント不足のせいじゃないです。僕の脳細胞の不足のせいです!解説するつもりが、尻拭いまでしていただいてゴメンナサイ!
rssリーダーの方に、僕のお間抜けぶりが影響しないように、教えていただいたコードを転載いたします。
new IfElse(
function():Boolean {
return Boolean(!postID); // URL末尾に投稿記事IDがないかチェック
},
new SerialList( 0, // イントロ有
new AddChild(progression.container, introPage),
new RemoveChild(progression.container, introPage, false, 3000)
),
new Trace("イントロを省略") // イントロ無
)
SerialList というCommandListクラスを使い、Commandを追加してやればokと。
CommandListクラスはCommandクラスのサブクラスで、これを継承したのが今回使用したSerialList。それにもうひとつParallelListというクラスもあるんですね。
SerialListが指定された複数のコマンドを 1 つづつ順番に実行させるのに対し、ParallelList クラスは指定された複数のコマンドを全て同時に実行させる、ということですねー。
はー、オイラ頭悪すぎてマジ泣きそう…。

IfElse コマンドの条件で複数のコマンドを追加する方法ですが、連続的にコマンドを実行する仕組みとして SerialList コマンドと ParallelList コマンドが用意されています。
それぞれ前者は登録されたコマンドを順番に、後者は同時に実行して全て終わってから次のコマンドを実行するコマンドですので、以下のように記述すれば、今回の処理が実現できると思います。
new IfElse(
function():Boolean {
return Boolean(!postID); // URL末尾に投稿記事IDがないかチェック
},
new SerialList( 0, // イントロ有
new AddChild(progression.container, introPage),
new RemoveChild(progression.container, introPage, false, 3000)
),
new Trace("イントロを省略") // イントロ無
)
この辺もできるだけ早めにドキュメント化できるようにがんばりますので、よろしくお願いします!
おー、なるほどぉ!
案の定、イケテないやり方でしたが、
おかげさまでスッキリしました。
早速blogにも補足として入れさせて頂きます。
チュートリアルのほうにもリンクしていただいて恐縮です。
これからProgressionを始められるユーザの方を
却って混乱させてしまうような記事にならないように、
頑張ります。
ありがとうございます。