Сохранение памяти

Предисловие

В этой статье я попытаюсь рассказать об всех недостатках програмной генерации кода для файла war3map.j. Как-то раз, открыв этот файл из простой милишки, я мягко говоря был в шоке. Спрашивается что же там такого шокирующего? Ответ прост: в скрипте море необнулённых переменных и гора нехороших вызовов функций. И в этой статье я расскажу как разгрести гору, затопив реку, и получить идеальную равнину.

Массовое поражение

Для уверенности хочу привести самый наглядный пример. Это функция, которая первой попалась мне на глаза:

Code
function CreateBuildingsForPlayer0 takes nothing returns nothing
local player p = Player(0)
local unit u
local integer unitID
local trigger t
local real life

set u = CreateUnit( p, 'hfoo', 576.0, 128.0, 270.000 )
endfunction

Ну так вот здесь масса нехороших моментов.
1) Рассмотрим локальные переменные. В данном триггере они совсем не нужны!
2) Мы можем спокойно воспользоваться напрямую функцией Player().
3) Остальные просто не используются. Плюс ко всему переменная не обнуляется.
4) Так же мы можем создать юнита простым действием CreateUnit().
Таким образом мы получаем следующее:

Code
function [b]CreateBuildingsForPlayer0[/b] takes nothing returns nothing
call CreateUnit( Player(0), 'hfoo', 576.0, 128.0, 270.000 )
endfunction

Теперь посчитаем во скользо раз я сократил использование памяти и места на винте)

Высокая оптимальность

Вышесказанный вариант тоже является не совсем правильным. Ведь можно напрямую заменить вызов "CreateBuildingsForPlayer0()" на то, что она вызывает. Впрочем это только потому что создаётся лишь один юнит для красного игрока.
Но сейчас не об этом. Уделим внимание глобалкам и присвоению к ним значений. В каждом скрипте есть функция инициализации карты. Называется она main(). И в этой функции записан вызов "InitGlobals()". Стираем не задумываясь! Эта функция совершает присваивание значений глобальным переменным. Затем обязательно нужно будет найти эту функцию и стереть её из кода.

Рассмотрим раздел globals.
Там происходит объявление переменный и присваивание им нулевого значения. Дла дочерних от handle присваивается null, для строки "Пустая строка" (aka ""), для real и integer 0, для boolean false. И только переменных от типа code не объявляется там. Уже надоевшая функция InitGlobals() присваивала им уже пользовательские значения, вообще для отдельных типов значения по умолчанию задаются именно там) Например, диалоги, группы и ещё некоторые типы. Удалив InitGlobals(), нужно присвоить значения переменным прямо в блоке "globals"

Функции

Так же желательно снести все функции, вызывающиеся "InitCustomTriggers()" в "main()". Если вам важнее быстродействие, чем красота кода, то и вызовы функций с префиксом имени InitTrig_ надо снести в main(). Вообще так надо проделать со всеми функциями инициализации. Половина всего будет найдена вами в файле скрипта, некоторое же всё таки придётся искать в Blizzard.j. Такой функцией является InitBlizzard(), она делает несколько вызовов, которые в свою очередь тоже дела.т по несколько других вызовов. Если конечные вызовы снести в main(), то скорость загрузки карты заметно возрастёт, как и размер скрипта =\
В имени функций нужно сохранять точнейший порядок, поэтому либо используйте неудобное копировать/вставить, либо сократить имена функций О.о

Другие беды

Иногда бывает что генерируется переменная из простого, создаваемого функцией, юнита или другого объекта, причём эта переменная в последствии не используется. Такое надо удалять из блока "globals". Скажу что после оптимизации скрипта карту лучше не открывать. Либо не откроется, либо просто перестроит код в изначальное положение... Замечу что тула векса впринципе делает только маленькую часть того, что можно сделать ручками. Если немного подумать, то можно состроить алгоритм суперзащиты карты лишь только за счёт war3map.j.

Приятной вам практики)