実行中のキューイング処理を中断する

連続する一連の処理を行う方法は、コマンドのキューイングを使うことで落ち着いているが、処理中のキューを中断するインタフェースを設計していなかった。つまり、一度引き金を引いたら弾を撃ち尽くすまで止められない、という状況だった。

なので、早急にコマンドとインボーカに abort を実装し、いかなる状態でも処理を中断できるようにした。クライアントオブジェクトは、インボーカの abort を呼び出せば、実行しているコマンドを意識することなく処理を中断 (正しくは破棄) できる。

例えば、ある段階で処理する内容が、

  1. XML の読み込み
  2. Tween アニメーション

というオーダの場合、各々のプロセスをコマンドに置き換えると以下のようになる。

loadXMLCommand

class loadXMLCommand extends AbstractCommand {
//実行の実装
public function execute():Void {...};
//完了の実装
public function done():Void {...};
}

playTweenAnimationCommand

class playTweenAnimationCommand extends AbstractCommand {
//実行と完了の実装
}

そして、これらに中断時の処理を実装する。XML ロードコマンドならばローダの破棄、Tween アニメーションのコマンドならば、Tween を停止し、リスナの解除等を行えばよいだろう。

class playTweenAnimationACommand extends AbstractCommand {
//破棄の実装
public function abort():Void {
this.tween.stop();
this.tween.removeListener(this.tweenListner);
}
}

次に、インボーカ側の abort の実装例。現在処理中のコマンドと、待ち行列に入っているコマンドの abort を呼び出す。

class Invoker {
public function abort():Void {
this.aborted = true;
//現在処理中のコマンドを破棄する
this.currentCommand.abort();
//キューに残っているコマンドを破棄する
while (this.commandQueue.getLength() > 0) {
var command:AbstractCommand = this.commandQueue.dequeue();
command.abort();
}
}
}

デストラクタの定義と同様に、プロセスの管理方法を徹底しておけば、後々になって苦労しなくて済むだろう。