Nov
9
9
CommandQueue – memento, undos and more
© 2010 pajamacode | Theme by DemusDesign, Theme Lab, and Search Optimization | Powered by WordPress
I’ve been experimenting with creating a sort of queue pool of commands that could be executed at any specified interval. But rather than creating a glorified tween sequencer, I wanted to have it be more generic and be able to “save” the previous state. The way I did this is via the often blogged about deep object copying using serialization. Unfortunately, it’s not possible to deep object copy a sprite or MovieClip directly so instead I added a type or proxying as well.
This is really the 0.1 verision of the class with quite a few bug fixes probably needed down the road but it shows some of the over-all concepts.
package com.pj_co.core
{
import com.pj_co.interfaces.IRegisteredDispatcher;
import com.pj_co.models.Command;
import com.pj_co.util.ObjectUtils
import flash.utils.Timer;
import flash.net.registerClassAlias;
import flash.net.getClassByAlias
import flash.events.TimerEvent;
import flash.events.EventDispatcher;
/**
* Cues commands using a timer based upon the delay param passed to the addCommand method
* @author Patrick Cousins pj@pj-co.com
* @version 0.1
*/
public class CommandQueue extends EventDispatcher //implements IRegisteredDispatcher
{
private var queuePool : Array;
private var _undoObjArray : Array;
private var _index : uint = 0;
private var _isRunning : Boolean = false;
private var looping : Boolean = false;
private var numOfTimesToRun : uint = 0;
private var timer : Timer;
private var direction : String;
public static const PLAY_FORWARD : String = "playCommandQueueForward";
public static const PLAY_REVERSE : String = "playCommandQueueReversed";
function CommandQueue ( )
{
init ( ) ;
}
public function get index ():uint { return _index; }
public function get isRunning ():Boolean { return _isRunning; }
public function get undoObjArray ():Array { return _undoObjArray; }
private function init ( ):void
{
queuePool = new Array ( ) ;
_undoObjArray = new Array ( ) ;
}
public function addCommand ( func : Function,
argArray : Array = null,
delay : uint = 0,
obj : * = null,
objClass : Class = null,
useDeepCopy : Boolean = false
) : void
{
// the problem with args is we need to apply them to the func in
// a way that matches that method's signature
var command : Command = new Command ( ) ;
command.func = func;
command.args = argArray;
command.delay = delay;
command.obj = obj;
command.objClass = objClass;
command.useDeepCopy = useDeepCopy;
queuePool.push ( command ) ;
}
public function execute ( direction : String = CommandQueue.PLAY_FORWARD,
numOfTimesToRun : uint = 1
) : void
{
this.direction = direction;
this.numOfTimesToRun = numOfTimesToRun;
_isRunning = true;
looping = numOfTimesToRun != 1 ? true : false
runNext ( ) ;
}
public function stop ( ) : void
{
try
{
timer.removeEventListener ( TimerEvent.TIMER_COMPLETE, runCommand ) ;
timer.stop ( ) ;
timer = null;
}
catch ( e : Error )
{
//no timer to remove
}
finally
{
_isRunning = false;
}
}
private function runNext ( ) : void
{
if ( _index >= queuePool.length || _index < 0 )
{
if ( looping && numOfTimesToRun > 1 )
{
numOfTimesToRun --;
runQueue ( ) ;
}
else if ( looping && numOfTimesToRun == 1 )
{
looping = false;
numOfTimesToRun --;
runQueue ( ) ;
}
else
{
stop ( ) ;
}
}
else
{
runQueue ( ) ;
}
}
private function runQueue ( ):void
{
try
{
timer.removeEventListener ( TimerEvent.TIMER_COMPLETE, runCommand ) ;
timer.stop ( ) ;
timer = null;
}
catch ( e : Error )
{
//no timer to remove
}
var command : Command = queuePool [ _index ] ;
timer = new Timer ( command.delay, 1 ) ;
timer.addEventListener ( TimerEvent.TIMER_COMPLETE, runCommand ) ;
timer.start ( ) ;
}
private function runCommand ( te : TimerEvent ) : void
{
var command : Command = queuePool [ _index ] ;
var argsWithObj : Array = command.args
makeCopy ( command ) ;
argsWithObj.unshift ( command.obj ) ;
command.func.apply ( null, argsWithObj ) ;
timer.removeEventListener ( TimerEvent.TIMER_COMPLETE, runCommand ) ;
_index = direction == CommandQueue.PLAY_FORWARD ? _index + 1 : _index - 1;
runNext ( ) ;
}
private function makeCopy ( cmd : Command ) : void
{
trace ( "makeCopy" ) ;
var undoObj : *
trace ( cmd.useDeepCopy ) ;
if ( cmd.useDeepCopy )
{
undoObj = ObjectUtils.deepCopy ( cmd.obj, cmd.objClass ) ;
}
else
{
undoObj = ObjectUtils.shallowCopy ( cmd.obj, cmd.objClass ) ;
}
_undoObjArray.push( undoObj );
}
}
}
filed under: Scripts | permalink
Leave a Reply
You must be logged in to post a comment.
