Access keys

ActionQueue

Kind of class: class
Inherits from: Dispatcher
Known subclasses:
Author: Arthur Clemens
Classpath: org.asapframework.util.actionqueue.ActionQueue
File last modified: Thursday, 12 October 2006, 11:09:49
Scripted animation and function flow class.
ActionQueue stores and runs a series of functions/methods one after the other. You can call local functions, object methods and special movieclip control methods, such as timed "fade", "move" or "pulse" functions.
ActionQueue is handy when you need timed animation, state transitions, complex button behavior or a series of functions that need to wait for a certain condition before they are run. You can insert waiting for messages or variable conditions (see #ExtendedActionQueue).
The most common use for ActionQueue is to manipulate movieclips.

Adding actions to the queue
addAction (myFunction) : Adds a (locally scoped) function or an anonymous function.
addAction (myObj, myMethod) : Adds an object's method.
addAction (myObj, myMethodName) : Adds an object's method by using the method's name. The object's method does not have to be known at the time that it is added to the queue.
addAction (myAQAction) : Adds a custom movieclip action from one of the AQxxx classes; use fade, scale, move, etcetera. See the list of available action methods at addAction, or create your own action method.
addInAction: As addAction, but in a separately spawned thread; this eliminates the need to create separate methods and queues for movieclip actions that should occur at the same time.

See also the method list summary.

On effects
ActionQueue 'AQ' methods such as AQScale.scale may use Flash' easing effects from mx.transitions.easing. You can use the default mx.transitions.easing effects, or define your own.

Example with mx.transitions.easing.Elastic:
import mx.transitions.easing.*;
queue.addAction( AQScale.scale, my_mc, 1, null, null, 100, 100, Elastic.easeIn );

Advanced Queue functions
To use conditional messages, conditions and looping, use ExtendedActionQueue.

Simultaneous effects
To control different movieclip aspects at the same time, for instance to move a clip and fade it out, use addInAction, or use AQReturnValue (example given below at addAction).
Usage:
This code example demonstrates a combination of ActionQueue methods, to give an idea of how this class can be used in an application.
import org.asapframework.util.actionqueue.*;
import mx.transitions.easing.*;
Create the ActionQueue instance:
var queue:ActionQueue = new ActionQueue();
With addAction you can use methods from AQSet to set properties of movieclips:
queue.addAction( AQSet.setAlpha, circle_mc, 75 );
queue.addAction( AQSet.centerOnStage, circle_mc );
queue.addAction( AQMove.move, circle_mc, 4, null, null, 0, 0, Bounce.easeInOut);
To add a pause, use addPause(number of seconds), where 0 means wait forever - indefinite pauses can be terminated by skip, ExtendedActionQueue.addContinueOnMessage and ExtendedActionQueue.addContinueOnCondition.
queue.addPause( 0.5 );
queue.addAction( AQFade.fade, circle_mc, 2, null, 100, Regular.easeIn );
All actions are added. Now let them perform:
queue.run();

We decide to let the button pulse, to indicate that the button has primary focus.
We create a pulse queue in the button class:
import org.asapframework.util.actionqueue.*;

class LoadButton extends MovieClip {

    private var mQueue:ActionQueue;

    public function activate () : Void {
        mQueue = new ActionQueue();
        // pulse with infinite duration:
        var duration:Number = 0;
        mQueue.addAction( AQPulse.pulse, this, null, 0.5, 100, 40, 100, duration );
        mQueue.run();
    }

    public function deactivate () : Void {
        mQueue.quit();
    }
}
Events broadcast to listeners:
ActionQueueEvent with type: QUEUE_STARTED
ActionQueueEvent with type: QUEUE_QUIT
ActionQueueEvent with type: QUEUE_PAUSED
ActionQueueEvent with type: QUEUE_RESUMED
ActionQueueEvent with type: QUEUE_STOPPED
ActionQueueEvent with type: QUEUE_FINISHED

Constructor

ActionQueue

function ActionQueue (
inName:String)
Creates and initializes a new ActionQueue object.
Parameters:
inName:
(optional) unique identifying name for the queue
Usage note:
When an ActionQueue performs a function on an object or movieclip, the queue will keep on executing when the object is deleted. And because the reference to the queue still exists, the object will stay alive as long as the queue is active. This will lead to a memory leak. So when you delete an object, you are also responsible yourself for deleting the queue.
Example:
public function onActionQueueStarted (e:ActionQueueEvent) : Void {
    Log.debug("queue " + e.name + " has started");
}
public function onActionQueueFinished (e:ActionQueueEvent) : Void {
    Log.debug("queue " + e.name + " has finished");
}
var queue:ActionQueue = new ActionQueue( "main queue" );
queue.addEventListener(ActionQueueEvent.QUEUE_STARTED, this);
queue.addEventListener(ActionQueueEvent.QUEUE_FINISHED, this);

If you don't need a queue status report you can create a queue in a more simple way:
var queue:ActionQueue = new ActionQueue();

Instance properties

count

count:Number
(read)
The number of items in the queue; for debugging purposes.

Class methods

relativeValue

static function relativeValue (
inStart:Number, inEnd:Number, inPercentage:Number) : Number
Calculates the relative value between start and end of a function at moment inPercentage in time. For instance with a movieclip that is moved by a function from A to B, relativeValue calculates the position of the movieclip at moment inPercentage.
Parameters:
inStart :
the start value of the object that is changing, for instance the start _x position
inEnd :
the end value of the object that is changing, for instance the end _x position
inPercentage:
the current moment in time expressed as a percentage value
Returns:
The relative value between inStart and inEnd at moment inPercentage.
Implementation note:
The used calculation is inStart + (inPercentage * (inEnd - inStart))
Example:
public function moveToActualPosition () : Void {
    mStartIntroPosition = new Point(_x, _y);
    mStartIntroScale = _xscale;
    var duration:Number = 2.0;
    var queue:ActionQueue = new ActionQueue();
    queue.addAction( AQReturnValue.returnValue, this, "performMoveToActualPosition", duration, 0, 1);
    queue.run();
}

private function performMoveToActualPosition (inPercentage:Number) : Void {
    _x = ActionQueue.relativeValue( mStartIntroPosition.x, mPosition.x, inPercentage );
    _y = ActionQueue.relativeValue( mStartIntroPosition.y, mPosition.y, inPercentage );
    _xscale = _yscale = ActionQueue.relativeValue( mStartIntroScale, mScale, inPercentage );
}

Instance methods

actions

function actions (
) : Array
Returns:
The array of action objects.

addAction

function addAction (
Overloaded method that accepts a number of argument configurations.

Adding a function
Will be called in local scope.
public function addAction ( inFunction:Function, argument1, argument2, ... ) : ActionQueue

Adding a object's method
Will be called in the object's scope.
public function addAction ( inMethodObject:Object, inMethod:Function, argument1, argument2, ... ) : ActionQueue

Adding a object's method by name
Will be called in the object's scope.
public function addAction ( inMethodObject:Object, inMethodName:String, argument1, argument2, ... ) : ActionQueue

Adding an action that will perform a function on an onEnterFrame
Such as movieclip control methods (like AQMove.move) (will be called in AQWorker's scope).
public function addAction ( inFunction:Function, argument1, argument2, ... ) : ActionQueue
The function inFunction should return a ActionQueuePerformData object.
Example:
Add a Custom interface/movieclip control method

Use any function that returns a ActionQueuePerformData, or use one of the ready made class metods from these classes:
AQAddMove
AQBlink
AQColor
AQFade
AQFollowMouse
AQMove
AQMoveRel
AQPulse
AQReturnValue
AQScale
AQSet
AQSpring
AQTimeline

This example will move a movieclip from its current position (null, null) to a new position (500, the current y value), during 1 second:
queue.addAction( AQMove.move, my_mc, 1, null, null, 500, null );
This example sets the alpha property of a movieclip to 50:
queue.addAction( AQSet.setAlpha, my_mc, 50 );

You can also create a custom function and pass this to the queue. This is especially useful when you need to have more complex interaction with the objects to control.

Follows an example of a function that is very similar to AQxxx class methods, and is in fact copied from AQMove.move - with the difference that we want to fade out the movieclip while it is moving.
// somewhere in your class
public function moveAndFade (inMC:MovieClip,
                             inDuration:Number,
                             inStartX:Number,
                             inStartY:Number,
                             inEndX:Number,
                             inEndY:Number,
                             inEffect:Function ) : ActionQueuePerformData {

    // initalize variables here

    var performFunction:Function = function (inPerc:Number) : Boolean {
        // do something with the received inPerc
        return true;
    };

    // Set up the data so ActionQueue will perform the function performFunction:
    var startValue:Number = 1.0; // counting from 1 down to 0
    var endValue:Number = 0;
    return new ActionQueuePerformData( performFunction, inDuration, startValue, endValue, inEffect );
}
Note that performFunction returns a Boolean. To abort performFunction let it return false.

Now you add the function to the queue using addAction:
var queue:ActionQueue = new ActionQueue();
queue.addAction( this, moveAndFade, my_mc, 5, null, null, 500, 200, Regular.easeInOut );
queue.run();

addAQMethod

function addAQMethod (
inMethod:Object) : ActionQueue
Deprecated As of 3 Feb 2006. Use addAction.

addCleanup

function addCleanup (
Deprecated Use run.
Cleans up the ActionQueue object after use, when the queue has been emptied. After this call no more actions can be added. Use this method after the last action.

addFunction

function addFunction (
inFunctionRef:Function) : ActionQueue
Deprecated As of 3 Feb 2006. Use addAction.
Adds a (locally scoped) function or reference (or an anonymous function) to a object's method to the queue.

addInAction

function addInAction (
addInAction stands for 'add Instant Action'. This method adds interface control method to the queue that is performed immediately as it processed by the queue (as soon as Flash triggers a new onEnterFrame). In contrast to addAction, the queue won't wait for the end of this method. This eliminates the need to create separate methods and queues for movieclip actions that should occur at the same time.
See for parameters and usage at addAction.
Returns:
The internally created ActionQueue - this is useful when you need to end an eternal queue.
Example:
The following code lets the movieclip 'ball_mc' move to a certain point, then simultaneously fades out the clip and clip 'square_mc':
queue.addAction( AQMove.move, ball_mc, 1, null, null, 500, null );
queue.addInAction( AQFade.fade, square_mc, 2, null, 0 );
var eternalQueue:ActionQueue = queue.addInAction ( AQPulse.pulse, square_mc, null, 0.5, 100, 40, 100, 0);
queue.addAction( this, "finishUp" );
Because the fading of the ball clip is part of the normal queue, the method 'finishUp' is called after ball_mc is finished fading out.
Kill the pulsing of eternalQueue:
eternalQueue.quit();
Implementation note:
A separate internal queue is created inside an anonymous function, and this function is added to the external queue. This queue is set to run and cleans up after itself.

addInAQMethod

function addInAQMethod (
inFunction:Object) : ActionQueue
Deprecated As of 3 Feb 2006. Use addInAction.

addMethod

function addMethod (
inObject:Object, inMethodName:String) : ActionQueue
Deprecated As of 3 Feb 2006. Use addAction.
Adds an object's method to the queue, by using the method's name. This way the object's method does not have to be known at the time that it is added to the queue.

addPause

function addPause (
inDuration:Number) : ActionQueue
Adds a pause to the queue. The next action in the queue will be called after the duration of the pause.
Parameters:
inDuration:
pause duration in seconds. Use 0 to pause the queue indefinitely.
Returns:
The current ActionQueue.
Example:
This example will pause the queue forever (until skip or ExtendedActionQueue.addContinueOnMessage or ExtendedActionQueue.addContinueOnCondition is called).
queue.addPause( 0 );

AQQuit

function AQQuit (
Quits the queue.
Events broadcast to listeners:
ActionQueueEvent with type: QUEUE_FINISHED
ActionQueueEvent with type: QUEUE_QUIT

clear

function clear (
Erases the queued actions and stops the queue. New actions can be added and the queue can be restarted with run.
Returns:
The current ActionQueue.
Example:
In this example a queue belonging to one button (scale_btn) is cleared by pressing another button (clear_btn). After that a new action is added and run.
import mx.transitions.easing.*;

scale_btn.startScale = function () {
    var queue:ActionQueue = new ActionQueue();
    this.queue = queue;
    this.queue.addAction( AQScale.scale, scale_mc, 5, null, null, 400, 400, Regular.easeOut );
    // possibly other actions...
    this.queue.run(true); // note: keepAlive set to true
}
clear_btn.onPress = function() {
    scale_btn.queue.clear();
    // add a new method to scale down again
    scale_btn.queue.addAction( AQScale.scale, scale_mc, 1, null, null, 100, 100, Regular.easeOut );
    scale_btn.queue.run(true); // note: keepAlive set to true
}

insertQueue

function insertQueue (
inActionQueue:ActionQueue) : ActionQueue
Inserts an ActionQueue that is run immediately as it is processed in the queue. insertQueue is similar to insertQueueActions, with the difference that param inActionQueue will be run independently of the current queue.
Parameters:
inActionQueue:
the ActionQueue to be inserted an run
Returns:
The newly inserted queue inActionQueue.
Example:
var queue1:ActionQueue = new ActionQueue();
queue1.addAction( this, "write", "A" );
queue1.addAction( this, "write", "B" );

var queue2:ActionQueue = new ActionQueue();
Adding a pause will cause the 'write' actions of queue2 to be ran after the actions of queue1 have been finished:
queue2.addPause(1);
queue2.addAction( this, "write", "C" );
queue2.addAction( this, "write", "D" );

queue1.insertQueue( queue2 );
queue1.addAction( this, "write", "E" );
queue1.run();
Output: ABE, and somewhat later: CD
The following example shows a combined effect of fading in and zooming in, where the fading is started exactly halfway the zooming:
var duration:Number = 0.4;
var queue = new ActionQueue();
queue.insertQueue( new ActionQueue().addPause(duration/2).addAction( AQFade.fade, my_mc, 1.0, null, 100 ) );
queue.addAction( AQZoom.zoom, my_mc, duration );
queue.run();

insertQueueActions

function insertQueueActions (
inActionQueue:ActionQueue) : ActionQueue
Inserts the actions of inActionQueue in the current queue. insertQueueActions is similar to insertQueue, with the difference that the actions that will be added to the current queue will be performed after the action of param inActionQueue - the order of performed actions will not change.
Parameters:
inActionQueue:
the ActionQueue which actions are inserted
Returns:
The current ActionQueue.
Example:
var queue1:ActionQueue = new ActionQueue();
queue1.addAction( this, "write", "A" );
queue1.addAction( this, "write", "B" );

var queue2:ActionQueue = new ActionQueue();
Adding a pause will not make a difference in the output, as the pause will also be added to the actions of queue1:
queue2.addPause(1);
queue2.addAction( this, "write", "C" );
queue2.addAction( this, "write", "D" );

queue1.insertQueue( queue2 );
queue1.addAction( this, "write", "E" );
queue1.run();
Output: ABCDE

isBusy

function isBusy (
) : Boolean
Queries the active state of the queue.
Returns:
Whether the ActionQueue is performing any action: true when running or paused, false when the queue is empty.
Example:
Example of a pause toggle button that uses isBusy to check if the queue should be ordered to run or to pause:
pause_btn.onRelease = function() {
    if (queue.isBusy()) {
        if (queue.isPaused()) {
            queue.play();
        } else {
            queue.pause();
        }
    } else {
        queue.run();
    }
}

isPaused

function isPaused (
) : Boolean
Retrieves the paused state of the queue. The queue can be pause using pause and restarted using play.
Returns:
Whether the queue is paused (true) or not (false).

name

function name (
) : String
Returns:
The identifier name of the queue; for debugging purposes.

pause

function pause (
inTimerShouldContinue:Boolean) : ActionQueue
Pauses the queue in the middle of an action. The action can be resumed by calling play. pause breaks in into a queue and must not be confused with addPause, that inserts a waiting time in between actions.
Parameters:
inTimerShouldContinue:
(optional) if true, the timer continues counting to the set end time; default value is false: the time left is stored and added to the current time when playing is resumed with play
Returns:
The current ActionQueue.
Events broadcast to listeners:
ActionQueueEvent with type: QUEUE_PAUSED

play

function play (
Resumes the queue after pause. The queue will resume with the stored action where it was left, including animations.
Returns:
The current ActionQueue.
Events broadcast to listeners:
ActionQueueEvent with type: QUEUE_RESUMED

quit

function quit (
Stops and deletes the queue.
Returns:
The current ActionQueue.
Events broadcast to listeners:
ActionQueueEvent with type: QUEUE_QUIT

run

function run (
inKeepAlive:Boolean) : ActionQueue
Starts the queue for the first time.
Parameters:
inKeepAlive:
If true, further actions can be appended after running; default false: the thread will clean up after itself automatically, and no more actions can be added.
Returns:
The current ActionQueue.
Events broadcast to listeners:
ActionQueueEvent with type: QUEUE_STARTED

skip

function skip (
Skips over the current action and calls the next action in the queue.
Returns:
The current ActionQueue.
Example:
var queue:ActionQueue = new ActionQueue();
queue.addAction( AQFollowMouse.followMouse, square_mc, 0.1, 0.9); // will not end out of itself
queue.addAction( AQFade.fade, square_mc, 2.0, null, 0 );	
queue.run();

// Clicking the skip_btn will stop the followMouse and fade out square_mc 
skip_btn.onRelease = function() {
    queue.skip();
}

toString

function toString (
) : String

Event handlers

onEnterFrame

function onEnterFrame (
inEvent:FramePulseEvent) : Void
onEnterFrame is called every enter frame
|
-> calls AQnext => while loop is used here whenever possible to bypass onEnterFrame, and AQapplyAction is called instead
|
-> calls AQapplyAction
|
-> calls the action

Calls AQstop when no more actions are in the list.
Parameters:
inEvent:
not used