Добавлен ScorpioT1000,
опубликован
Выполнение кода и обращение к данным
Содержание:
А теперь сюрприз! Каждый "поток" в Warcraft 3 имеет лимит операций. Как только выполнится определенное количество операций, варкрафт экстренно завершает поток и даже не сообщает об этом.
Скорее всего, это было сделано, чтобы избежать бесконечных циклов и различных ошибок зависания, допущеных дизайнерами во время написания карт Blizzard.
Подробнее про лимит операций с примерами можно посмотреть в теме XGM Forum - Прерывание потоков & limit op.
Что же теперь делать?!
За простые потоки волноваться не надо, а вот за поток инициализации различных баз данных стоит побеспокоиться и разбить его на новые потоки.
Как создать новый поток
Создать поток можно запуском одноразового таймера с минимальной задержкой, но в редких случаях я предлагаю не заморачиваться с таймерами и использовать функцию ExecuteFunc().
Простой пример:
function test3 takes nothing returns nothing
много кода
endfunction
function test2 takes nothing returns nothing
много кода
call ExecuteFunc("test3")
endfunction
function test1 takes nothing returns nothing
много кода
call ExecuteFunc("test2")
endfunction
// ...
call test1()
Пример с передачей параметров. Внимание: это работает хорошо только в Warcraft 3 и подобных! Как раз из-за того замечания про потоки.
На других, современных языках программирования появится проблема синхронизации данных.
На других, современных языках программирования появится проблема синхронизации данных.
globals
unit test_receive_u = null
int test_receive_i = 0
endglobals
function test_receive takes nothing returns nothing
local unit u = test_receive_u
local int i = test_receive_i
// ваш код, глобальные в нем не используются,
// потому что они могут быть перезаписаны другим потоком
endfunction
function test_send takes nothing returns nothing
local unit u
local int i
// ваш код
// передача аргументов в новый поток и создание нового потока
set test_receive_u = u
set test_receive_i = i
call ExecuteFunc("test_receive")
// Здесь внимание! Даже если вы вызовете TriggerSleepAction,
// новый поток продолжит выполняться. И это хорошо! =)
// ваш код, например, обнуление (но не удаление) локальных юнитов
endfunction
Содержание
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован ScorpioT1000
я могу написать, как я подозреваю сделана система событий внутри игры, но зачем это нужно)
Зачем? За тем же, зачем и это
*юзал, когда писал на варе =)
Отредактирован ScorpioT1000
И ещё, в больших циклах или между большими блоками кода (без вышеуказанных прерывающих функций) можно насильно вставлять TriggerSleepAction(0.01) и тогда выполнение тригера будет временно прерываться и потом снова возобновляться - верно? И это не так же "дорого" для крутых алгоритмов тригера?
Никто до сих пор не создал "прайс-лист" функций, и вряд-ли создаст, т.к. Nobody Cares и лень. Следовательно "стоимость" функций тебе нужно рассчитывать самому.