开发者

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:

  1. Well, I know it'd be solved if I could simply retain the ...args as is, and pass it on to the this.m_function.call call.

  2. 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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜