Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Аналог функции sleep() (http://www.flasher.ru/forum/showthread.php?t=171532)

bav 17.11.2011 21:10

Аналог функции sleep()
 
Здравствуйте, товарищи. Возникла потребность запускать функцию через некоторые промежутки времени, если выполняется некое условие. Приведу код, ибо он яснее словесной тирады:
Код AS3:

function someFunc(event:TimerEvent = null):void {
    // Наличие параметра говорит о том, что функция была вызвана после
    // ожидания, запущенного из этой же функции.
    if (event) event.target.removeEventListener(TimerEvent.TIMER_COMPLETE, someFunc);
    // то есть нормальный вызов функции происходит так: someFunc();
 
    if (<некое условие>) {
        // Если условие истинно, перезапускаем функцию через 1 секунду.
        var timer:Timer = new Timer(1000, 1);
        timer.addEventListener(TimerEvent.TIMER_COMPLETE, someFunc);
        timer.start();
        return;
    }
    // иначе, если <некое условие> оказалось ложным,
    // выполняем дальнейший код функции.
}

Интересует, нет ли здесь утечек памяти (например не нужно ли явно вызывать (event.target as Timer).reset())? То есть, насколько я понимаю, timer живет до тех пор, пока тикает и пока имеет слушателя события. Если так, то первая строчка функции должна сделать его доступным для GC. Также буду благодарен за возможные альтернативные решения.

goodguy 17.11.2011 21:16

Цитата:

Интересует, нет ли здесь утечек памяти
Нет. Утечек тут не будет. Но переменную таймера я бы все-таки сделал на уровне класса

gloomyBrain 17.11.2011 22:39

Хм... А я бы сделал Java-style глобальный таймер и уже на него бы вешал задания по вызову функций. То есть вместо нескольких таймеров будет один ENTER_FRAME, который будет проверять задания в очереди и запускать те из них, чье время пришло. То есть 3 вещи:
1) Реализация паттерна "команда" в виде функции, параметров и даты запуска
2) Очередь из этих команд (связный список, чтобы было удобно хранить в отсортированном виде)
3) Таймер, который бы бегал по очереди и вызывал нужные задания

Psycho Tiger 17.11.2011 22:49

Утечки будут.

gloomyBrain 18.11.2011 00:14

Тигра, а ты тему читал?

expl 18.11.2011 00:29

Цитата:

То есть, насколько я понимаю, timer живет до тех пор, пока тикает и пока имеет слушателя события
По идее, зависит от реализации флешплеера, теоретически его может снести и до того, как закончит тикать - ссылок то на него нет, он только сам на слушатели ссылается. Дисплей-объект, например, рассылающий ENTER_FRAME, может спокойно кануть в лету послав десяток-другой событий.
Однако:
Цитата:

Timer против GC.
Запись от dimarik размещена 21.02.2011 в 21:41
Обновил(-а) dimarik 13.03.2011 в 21:29
Все просто. Пока тикает экземпляр Timer, он не может быть удален сборщиком мусора (Garbage Collector).
Ну а насчёт утечек - если бы до таймера не добирался GC даже при его неактивности - это была бы принципиальная проблема flashplayer'а. Т.е. никаким боком нельзя было бы убрать ненужные таймеры.

С другой стороны, если вы пользуетесь одним таймером, а не создаете по 5 штук в секунду - конечно это будет лучше для производительности - ни память каждый раз выделять не надо, ни gc сильно не напрягается (вопрос только в том, сколько будет жрать чудная система в стиле, предложенном gloomyBrain, зато отписаться можно будет от ставшей ненужной комманды)

P.S. Связный список, он ведь тоже подразумевает создание объекта - узла списка при добавлении элемента, а время поиска произвольного узла перед тем как удалить - явно не быстрее чем в массиве. Можно, конечно навернуть словарик соответствия узел-елемент, тогда время доступа зависеть от количества элементов не будет. Но если элементы повторяются... Скорость доступа замедляется на время вызова функции (тут вам не haXe с inline-ами). Короче без тестов производительности я бы это дело не рискнул встраивать - обошелся бы обычным массивом

P.S.2 Самый эффективный способ - это когда список организуется с самими хранимыми элементами в качестве узлов - тогда создавать ничего не надо - элементы уже созданы, просто на них навешаны prev и next поля. Только теперь элемент не может храниться в 2-х списках одновременно. Плюс т.к. поле не может быть частью переменной - интерфейс элемента списка использовать нельзя - только наследование или узкозаточенный список под конкретные элементы.

gloomyBrain 18.11.2011 00:33

Из того, что bav подписывается на TIMER_COMPLETE, можно сделать вывод - таймер уже не тикает. Следовательно, данная причина утечек не рассматривается. Таймер создается локально, значит и вторая причина - не причина.

Psycho Tiger 18.11.2011 00:42

Фу, минус мне. Не увидел, что tick = 1. Потому что я пил, дура! (с)
У меня вот есть сниппет.
Код AS3:

if (event) (event.currentTarget as IEventDispatcher).removeEventListener(event.type, arguments.callee);

Если отписаться надо - всегда его использую. Даже если поле класса есть и метод вполне себе определен. Потому что время экономит.
Пойду ещё виски налью, что-то я в разнос.

gloomyBrain 18.11.2011 01:19

Цитата:

время поиска произвольного узла перед тем как удалить - явно не быстрее чем в массиве
А зачем тебе может понадобиться произвольный узел? Вероятнее всего, он нужны будут именно по порядку.
Цитата:

Плюс т.к. поле не может быть частью переменной
Вот это я не очень понял.

expl 18.11.2011 01:46

Плюс т.к. поле не может быть частью переменной - это про то что нельзя запихнуть prev и next в интерфейс (а геттерами/сеттерами делать слишком накладно). Впринципе, обычно это не проблема.

Цитата:

А зачем тебе может понадобиться произвольный узел? Вероятнее всего, он нужны будут именно по порядку.
Это только если делать чистую очередь или стек.
Если очередь с приоритетом (например те же комманды по времени сортировать бинарной вставкой) - то потребуется. Или вытащить комманду, которая уже не нужна. В общем примеров достаточно.

Почему, кстати эту задачу Вы предлагаете решать списком?
У него же перед массивом только 2 преимущества - скорость вставки (если знаем соседний узел!) и удаления (если знаем узел!) не зависит от количества элементов. Но чтобы это было действительно быстрее надо ряд условий соблюсти.
(Просто видел реализации вещей в виде списка, мотивация использования списков в которых непонятна,
может есть еще какие-то преимущества, или я не правильно что-то оцениваю?)


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

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