/** * @author: Sebastian Martens; sebastian@sebastian-martens.de * @copyright: * @svn: $Id: JsCallStack.as 9 2008-12-25 23:35:24Z dinnerout $ */ package com.nonstatics.jsCallStack { import flash.events.TimerEvent; import flash.external.ExternalInterface; import flash.utils.Timer; import mx.collections.ArrayCollection; /** * @classdescription: JsCallStack implements a stack for JavaScript calls from AS3 via the ExternalInterface Class. Sometimes * if you use too many JS Calls at the same time, not all JS Calls will be handled correctly. With this * class you can use a stack which will call the js functions asynchronous with a timer. You are also able to * get ridd of double called functions */ public class JsCallStack { public static const STACK_MODE_LIFO:int = 0; public static const STACK_MODE_FIFO:int = 1; private var _stack:ArrayCollection; // stack of javascript calls private var _callTimer:Timer; // timer object private var _timerInterval:int = 500; // interval timer calles javascript functions in ms private var _stackMode:int = JsCallStack.STACK_MODE_LIFO; // sets internal stack mode private var _isExAvailable:Boolean; /** * setter method for timer interval value * @param value:Int - timer interval in milliseconds */ public function set timerInterval( value:int ):void{ var isRunning:Boolean = this._callTimer.running; // stop timer, set new value and restart if timeer was running this._callTimer.stop(); this._timerInterval = value; this._callTimer.delay = this._timerInterval; if( isRunning ) this._callTimer.start(); } /** * getter method for timer interval * @return Int - set timer interval */ public function get timeInterval():int{ return this._timerInterval; } /** * pauses the execution of javascript calls */ public function pauseExecution():void{ this._callTimer.stop(); } /** * restarts the execution of javascript calls */ public function startExecution():void{ if( this._stack.length > 0 ){ this._callTimer.start(); } } /** * returns if the timer is running * @return Boolean - is the execution timer running */ public function isExecutionRunning():Boolean{ return this._callTimer.running; } /** * constructor method * @param stackMode:int - stack mode of handling stack entries */ public function JsCallStack( stackMode:int=JsCallStack.STACK_MODE_FIFO ){ // test if ExInterface is available this._isExAvailable = ExternalInterface.available; // init stack this._stack = new ArrayCollection(); // timer this._callTimer = new Timer( this._timerInterval ); this._callTimer.addEventListener(TimerEvent.TIMER, stackHandler); // stack mode this._stackMode = stackMode; } /** * adds an javascript function call to call stack * @param funcName:String - function name of js function to call * @param paramter:Object - object of paramters to path to the javascript function * Object will be converted to JSON and hand over an JSON-Object * @param resultHandler:Function - method to handler javascript results * @param skipOldCalls:Boolean - if true older calls in stack of the same functionname won't be * called any more, only latest call * @param convert2JSON:Boolean - if true the parameter object will be converted to JSON for the javascript call * @return Int value of stack position, returns -1 if External Interface is not available */ public function addJSCall( funcName:String, parameter:Object=null, resultHandler:Function=null, skipOldCalls:Boolean=false, convert2JSON:Boolean=false ):int{ var position:int = this._stack.length; // External Interface not available if( !this._isExAvailable ) return -1; // create object and add to stack var o:Object = { functionName:funcName, params:parameter, resHandler:resultHandler, skip:skipOldCalls, id:position, convertToJSON:convert2JSON }; this._stack.addItemAt( o, position ); // start timer if not running if( !this._callTimer.running ) this._callTimer.start(); return position; } /** * removes an javascript call from stack * @param id:int - identifier position of call which was returned from addJSCall Method * @return Boolean - function found an removed, false if already called */ public function removeJSCall( id:int ):Boolean{ var result:Boolean = false; var isRunning:Boolean = this._callTimer.running; // no item in stack if( this._stack.length==0 ) return true; // stop call timer to avoid access confilcts this._callTimer.stop(); // search in stack for id for( var i:int=0; i