Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   AS2 Вызов функции по ссылке с нейзвестным количеством парамертов (http://www.flasher.ru/forum/showthread.php?t=83795)

Бармалей 16.08.2006 13:20

AS2 Вызов функции по ссылке с нейзвестным количеством парамертов
 
Столкнулся с необходимостью синхронизировать выполнение кода с показом анимации. Т. е., предположим, что, после показа некоторой анимации, мне нужно выполнить заранее нейзвестную динамически составляющуюся последовательность действий. Для этих целей начал писать класс ConsistencyManager, который и должен обслуживать эту последовательность.

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

Метод nextAction() производит вызов следующего действия. Его-то и нужно доработать. Если следующее действие - просто функция без параметров, то он выполняется без проблемм. Если функция с заданными параметрами, то я просто не представляю как реализовать вызов функции. Хотя прочитал уже все доки про классы Function и arguments.

Как вы понимаете этот вопрос ориентирован на людей, хорошо разбирающихся во внутренних механизмах ActionScript, поэтому прошу попусту не коментить. Однако, если у кого-то есть готовые решения подобного вопроса или же предположения как реализовать класс, буду рад любым коментариям или ссылкам.

А сейчас отправляю вас непосредственно к коду класса:

Код:

/**
 * ConsistencyManager, МенеджерПоследовательностей. Версия 1.
 * Отвечает за выполнение последовательности действий. Будет полезен,
 * если вам необходимо, чтобы некоторые визуальные или невизуальные действия
 * выполнялись последовательно и были разделены друг от друга во времени.
 * Реализация класса требует, чтобы вызов следующего действия был доступен из любой
 * точки ролика. Кроме того, так как Flash не поддерживает многозадачность
 * и все события выполняются последовательно, необходимо, чтобы в программе создавался
 * только один экземпляр ConsistencyManager. Именно поэтому класс реализован
 * по принципу паттерна Singleton.
 *
 * Использование:
 *
 * // Импортируем класс.
 * import com.yarovoy.util.time.ConsistencyManager;
 *
 * // Сохраняем ссылку на единственный экземпляр класса.
 * var cm:ConsistencyManager = ConsistencyManager.getInstance();
 *
 * // Заполняем класс последовательностями.
 * cm.pushAction(myFunc1); // Функция вызовится без параметров.
 * cm.pushAction([myFunc2, par1, par2, parN]); // функция вызовится с параметрами par1, par1, parN
 *
 * // Делаем проверку на наличие последовательностей в стеке
 * // и вызываем следующее действие.
 * while(cm.hasActions()){
 *                cm.nextAction();
 * }
 *
 * Новые версии на: http://www.yarovoy.com/classes/as2/.
 *
 * @author Yury Yarovoy
 * @version 1.0.0
 */

class com.yarovoy.util.time.ConsistencyManager {
       
        // ------------------------------------------------------------------------------------------------
        // Private props
        // ------------------------------------------------------------------------------------------------
       
        private var $actions:Array;
       
        private static var $instance:ConsistencyManager = null;
       
        // ------------------------------------------------------------------------------------------------
        // Getters and setters
        // ------------------------------------------------------------------------------------------------
       
        /**
        * Возвращает ссылку на единственный экземпляр класса.
        *
        * @return        $instance                - ссылка на единственный экземпляр класса.
        */
        public static function getInstance():ConsistencyManager {
                if(ConsistencyManager.$instance == null){
                        ConsistencyManager.$instance = new ConsistencyManager();
                }
                return ConsistencyManager.$instance;
        }
       
        // ------------------------------------------------------------------------------------------------
        // Constructor
        // ------------------------------------------------------------------------------------------------
       
        private function ConsistencyManager() {
                $actions = new Array();
        }
       
        // ------------------------------------------------------------------------------------------------
        // Public methods
        // ------------------------------------------------------------------------------------------------
       
        /**
        * Добавляет новое действие в стек выполняемых действий.
        *
        * @param        action                - ссылка на функцию или массив ссылок на функции.
        * @return        success                - успешность выпонения операции добавления действий.
        */
        public function pushAction(action:Object):Boolean {
               
                // Флаг показывающий за успешность выполнения операции.
                var success:Boolean = false;
               
                // Если в качестве параметра поступила ссылка на функцию,
                // добавляем ее в стек выполняемых действий.
                if(action instanceof Function){
                        $actions.push(action);
                        success = true;
                }
               
                // Если в качестве параметра поступил массив,
                // добавляем его элементы в стек выполняемых действий.
                if(action instanceof Array){
                        var len:Number = action["length"];
                        if(action[0] instanceof Function){
                                $actions.push(action);
                                success = true;
                        }
                }
               
                // Возвращаем успешность выполнения метода.
                return success;
        }
       
        /**
        * Выполняет следующее действие в стеке действий.
        *
        * @return        success                - успешность выполнения следующего действия.
        */
        public function nextAction():Boolean {
                if($actions.length > 0){
                        if($actions[0] instanceof Function){
                                // Если первый элемент - ссылка на функцию,
                                // то просто выполняем ее.
                                $actions.shift()();
                                return true;
                        }else if($actions[0] instanceof Function){
                                // Если первый элемент - массив, в качестве
                                // первого элемента которого выступает функция,
                                // вызываем функцию, передавая ей в качестве параметров
                                // остальные элементы.
                               
                                // КАК ЭТО РЕАЛИЗОВАТЬ Я НЕ ЗНАЮ.
                                return true;
                        }
                       
                }else{
                        return false;
                }
        }
       
        /**
        * Возвращает число - количество оставшихся действий
        * в последовательности действий.
        *
        * @return        length                - число невыполненных действий в стеке.
        */
        public function hasActions():Number {
                return $actions.length;
        }
}


DarkLight 16.08.2006 13:49

Может так:
Код:

var $func:Function = $actions.shift();
$func.apply(null, $actions);


Бармалей 16.08.2006 14:10

Да уж. Вот что называется "просмотрел все доки про Function"... Спасибо, вот доработанный метод nextAction:

Код:

/**
        * Выполняет следующее действие в стеке действий.
        *
        * @return        success                - успешность выполнения следующего действия.
        */
        public function nextAction():Boolean {
                if($actions.length > 0){
                        if($actions[0] instanceof Function){
                                // Если первый элемент - ссылка на функцию,
                                // то просто выполняем ее.
                                $actions.shift()();
                                return true;
                        }else if($actions[0][0] instanceof Function){
                                // Если первый элемент - массив, в качестве
                                // первого элемента которого выступает функция,
                                // вызываем функцию, передавая ей в качестве параметров
                                // остальные элементы.
                                $actions[0][0].apply(null, $actions[0].slice(1));
                                $actions.shift();
                                return true;
                        }
                       
                }else{
                        return false;
                }
        }


Бармалей 16.08.2006 14:13

Можно еще оптимизировать строчки:

Код:

$actions[0][0].apply(null, $actions[0].slice(1));
$actions.shift();

в одну:

Код:

$actions.shift()[0].apply(null, $actions[0].slice(1));
Спасибо, еще раз.

Den0k 16.08.2006 14:42

может я вник в тему поверхностно, но вспоминается

http://potapenko.com/rus/articles/conveyor.htm

по идее пригодится.

Бармалей 16.08.2006 16:30

Цитата:

Сообщение от Den0k
может я вник в тему поверхностно, но вспоминается

http://potapenko.com/rus/articles/conveyor.htm

по идее пригодится.

Ух-ты, Женя там целую дискусию на эту тему развил. Чтож буду перенимать опыт старшего поколения.

Бармалей 16.08.2006 16:36

Принципы работы CM и конвеера похожи. Хотя в Конвеере еще можно ставить паузу между вызовами методов. В текущем проекте такой функционал никчему.

Спасибо за ссылку на статью.


Часовой пояс GMT +4, время: 20:41.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.