actionscriptでアンドゥ、リドゥの実装

自分で作っているプログラムにアンドゥ、リドゥ実装したくなったので、
簡単なサンプル作ってみた。

package {
    import flash.display.Sprite;	
    import flash.events.MouseEvent;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    
    public class SandBox extends Sprite{
    	//描画、マウスハンドラ用
        private var child:Sprite;
        //描画位置の配列
    	private var PointArray:Array;
   	//タイマー関数
	private var timer:Timer;
	//アンドゥ用データ
	private var UndoData:Array;
	
	public function SandBox()
	{
	 PointArray = new Array();
	 UndoData = new Array();
	 	
	 child = new Sprite();
         child.focusRect = false;
         //背景クリア
         child.graphics.beginFill(0xffffff);
         child.graphics.drawRect(0,0,1024,768);
         child.graphics.endFill();
         addChild(child);
	 	  
	 //イベント追加
         child.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
          
               
         timer=new Timer(40,0);
         timer.addEventListener(TimerEvent.TIMER,onTick);
         timer.start();
          
          
		 
	 }
	 	
	 	
	 //時間毎に行う処理
	private function onTick(evt:TimerEvent):void 
	{
	  //背景クリア	
	  child.graphics.beginFill(0xffffff);
          child.graphics.drawRect(0,0,1024,768);
          child.graphics.endFill();
          
          child.graphics.beginFill(0x000000);
          child.graphics.drawRect(500,100,100,100);
          child.graphics.endFill();
          
          child.graphics.beginFill(0x0000ff);
          child.graphics.drawRect(600,100,100,100);
          child.graphics.endFill();
          
          var i:int;
          for(i=0;i<PointArray.length;++i){
	      child.graphics.beginFill(0xff0000);
	      child.graphics.drawCircle(PointArray[i].Getx(),PointArray[i].Gety(),20);
	      child.graphics.endFill();
          }
          
	}
	 	
	 private function mouseDownHandler(evt:MouseEvent):void {
	 	
	  if(500 < mouseX && mouseX < 600){
              if(100 < mouseY && mouseY < 200){
            	Undo();
            	return;
              }
          }
         
         
         if(600 < mouseX && mouseX < 700){
            if(100 < mouseY && mouseY < 200){
                Redo();
            	return;
            }
         }
         
	 		
	 PointArray.push(new Point(mouseX,mouseY));
        }
        
        private function Undo():void
        {
          if(PointArray.length  > 0){
	       	UndoData.push(PointArray.pop());
          }
        }
        
        private function Redo():void
        {
           if(UndoData.length  > 0){
	       	PointArray.push(UndoData.pop());
	   }
        }
    }
}

以下がコンパイル結果。
適当な所をクリックすると赤い丸がおけて、黒い四角クリックでアンドゥ、
青い四角でリドゥです。
アンドゥ、リドゥ


現在はデータに対してアンドゥ、リドゥしているけど、
Commandパターンを用いて処理自体をアンドゥ、リドゥをする方法もある。
ペイントソフトのように、様々な描画処理を一般化してアンドゥ、リドゥできますね。

Undo,Redoの実装って何十回もやってる気がする - あしあと日記
http://www.sun-inet.or.jp/~yaneurao/intensive/ggg/