Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Глобальный Enter Frame (http://www.flasher.ru/forum/showthread.php?t=194112)

Sintesis 08.02.2013 02:19

Глобальный Enter Frame
 
Как лучше реализовать ентерфрейм, чтоб была возможность добавлять функции в которых есть анимация. Сделал так, но мне кажется это медленно:
Код AS3:

package resources{
        import flash.events.Event;
 
        /**
        * ...
        * @author Sintesis
        */

        public class MyTween{
 
                private var _myFuncVector:Vector.<Function>;
                private var _funcCount:int = 0;
                private var _oldFuncCount:int = 0;
 
                public function MyTween(){
                        _myFuncVector = new Vector.<Function>;
                }
 
                public function startTimer():void {
                        Dispatcher._stage.addEventListener(Event.ENTER_FRAME, timerListener);
                }
 
                public function stopTimer():void {
                        Dispatcher._stage.removeEventListener(Event.ENTER_FRAME, timerListener);
                }
 
                public function setFunc(func:Function):void {
                        _myFuncVector.push(func);
                        _funcCount = _myFuncVector.length;
                    _oldFuncCount = _myFuncVector.length;
                }
 
                private function timerListener(event:Event):void {
//не нравится, что каждый кадр перебираю вектор _myFuncVector
                        while (_funcCount--) {
                                _myFuncVector[_funcCount]();
                        }
                        _funcCount = _oldFuncCount;
                }
        }
}

может есть лучшие решения?

-De- 08.02.2013 02:26

Да вроде нормально. Именно перебор сильно не улучшить. Можно for .. in попробовать, можно сделать список вместо вектора (как бонус вставка/удаление быстрее), но до 1000 длины вектора нереально разницу увидеть. Можно написать функцию удаления - это даст повод подумать над Dictionary вместо или вместе с вектором.

Sintesis 08.02.2013 02:35

Цитата:

Сообщение от -De- (Сообщение 1119677)
Именно перебор сильно не улучшить.

Печально. Но может есть какой-то другой подход добавления/удаления в анимацию, без создания таймеров или ентерфрейма каждому отдельному анимируемому объекту?

Frost47rus 08.02.2013 12:02

каждую анимацию имплементить от интерфейса с function Tick():void;, например.
создание анимации проводить в какой-нибудь AnimationSystem, которая будет получать игровой Tick от игрового мира World, скажем. Собирать анимации в Vector.<Animation>();
Код AS3:

public function Tick(dt:Number):void{
 var i:int;
 for (i=0; i< animations.length; i++){
  animations[i].Tick();
 }
}


Sintesis 08.02.2013 17:33

А вот это всё каждый фрейм происходит?
Код AS3:

public function Tick(dt:Number):void{
 var i:int;
 for (i=0; i< animations.length; i++){
  animations[i].Tick();
 }
}


expl 08.02.2013 17:49

Цитата:

//не нравится, что каждый кадр перебираю вектор _myFuncVector
Вы в каждом кадре должны вызвать все функции (так же?)
А сам перебор (сравнение i <, инкремент i++, обращение к элементу массива) - ни как не больше времени и памяти жрёт чем непосредственный вызов всех функции Tick()
Т.е. это не место для оптимизаций.

Где место для оптимизаций? Это удаление функции могло бы быть, но у Вас просто нет такого метода :)

Цитата:

while (_funcCount--) {
_myFuncVector[_funcCount]();
}
_funcCount = _oldFuncCount;
Зачем так сложно? _Если_ не предпологается удаление функций, то не нужно поля использовать (да и если бы предполагалось - можно было бы переменными обойтись):
Код AS3:

for each (var fun:Function in _myFuncVector)
{
    fun();
}


Sintesis 08.02.2013 18:45

Цитата:

Сообщение от expl (Сообщение 1119774)
Вы в каждом кадре должны вызвать все функции (так же?)

Зачем так сложно?
Код AS3:

for each (var fun:Function in _myFuncVector)
{
    fun();
}


Да! Спасибо expl, совсем забыл про for each так красивей). Удаление функций тоже есть, просто не писал сюда, оно нормально работает. Думал, может, связанные списки делать, но оказывается это не такой уж и напряг когда цикл в энтерфрейме постоянно перебирает вектор с функциями.

Добавлено через 8 минут
Интересно, что быстрей такой подход как Frost47rus написал где будут через интерфейс дёргаться методы или как у меня с передачей всего метода в ентерфрейм или это совсем не важно что так, что так?

iflamberg 08.02.2013 19:07

Разве for..in не намного медленней, чем другие циклы?

Sintesis 08.02.2013 19:52

так, нужно будет сделать класс который измеряет скорость работы отдельных кусков кода(но это уже другая история), действительно for each ведь медленее while, но используя for each в данном случае стают не нужными private var _funcCount:int = 0; private var _oldFuncCount:int = 0; и все манипуляции с ними отпадают.
В общем-то почти всё что хотел - узнал, так как по любому прийдётся перебирать вектор с анимациями каждый кадр то моё решение удовлетворяет.

expl 08.02.2013 21:11

Цитата:

Удаление функций тоже есть, просто не писал сюда, оно нормально работает
Тогда с предложенным мной наивным foreach можно огрести,
если удаление функции происходит внутри другой или той же вызываемой функции (хотя предыдущий подход тоже не спасёт ситуацию)

Цитата:

действительно for each ведь медленее while
Глупости, смотря для чего и как
Тут народ пытался определить что же лучше (с переменным успехом): http://stackoverflow.com/questions/1...ce-in-as3-flex
Цитата:

for each в данном случае стают не нужными private var _funcCount:int = 0; private var _oldFuncCount:int = 0;
Да зачем вообще здесь поля эти использовать, да ещё 2 штуки.
Пользуйтесь переменными.

Вот пример без foreach, если религия не позволяет:
Код AS3:

var length:int = _myFuncVector.length;
for (var i:int = 0; i < length; i++)
{
    _myFuncVector[i]();
}

Или так (если коллеги за читабельность по рукам не надают и можно в обратном порядке функции выполнять):
Код AS3:

for (var i:int = _myFuncVector.length; i-- > 0;)
{
    _myFuncVector[i]();
}



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

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