Home > flash > Progression のコマンドクラスの Func コマンドではまった

Progression のコマンドクラスの Func コマンドではまった

  • Posted by: non
  • 2008年8月 3日 10:22
  • flash

Progression Framework 2.x.x 系での話。 3.x.x系がリリースされた今となっては役に立つ情報なのか微妙なのだけれど、そこは置いておいて今回は コマンドクラスの Func でつまったところについて書いてみる。

Func コマンドで画像をロードする

コマンドリストに Func コマンドを登録し、Func コマンドでの画像のロードを前提とした場合、以下のようなコードになる。第3引数の配列は、第2引数で指定した関数(loader.load)の引数で、このとき、loader.load の第1引数として画像のURLを指定したURLRequestオブジェクトを渡している。

var loader:Loader = new Loader();

addCommand(
    new Func( null, loader.load, [ new URLRequest( "image.jpg" ) ] )
);

ちなみに、EventDispatcher インスタンスと終了イベントを指定してやると、ロード終了後に他のコマンド(例えば DoTweener )を実行することもできる。リスナーを自前で発行する必要がないのでシンプルで使いやすい。

var loader:Loader = new Loader();
loader.alpha = 0;

addCommand(
    new Func( null, loader.load, [ new URLRequest( "image.jpg" ) ], 0, loader.contentLoaderInfo, Event.COMPLETE ),
    new DoTweener( loader, { alpha: 1.0, time: 2 } )
);

ここまでは大丈夫。

Func コマンドの引数として指定した値が参照されるタイミング

直接値を指定したり、コマンドリスト実行前に値を指定した場合は、問題なく値を受け取ってくれる。でも、以下のコードようにコマンドリスト実行中に値が変更された場合では、コマンドリスト実行前の値で Func コマンドが実行されてしまう。

コマンドリストに登録した Func コマンドの引数はコマンドリスト実行前に参照されているっぽい。

以下のコードでは URL を setURL 関数で指定しているけど、実際には XML をロード後に 抽出した画像の URL をセットするといった用途に使われるはず。そういうときにちょっと困る。

※ちなみに、以下のコードのままだと Func コマンド実行時には URL が未定義なので exception イベントが発生してしまい、コマンドリストは中断されどうしようもない状態になる。これに関してはタロタローグの太郎さんの記事に詳細が載っている。

package
{
    import flash.display.Loader;
    import flash.events.Event;
    import flash.net.URLRequest;
    import jp.progression.casts.CastSprite;
    import jp.progression.commands.*;
    import jp.progression.Progression;
    import caurina.transitions.Tweener;
    
    public class SampleCast extends CastSprite
    {
        private var loader:Loader;
        private var url:String;
        
        public function SampleCast()
        {
            loader = new Loader();
            loader.alpha = 0;
            addChild( loader );
        }
        
        private function setURL():void
        {
            url = "images/sample.jpg";
        }
        
        protected override function _onCastAdded():void
        {
            addCommand(
                new Func( this, setURL ),
                new Func( null, loader.load, [ url ], 0, loader.contentLoaderInfo, Event.COMPLETE ),
                new DoTweener( loader, { alpha: 1.0, time: 2 } )
            );
        }
        
        protected override function _onCastRemoved():void
        {
            addCommand(
                new DoTweener( loader, { alpha: 0, time:0.3 } ),
                new Func( loader, loader.unload )
            );
        }
    }
}

解決方法を考えてみた

要は Func コマンドで URL を引数として渡さなければいい。そこで考えたのが以下の3つ。

  1. Loader のラッパークラスを作って load 実行時に引数を渡さないようにする( URL は インスタンス作成時に指定)
  2. Loader 用のカスタムコマンドクラスを作って値参照のタイミングをもっと柔軟にする
  3. 引数無しの関数を別途定義し、dispatchEvent でロード完了のタイミングを取ってくる

お手軽な 3 を選択。本当は 2 を選択すると良さげ。以下コード。

package
{
    import flash.display.Loader;
    import flash.events.Event;
    import flash.net.URLRequest;
    import jp.progression.casts.CastSprite;
    import jp.progression.commands.*;
    import jp.progression.Progression;
    import caurina.transitions.Tweener;
    
    [Event( name="loadComplete", type="flash.events.Event" )]
    
    public class SampleCast extends CastSprite
    {
        private var loader:Loader;
        private var url:String;
        
        public function SampleCast()
        {
            loader = new Loader();
            loader.alpha = 0;
            addChild( loader );
        }
        
        private function setURL():void
        {
            url = "images/sample.jpg";
        }
        
        private function loadImage():void
        {
            loader.contentLoaderInfo.addEventListener( Event.COMPLETE, loadCompleteHandler );
            loader.load( new URLRequest( url ) );
        }
        
        private function loadCompleteHandler( evt:Event ):void
        {
            dispatchEvent( new Event( "loadComplete" ) );
        }
        
        protected override function _onCastAdded():void
        {
            addCommand(
                new Func( this, setURL ),
                new Func( this, loadImage, [], 0, this, "loadComplete" ),
                new DoTweener( loader, { alpha: 1.0, time: 2 } )
            );
        }
        
        protected override function _onCastRemoved():void
        {
            addCommand(
                new DoTweener( loader, { alpha: 0, time:0.3 } ),
                new Func( loader, loader.unload )
            );
        }
    }
}

Progression Framework 3.x.x

2.x.x系でずっとやっているので、3.x.x系を触れない。エフェクト系も追加されて興味津々なんだけど、怖くて今はアップデートできない。どこかのタイミングで移行したいなー。

heteml banner

Comments:0

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Trackbacks:0

TrackBack URL for this entry
http://nondelion.com/cms/mt-tb.cgi/113
Listed below are links to weblogs that reference
Progression のコマンドクラスの Func コマンドではまった from nondelion.com

Home > flash > Progression のコマンドクラスの Func コマンドではまった

Search
Feeds

Return to page top