Сигналы и таймауты - TrueCat17/Ren-Engine GitHub Wiki
С помощью сигналов можно реагировать на определённые события (и/или запускать их самостоятельно).
Таймауты позволяют вызвать какую-либо функцию через определённое время.
Интервалы позволяют вызывать функцию через определённые промежутки времени.
Всё это работает на уровне питона, т. е. должно быть либо в блоке python
, либо в команде $
.
Добавить реакцию на сигнал "event" - выполнить функцию function
:
signals.add("event", function, priority = 0, times = -1)
Если на одно событие повешено несколько функций, то сначала выполнится та, что с меньшим приоритетом.
Если 2 функции имеют одинаковый приоритет, то первой будет первая добавленная.
times
определяет число вызовов, после которого эта функция будет удалена из реакций на данное событие (-1
- никогда не удалять).
Пример:
def my_function(arg = "world"):
out_msg("Hello, %s!" % arg)
signals.add("my_super_event", my_function)
Удалить реакцию на событие "event":
signals.remove("event", function)
Здесь function
- функция, указанная ранее в signals.add
.
Отправить сигнал (вызвать все функции, подписанные на "event"):
signals.send("event", *args, **kwargs)
2 последние аргумента обозначают, что вы можете добавлять какие-угодно аргументы, и они будут переданы вызываемым функциям.
Например: signals.send("my_super_event", "My Super World")
Или даже с именованым параметром: signals.send("my_super_event", arg="another world")
При отправке сигнала все функции, реагирующие на этот сигнал, вызываются сразу же.
Список стандартных сигналов - в конце.
Таймауты и интервалы работают примерно также, как и в JS (javascript
в вашем браузере).
Вызвать function
через time_sec
секунд (может быть нецелым числом):
my_id = set_timeout(function, time_sec)
Результат - идентификатор таймаута (его номер), через который его можно отменить (и это единственный способ сделать это).
Отменить вышеуказанную операцию:
clear_timeout(my_id)
Если вызвать эту функцию несколько раз для одного и того же идентификатора, то это не будет считаться ошибкой.
Интервалы очень похожи на таймауты, но указанная функция вызывается не 1 раз, а постоянно через указанные промежутки времени:
my_id = set_interval(function, time_sec)
Отмена:
clear_interval(my_id)
Вместо функций могут приниматься вызываемые (callable
) объекты, в том числе такие как Function
, AddVariable
, SetDict
и т. д.
Однако следует помнить, что все эти функции должны где-то храниться, а значит и уметь сохраняться и восстанавливаться с помощью pickle
.
Причём проверка на это занимает какое-то время, так что делать это по тысяче раз за кадр - плохая идея.
Впрочем, проверку можно временно отключить, вызвав
signals.set_check_picklable(False)
Тогда после включения (True
вместо False
в примере выше)
будут проверены все новые объекты сразу, что будет в десятки раз быстрее.
Функции таймаутов никогда не выполнятся сразу же - только в следующем кадре, даже если указано выполнить их через 0
секунд.
Таймауты и интервалы реализованы через сигналы, конкретно - через "enter_frame".
Поэтому их точность зависит от текущего FPS (кол-ва кадров в секунду).
При максимальном FPS (60
) можно рассчитывать на максимальную точность в 16.7
милисекунды (если не будет зависаний по каким-либо причинам).
Таким образом, нельзя рассчитывать на то, что нужные функции будут вызваны милисекунда в милисекунду (или даже в нужный десяток милисекунд). Также интервал будет вызван между 2 соседними кадрами не более одного раза.
Непонятно зачем, но если вдруг есть реальная причина, то можно создать собственный экземпляр сигналов,
полностью независимый от стандартного: my_signals = Signals()
Разумеется, при отправке событий в стандартные сигналы, ваши не будут их получать (на то он и полностью независимый).
Общие:
-
"enter_frame"
- "вход" в кадр (перед отрисовкой скринов), -
"exit_frame"
- "выход" из кадра (после отрисовки всех скринов), -
"show_screen"
- на экран добавлен какой-то скрин (функция должна принимать 1 аргумент - название скрина), -
"hide_screen"
- с экрана был скрыт какой-то скрин (функция должна принимать 1 аргумент - название скрина), -
"resized_stage"
- размер окна был изменён (см. функциюget_stage_size
).
РПГ-часть:
-
"rpg-location"
- игрок перешёл из одной локации в другую (см. переменныеcur_location
иcur_location_name
), -
"rpg-place"
- игрок вошёл в определённое место на локации (см.cur_place
иcur_place_name
), -
"rpg-no_exit"
- игрок попытался перейти туда, куда у него нет доступа (см. систему запретов в РПГ), -
"rpg-stand_up"
- игрок встал, -
"rpg-sit_down"
- игрок сел, -
"rpg-action"
- нажата "кнопка действия".
Инвентарь РПГ-части (функция должна принимать 1 аргумент - название объекта):
-
"inventory-remove"
- выбрасывание предмета из инвентаря, -
"inventory-use"
- использование предмета в инвентаре, -
"inventory-take"
- взятие предмета в инвентарь.
Прочее:
-
"time"
- изменено время суток (функция должна принимать название нового времени суток), -
"language"
- был установлен язык игры (см. Система переводов).