Понимаем корутины в Lua
Coroutines (сопрограммы) позволяют разбивать громоздкие задачи на части, чтобы те не "вешали" процесс.
Понимание работы
Допустим, у вас есть тяжелый цикл, который выполняется целую секунду. Мы берем этот цикл, засовываем в корутину и после каждой итерации делаем .yield
. Теперь один шаг этого цикла будет выполняться за один тик.
Yield это что-то вроде промежуточного return. Возвращает любые данные посреди задачи и ставит ее на "паузу" до следующего обращения через coroutine.resume
. После resume задача продолжится с места yield. Самих yield в задаче может быть несколько и наглядно это видно со статейки на моем любимом сайте о Lua и еще лучше вот тут.
Корутины не ускоряют работу ваших функций. Они "размазывают" их и выполняют шагами. Словно это повторяющийся таймер
Примеры использования
- Есть 100 игроков и каждому нужно просчитать баланс. Допустим, это тяжелая функция
- У нас скрипт, позволяющий копировать и восстанавливать все объекты на карте. Спавн объекта - затратная функция, объектов может быть 100+
- Обновление большого количества данных на HUD
- Сохранение/чтение данных игроков в БД/файлы
- Разбивка функции загрузки какой-то модели
Догадались, как применить корутины? :) Применений очень много - их можно ткнуть почти везде, где допустимо "фоновое" выполнение задачи, которая состоит из тяжелых функций.
Использование корутин
- Пример с вики для Garry's Mod разработчиков - здесь hook Think что-то вроде
while true do
, который в этой игре намертво вешает сервер. Он срабатывает каждый тик - Обертка для этих корутин. В конце есть примеры, позволяющие выполнять асинхронные функции последовательно (fetch, playfile ...)
Для лучшего понимания
Мой телеграм чатик, с которого взята часть информации на тему корутин, а еще вы тут можете задать свои вопросы. Отсюда пришло понимание и заинтересованность в них. Вот вырезка самого важного