Deflexing presents.

Created a simple MethodQueue utility class that works nearly identically
to UIComponent.callLater().


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4537 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2007-02-07 00:10:56 +00:00
parent 3c75faa8a1
commit 8ab80b10a5
3 changed files with 103 additions and 7 deletions
+94
View File
@@ -0,0 +1,94 @@
package com.threerings.util {
import flash.display.Stage;
import flash.events.Event;
/**
* A simple mechanism for queueing functions to be called on the next frame.
* Similar to UIComponent's callLater, only flex-free.
*/
public class MethodQueue
{
/**
* Set the stage which will be used for coordinating the use of the
* method queue. If no stage is set, functions will continue to pile up
* without being called.
*/
public static function setStage (stage :Stage) :void
{
if (_listening) {
removeListener();
}
_stage = stage;
checkListen();
}
/**
* Call the specified method at the entry to the next frame.
*/
public static function callLater (fn :Function, args :Array = null) :void
{
_methodQueue.push([fn, args]);
if (!_listening) {
checkListen();
}
}
/**
* Stop listening for the frame event.
*/
protected static function removeListener () :void
{
_stage.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
_listening = false;
}
/**
* Check to see if we should be listening for the next frame event.
*/
protected static function checkListen () :void
{
if (_stage != null && _methodQueue.length > 0) {
_stage.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
_listening = true;
}
}
/**
* Handle a frame event: call any queued functions.
*/
protected static function handleEnterFrame (event :Event) :void
{
// swap out the working set
var methods :Array = _methodQueue;
_methodQueue = [];
// safely call each function
for each (var arr :Array in methods) {
try {
Function(arr[0]).apply(null, (arr[1] as Array));
} catch (e :Error) {
Log.getLog(MethodQueue).warning("Error calling deferred method " +
"[e=" + e + ", fn=" + arr[0] + "].");
}
}
// If no new functions were added while we were calling the current set,
// then remove the listener.
if (_methodQueue.length == 0) {
removeListener();
}
}
/** The stage we're working with. */
protected static var _stage :Stage;
/** The currently queued functions. */
protected static var _methodQueue :Array = [];
/** Are we presently listening for the frame event? */
protected static var _listening :Boolean = false;
}
}