Categories: Уроки

7 способов сделать таймер в DevelNext и JPHP

Таймеры штука интересная и очень полезная в разработке. Если вы работали только с серверным php, то скорее всего, таймеры вам были не очень-то нужны, максимум, вы использовали cron и больше ничего. В это статье мы рассмотрим 10 способов реализовать таймер в develnext и jphp, расскажем про плюсы и минусы каждого.

1 способ. Примитивный.

Используйте потоки + sleep():

// если надо
// use php\lang\Thread; или use std;

$thread = new Thread(function () {
  while(true) {
    echo "Timer\n"; // код таймера
    sleep(1); // ждем 1 секунду
  }
});

Все что мы делаем – создаем поток, а внутри бесконечный цикл, в каждой итерации ставим паузу на 1 секунду. Вот и весь таймер. Это – самый простой и в то же время, самый не оптимальный таймер на develnext и jphp.

Не делайте так НИКОГДА, читайте ниже, как лучше!

 

2 способ. Класс Timer.

Это встроенный класс в стандартную библиотеку jphp, он доступен и в develnext. Его смело можно использовать, он очень удобен. Класс умеет создавать одноразовые таймеры и таймеры, которые выполняются каждые несколько секунд, часов и т.д. А вот и пример:

// если нужно
// use std; или use php\time\Timer;

$timer = Timer::every(1000, function () {
  // выполняется код каждую секунду.
});

Таймер умеет принимать в качестве периода не только миллисекунды, но и сложные значения, например:

Timer::every('30s', function () { ... }); // каждые 30 секунд.
Timer::every('1m 30s', function () { ... }); // каждые 1.5 минуты
Timer::every('1h 30m', function () { ... }); // каждые полтора часа
Timer::every('1.5h', function () { ... }); // также, каждые полтора часа.

В периодах можно указывать:

  1. s – секунды
  2. m – минуты
  3. h – часы
  4. без буквы – млсек.

Их можно указывать в дробном виде, как в примере выше, комбинировать с несколькими и т.п.

Таймер выполняет все в одном потоке, поэтому если вам необходимо, чтобы код выполнился в отдельном потоке, создавайте поток сами – вручную.

Если вы используете DevelNext и в таймере пытаетесь менять GUI, визуальные компоненты, показывать диалоги и все в таком духе, то используйте функцию uiLater(), для того, чтобы не было ошибок (см. подробнее здесь).

Такие таймеры легко останавливать:

$timer = Timer::every('1s', function () { ... });

// где-нибудь в коде, отменить таймер.
$timer->cancel();

Либо можно использовать аргумент функции таймера:

Timer::every('1s', function (Timer $timer) {
    if (/* какое-то условие */) {
        $timer->cancel(); // остановить таймер.
    }
});

У класса также имеется метод для одиночного срабатывания, как setTimeout() из JavaScript:

Timer::after('20s', function () {
   // выполнить 1 раз через 20 секунд.
});

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

 

3 способ. Класс TimerScript.

Этот класс доступен только если вы разрабатываете в DevelNext. По большому счету, этот класс является модульным компонентом и доступен в редакторе модулей. Создать его в коде очень просто и апи у него легкое:

// если нужно
// use frameworkd; или use script\TimerScript;

$timer = new TimerScript();
$timer->interval = 2500; // 2.5 секунды
$timer->repeatable = true; // повторять да/нет
$timer->on('action', function () {
    // событие таймера
});

// запускаем таймер
$timer->start();

Кстати, TimerScript поддерживает в качестве интервала и сложные выражения, как таймер из 2 пункта. Например:

$timer->interval = '2.5s';
$timer->interval = '1m 30s';

Такие значения можно вводить и в самой среде, в редакторе модулей для таймеров.

 

4 способ. Простой.

В самом DevelNext-e есть 2 функции, которые умеют создавать паузу в выполнении кода, аналог sleep().

wait(2500); // ждать 2.5 секунды, но это еще не таймер.

// одноразовый таймер.
waitAsync(2500, function () {
    // код выполнится через 2.5 секунды.
});

Недостаток этого таймера в том, что он может выполнится только один раз, как setTimeout() из JavaScript. Однако он очень удобен тем, что выполняется в UI потоке и синтаксис у него простой и короткий.

 

5 способ. Для Анимации.

Этот таймер является частью JavaFX и DevelNext, он нужен специально для создания плавных анимаций. У этого таймера нет понятия интервала, т.к. он срабатывает в каждый кадр отрисовки, т.е. 1/60 секунды.

$timer = new UXAnimationTimer(function () {
   // код таймера, можно работать с UI.
});
$timer->start(); // запускаем таймер.
$timer->stop(); // останавливаем таймер.

С помощью этого таймера написан класс для анимаций Animation (читайте здесь).

Если вы меняете UI объекты, чтобы создать какую-то анимацию с цветом, с передвижением и т.п., используйте этот таймер. Если не знаете как, посмотрите исходники класса Animation здесь.

 

6 способ. Одно-поточный таймер.

Таймер timer\AccurateTimer основан на классе из предыдущего пункта, однако он добавляет опцию интервала и повторяемости, как, например, TimerScript. Его также можно использовать для анимаций, для UI. Выполняется он в потоке UI, поэтому сильно-нагруженные операции в нем делать не стоит, иначе ваша программа будет лагать и тормозить.

$timer = AccurateTimer(2500, function () {
    // выполнение таймер в потоке UI.
});
$timer->start(); // запускаем таймер.

Реализация этого таймера простая, все в одном потоке, поэтому не стоит создавать более 1000 таких таймеров одновременно. Лучше попробуйте таймер из пункта 2 или 3.

 

7 способ. Таймер-триггер.

В develnext можно запустить таймер-триггер, который сработает тогда, когда сработает определенное условие. Это делается с помощью метода Timer::executeWhile()

TimerScript::executeWhile(function () {
    // если вернуть здесь true, то событие ниже выполнится.
    // return true/false;
}, function () {
    // код таймера-триггера.
});

Можно использовать например в играх.

 

Идея для проекта

На этом все, надеюсь вам было интересно! Таймеры очень интересная штука, их можно использовать в играх и во многих других программах. Попробуйте на основе этой статьи создать свою программу “Будильник”, где можно было бы указывать время срабатывания, указывать мелодию. В этой программе можно было бы использовать компонент “Трей-иконка”, чтобы будильник работал постоянно и звонил когда нужно. В общем, это – еще одна идея для вашего проекта.

Дмитрий Зайцев

View Comments

Share
Published by
Дмитрий Зайцев

Recent Posts

Изолированные окружения в JPHP

После статьи про скрытые возможности DevelNext, многим стал интересен специальный класс Environment, который позволяет создавать изолированные или частично изолированные окружения…

7 лет ago

Кто он, автор DevelNext и DevelStudio?

Возможно, писать о себе в третьем лице не очень хорошо, но лучше заголовка для этой статьи я не придумал. Сегодня…

7 лет ago

Топ 7. Скрытые возможности DevelNext

Итак, в этой статье мы расскажем о 7 скрытых возможностях DevelNext. 1. Копирование компонентов в txt Вы когда-нибудь пробовали скопировать…

7 лет ago

Осенний DevelNext 16.7.0 уже доступен!

Представляем вам осеннюю версию DevelNext 16.7.0, с поддержкой возможностей из PHP 7, менеджером скинов и новыми компонентами в стиле Material…

7 лет ago

Встречайте летний DevelNext 16.6.0

Сегодня у нас отличные новости, встречайте новый летний DevelNext 16.6.0! Мы постарались сделать его еще более дружелюбным для новичков, постарались…

7 лет ago

Встречайте DevelNext 16.5.2

Сегодня у нас отличные новости, встречайте новый DevelNext 16.5.2! DevelNext это теперь по праву целая студия, а не просто конструктор,…

8 лет ago