package flare.vis.operator { import flare.animate.FunctionSequence; import flare.animate.Transitioner; import flare.util.Vectors; /** * An OperatorSequence maintains a list of operators that are run in * sequence with an animated transition in between each. This is in * contrast to an OperatorList, which runs all the operators at once * and constructs a single animated transition across all sub-operators. * Instead, an OperatorSequence runs each operator separately, providing * each with a different Transitioner. The result is a multi-stage * animation, in which each operator in the seqeunce get its own * sub-transition. * *

The add method is not supported by this class. Instead, * use the addToSequence method, which includes the operator * to add along with a duration value (in seconds) specifying the length * of the animated transition for the operator.

* *

An OperatorSequence is implemented by creating a * flare.animate.FunctionSequence instance and using it to * construct the staged animation. The FunctionSequence is * then added to the Transitioner passed in to the * operate method for this class. As a result, the * operate methods for each operator contained in the * seqeunce will not be invoked until the top-level * Transitioner is played.

* *

However, if the input Transitioner is null or in * immediate mode, all the operators in the sequence will be run * immediately, exactly like a normal OperatorList.

*/ public class OperatorSequence extends OperatorList { /** @private */ protected var _times:Vector. = new Vector.; /** * Creates a new OperatorSequence. */ public function OperatorSequence() { super(); } /** * Adds an operator and its timing information to this operator * sequence. The operator will be invoked with a transitioner * configured with the given duration (in seconds). * @param op the operator to add to the sequence * @param duration the duration of the animated transition to be * used for results of the given operator. */ public function push(op:IOperator, duration:Number):void { super.add(op); _times.push(duration); } /** * Sets the duration in seconds for the animated transition for the * operator at the given index. * @param i the index at which to set the duration * @param duration the desired duration, in seconds * @return the previous duration value */ public function setDurationAt(i:uint, duration:Number):Number { var old:Number = _times[i]; _times[i] = duration; return old; } /** * This method is not supported by this class and will throw an error * if invoked. * @param op an input operator (ignored) */ public override function add(op:IOperator):void { throw new Error("Operation not supported. Use push instead."); } /** @inheritDoc */ public override function remove(op:IOperator):Boolean { var idx:int = Vectors.remove(_list, op); if (idx >= 0) { _times.splice(idx, 1); return true; } else { return false; } } /** @inheritDoc */ public override function removeOperatorAt(i:uint):IOperator { var op:IOperator = super.removeOperatorAt(i); if (op != null) _times.splice(i, 1); return op; } /** @inheritDoc */ public override function operate(t:Transitioner=null):void { if (t==null || t.immediate) { super.operate(t); } else { var fs:FunctionSequence = new FunctionSequence(); for (var i:int=0; i<_list.length; ++i) { if (_list[i].enabled) fs.push(getFunction(_list[i] as IOperator), _times[i]); } t.add(fs); } } private function getFunction(op:IOperator):Function { return function(t:Transitioner):void { op.operate(t); if (visualization.axes) { visualization.axes.update(t); } } } } // end of class OperatorSequence }