# Вопрос по таймеру
Antokolos(syscall,12) — All
2017-06-03 08:13:40


Возник такой вопрос.
К примеру, у нас есть таймер, установленный по timer:set(5)
и вот такой код:

game.timer = stead.hook(game.timer, function(f, s, cmd, ...)
if vn.processing then
return;
end
if not vn.on then
return f(s, cmd, ...);
end
vn.processing = true;
local result = code_that_can_take_more_than_5ms_to_complete();
vn.processing = false;
return result;
end)

Собственно, вопрос: нужно ли вообще это извращение с vn.processing? Или в таймере всё синхронно и новый вызов гарантированно не произойдёт, пока старый не завершён?
А если там реально всё асинхронно, и таймер стреляет с той частотой, что ему указали, будет ли такой код потокобезопасным (в Java я бы точно сказал, что нет, vn.processing нельзя модифицировать без синхронизации, мьютекса итп.)
Ну и вообще, как разрулить такую ситуацию? В идеале хочется, чтобы новый вызов кода по таймеру НЕ происходил, пока старый не отработал.

# Re: Вопрос по таймеру
Antokolos(syscall,12) — Antokolos
2017-06-03 08:17:24


Antokolos> Возник такой вопрос.
P.S.: Вопрос по STEAD2, но, думаю, в STEAD3 всё примерно так же.

# Re: Вопрос по таймеру
Peter(syscall,1) — Antokolos
2017-06-03 08:27:55


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

P.S. для вставки кода юзай такую запись

ПРИВЕТ МОНОШИРИЙНЫЙ МИР

# Re: Вопрос по таймеру
Antokolos(syscall,12) — Peter
2017-06-03 08:34:24


Peter> Таймер всегда синхронный -- он не прерывает команду инстеда, он обрабатывается между командами и сам может генерировать команду. Насколько я помню -- game.timer это уже производное событие -- которое обрабатывается как обычная команда своим чередом.
Ясно, спасибо! Ну, тогда код упростится :)

# Re: Вопрос по таймеру
Kerbal(syscall,8) — Antokolos
2017-06-03 11:09:56


В таймере новый вызов происходит, емнип, через timer:set(n) после отработки старого вызова. Т.е. отработал вызов, ждёт n, новый вызов. Во время n происходят другие события.

# Re: Вопрос по таймеру
Antokolos(syscall,12) — Kerbal
2017-06-03 14:34:10


Kerbal> В таймере новый вызов происходит, емнип, через timer:set(n) после отработки старого вызова. Т.е. отработал вызов, ждёт n, новый вызов. Во время n происходят другие события.
Вообще, изначально у меня было так:
в самом начале длительного метода timer:stop(), чтобы точно уже не пришёл новый тик.
в самом конце длительного метода timer:set(n), чтобы вновь запустить таймер.
Однако, это по каким-то причинам иногда стало приводить к тормозам (сейчас делаю Варвара под Андроид, и на слабом планшете это очень чувствуется).
Была даже гипотеза, что какие-то проблемы с освобождением памяти, но нет, это не подтвердилось.
Сейчас у меня timer:set(n) только в функции init(), timer:stop() вообще не используется, т.е. таймер бесконечно молотит.
В результате становится возможным реализовать, к примеру, onmouseover для спрайта.
Единственно вот беспокоил вопрос, не может ли так выйти, что таймер запустится снова, не дождавшись отработки предыдущего вызова.

# Re: Вопрос по таймеру
kerber(syscall,2) — Antokolos
2017-06-03 14:58:42


onmouseover для спрайта хотеть! Покажешь потом как сделал? Я, когда делал панорамы и дёргал функцию отрисовки в таймере, обрамлял рассчёт каждой линии рендера вызовом stead.busy() чтобы не залипал курсор. Этот же трюк использовал в шахматах. Там тоже на планшете медленно ходы обдумывает. Посмотри, может пригодится где-нить.
https://yadi.sk/d/pmvrIvW5xiXbZ
http://instead-games.ru/game.php?ID=225

# Re: Вопрос по таймеру
Antokolos(syscall,12) — kerber
2017-06-03 18:23:04


kerber> onmouseover для спрайта хотеть! Покажешь потом как сделал? Я, когда делал панорамы и дёргал функцию отрисовки в таймере, обрамлял рассчёт каждой линии рендера вызовом stead.busy() чтобы не залипал курсор. Этот же трюк использовал в шахматах. Там тоже на планшете медленно ходы обдумывает. Посмотри, может пригодится где-нить.
kerber> https://yadi.sk/d/pmvrIvW5xiXbZ
kerber> http://instead-games.ru/game.php?ID=225

Спасибо, погляжу!
Ну, а по поводу onmouseover идея простая. Постоянный таймер + stead.mouse_pos() даёт координаты, и есть два спрайта, обычный и при наведённой мыши. С помощью модуля vn в нужный момент показывается нужный спрайт.
Более подробно можно в Варваре посмотреть, только там страшный код, конечно :)
Ну или вот есть более простой пример:
https://yadi.sk/d/bj-eEC403DszoC
Только модуль там староват, я его постоянно обрабатываю напильником.
Последние версии смотреть здесь:
https://github.com/Antokolos/NLB/blob/master/NLBL/src/main/resources/vnstead/modules/vn.lua

# Re: Вопрос по таймеру
Peter(syscall,1) — Antokolos
2017-06-03 18:28:14


Очень мне хочется, чтоб вы пощупали новые спрайты. В stead3. Ибо там они автоматом освобождаются. И мало кто их тестил. ;) У самого пока руки никак не дойдут до творчества...

# Re: Вопрос по таймеру
Antokolos(syscall,12) — Peter
2017-06-05 04:35:34


Peter> Очень мне хочется, чтоб вы пощупали новые спрайты. В stead3. Ибо там они автоматом освобождаются. И мало кто их тестил. ;) У самого пока руки никак не дойдут до творчества...
Пощупаем-пощупаем :) В планах перевод конструктора на stead3, заодно и генерируемый код надо причесать.
А кстати, sprite.free() осталась, но теперь ничего не делает?

# Re: Вопрос по таймеру
Peter(syscall,1) — Antokolos
2017-06-05 06:08:58


Ну она работает, но теперь она вызывается автоматом при разрушении переменной. Так что вроде как не нужна. Я честно говоря не знал, что она осталась. :)