package org.casaframework.time { import flash.events.Event; import flash.events.EventDispatcher; import flash.events.IEventDispatcher; import org.casaframework.events.SequenceEvent; import org.casaframework.util.ArrayUtil; public class Sequence extends EventDispatcher { protected var isRunning:Boolean; protected var isLooping:Boolean; protected var completeFired:Boolean; protected var interval:Interval; protected var sequence:Array; protected var currentTaskID:int = -1; public function Sequence(isLooping:Boolean = false) { super(); isLooping = isLooping; sequence = new Array(); interval = Interval.setTimeout(triggerEvent, 1); } public function addTask(startMethod:Function, delay:Number = 0, scope:IEventDispatcher = null, completeEventName:String = null, position:int = -1):void { var task:Task = new Task(startMethod, delay, scope, completeEventName); if(position < 0) { sequence.push(task); }else { sequence.splice(position, 0, task); } } public function removeTask(task:Task):Boolean { if(ArrayUtil.removeItem(sequence, task)) { return true; } return false; } public function start():void { dispatchEvent(new SequenceEvent(SequenceEvent.START)); startSequence(); } public function stop():void { if(!isRunning) { return; } interval.stop(); completeFired = isRunning = false; dispatchEvent(new SequenceEvent(SequenceEvent.STOP)); } public function resume():void { if(isRunning) { return; } if(currentTaskID == -1) { start(); return; } isRunning = true; dispatchEvent(new SequenceEvent(SequenceEvent.RESUME)); if(completeFired) { startDelay(); }else { interval.start(); } } protected function startSequence():void { interval.stop(); isRunning = true; currentTaskID = -1; startDelay(); } protected function startDelay(event:Event = undefined):void { if(currentTaskID != -1) { removeCurrentListener(); } if(!isRunning) { completeFired = true; return; } if(++currentTaskID >= sequence.length) { if(isLooping) { dispatchEvent(new SequenceEvent(SequenceEvent.LOOP)); startSequence(); } else { dispatchEvent(new SequenceEvent(SequenceEvent.COMPLETE)); } return; } var newDelay:Number = current.delay; if(newDelay == 0) { triggerEvent(); }else { interval = Interval.setTimeout(triggerEvent, newDelay); interval.start(); } } protected function removeCurrentListener():void { if(current.completeEventName != null){ current.scope.removeEventListener(current.completeEventName, startDelay); } } protected function triggerEvent():void { if(current.completeEventName != null){ current.scope.addEventListener(current.completeEventName, startDelay); current.startMethod(); }else { current.startMethod(); startDelay(); } } protected function get current():Task { return Task(sequence[currentTaskID]); } } } import flash.events.IEventDispatcher; class Task { public var startMethod:Function; public var delay:Number; public var scope:IEventDispatcher; public var completeEventName:String; function Task(startMethod:Function, delay:Number, scope:IEventDispatcher = null, completeEventName:String = null) { this.startMethod = startMethod; this.delay = delay; this.scope = scope; this.completeEventName = completeEventName; } }