ActionScript 3 custom "call-later" almost working, expert wanted!
I have this class ('Scheduler.as'):
package
{
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Scheduler
{
private var m_tmr:Timer = null;
private var m_the_this:* = null;
private var m_function:Function = null;
private var m_args:Array = null;
public function Scheduler(the_this:*, f:Function, interval:int, args:Array = null)
{
this.m_the_this = the_this;
this.m_function = f;
this.m_args = args;
if (this.m_args.length == 0)
this.m_args = null;
this.m_tmr = new Timer(interval, 1);
this.m_tmr.addEventListener(TimerEvent.TIMER, on_timer);
this.m_tmr.start();
}
private function on_timer(e:TimerE开发者_运维百科vent):void
{
if (this.m_args == null)
this.m_function.call(this.m_the_this);
else
this.m_function.call(this.m_the_this, this.m_args);
}
public static function schedule_call(the_this:*, f:Function, interval:int, ...args):Scheduler
{
return new Scheduler(the_this, f, interval, args);
}
}
}
And here's an AS3 FlashDevelop app that uses it ('Main.as'):
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
Scheduler.schedule_call(this, this.test_func_NO_PARAMS, 0);
Scheduler.schedule_call(this, this.test_func_ONE_PARAM, 0, 123);
Scheduler.schedule_call(this, this.test_func_TWO_PARAMS, 0, "HELLO", "WORLD");
}
private function test_func_NO_PARAMS():void
{
trace("No params was called successfully!");
}
private function test_func_ONE_PARAM(some_number:int):void
{
trace("One param was called successfully! 'some_number' = " + some_number);
}
private function test_func_TWO_PARAMS(stringA:String, stringB:String):void
{
trace("Two params was called successfully! 'stringA' = " + stringA + ", 'stringB' = " + stringB);
}
}
}
So as you see in your test-run the first two calls work fine, the one that calls a function that takes no parameters and the one that takes one parameter.
The problem is when I need to pass more than one parameter!
Solving the issue:
Well, I know it'd be solved if I could simply retain the
...args
as is, and pass it on to thethis.m_function.call
call.Another way, maybe is to have some sort of a
foreach
loop which would feed the designated...args
when the time comes, yet again, how would I refer/pass it?
There must be a nice trick here to make it work, you're welcome to sweat with me on this one!
Try changing this line:
this.m_function.call(this.m_the_this, this.m_args);
to this:
this.m_function.apply(this.m_the_this, this.m_args);
apply
passes the parameters to the applied function as a list instead of a single array (the same effect as if you wrote the_function(arg[0],arg[1],arg[N])
).
Edit:
Maybe I'm not understanding your problem, but this simplified sample of your code works fine (I'm not using a Timer and I'm not building any instance but I think the main thing here is how apply works; taking an array of parameters and passing them as a list of variable parameters to the invoked function):
private function arg0():void {
trace("arg0");
}
private function arg1(a:*):void {
trace("arg1");
}
private function arg2(a:*,b:*):void {
trace("arg2");
}
private function arg3(a:*,b:*,c:*):void {
trace("arg3");
}
private function test():void {
schedule_call(this,arg0,10);
schedule_call(this,arg1,10,1);
schedule_call(this,arg2,10,1,2);
schedule_call(this,arg3,10,1,2,3);
}
public function schedule_call(the_this:*, f:Function, interval:int, ...args):void
{
var m_args:Array = args;
f.apply(the_this, m_args);
}
精彩评论