描画と処理開始のギャップを無くす、そんな設計

タスクシステムは、タスクという処理の塊をリストに登録し、メインループ(onEnterFrameとか)でリストに登録されたタスクの処理関数を一通りすべて実行するシステムです。
例えばそのリストへの登録を以下のようにするとします。

addTask(new Player());

このようにして初めてPlayerが動作を始めます。


しかしこのPlayerクラスの処理開始と同時に画面への描画(プレイヤーのグラフィックを描くとか)を行いたい場合、初期処理としてコンストラクタに描画処理を描くと、上の例では問題ありませんが、場合によって問題が起こることがあります。
とりあえず事前にPlayerをnewしておいて、処理を開始したいタイミングで初めてaddTaskする場合、実質、処理を開始するaddTaskの前のnewした段階で画面描画が行われ、「なんでコイツがこんな早い段階で描画されんねん。」ということになりかねません。

var player:Player = new Player();    // この段階で描画される

// なんかしら処理
// 何フレームか時間稼ぎ

addTask(player);    // 実質の処理開始


この実質の処理開始にあわせて、コンストラクタとは別に新たに処理開始時に実行されるメソッドなどができればシステムの柔軟性が上がりそうです。
Playerクラスが継承するTaskクラス

package
{
    public class Task
    {
        // コンストラクタ
        public function Task()
        {
        }

        // 実質の処理開始時に実行するメソッド
        public function init():void
        {
        }

        // 他もろもろ
    }
}

そしてリストに追加される時に上記のinitが実行されるよう、addTaskも弄ります。
addTaskメソッド

public function addTask(t:Task):Task
{
    // ここでリスト追加処理

    t.init();    // init実行

    return t;
}


あとはPlayerのコンストラクタで実行していた描画処理をTaskからオーバーライドしたinit内に移してやれば、リスト追加と同時にプレイヤーが描画されるということになります。

package
{
    public class Player extends Task
    {
        // コンストラクタ
        public function Player()
        {
        }

        // オーバーライドしたinitメソッド
        override public function init():void
        {
            // 描画処理
        }
    }
}


これで自分用タスクシステムがまた一つ柔軟になりました。
しかし機能を加えれば加えるほどややこしくなっていくのが心配です。


# 今回初めてはてなのコードハイライトを使ってみた。AS用のが見当たらなかったのでjavascript用で代用です。