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
}