Пользовательский ActionScript 3 «Позвонил позже» почти работает, эксперт хотел! - PullRequest
0 голосов
/ 15 февраля 2011

У меня есть этот класс ('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:TimerEvent):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);
        }
    }
}

А вот приложение AS3 FlashDevelop, которое его использует ('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);
        }
    }
}

Итак, как вы видите в своем тестовом прогоне , первые два вызова работают нормально , тот, который вызывает функцию, не принимает параметров , и тот, который принимает один параметр .

Проблема в том, что мне нужно передать более одного параметра!

Решение проблемы:

  1. Ну, я знаю, что этобыть решенным, если бы я мог просто сохранить ...args как есть и передать его на this.m_function.call вызов.

  2. Другой способ, может быть, это иметькакая-то петля foreach, которая будет кормить назначенный ...args, когда придет время, и еще раз, как бы я сослался / передал его?

Должен быть хороший трюкздесь, чтобы это сработало, вы можете попотеть со мной на этом!

1 Ответ

1 голос
/ 15 февраля 2011

Попробуйте изменить эту строку:

this.m_function.call(this.m_the_this, this.m_args);

к этому:

this.m_function.apply(this.m_the_this, this.m_args);

apply передает параметры в прикладную функцию в виде списка вместо одного массива (тот же эффект, как если бы вы написали the_function(arg[0],arg[1],arg[N])).

Edit:

Может быть, я не понимаю вашу проблему, но этот упрощенный пример вашего кода работает нормально (я не использую таймер и не создаю ни одного экземпляра, но я думаю, что главное здесь - как работает применение; массив параметров и передача их в виде списка переменных параметров в вызываемую функцию):

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