Добавлен , опубликован

Курс JASS + vJASS

Содержание:

Ссылочные типы

Тут нам нужно действительно хорошо разобраться. Мы знаем что примитивные типы содержат в себе какое-то одно значение, например число. Ссылочные типы также содержат в себе одно значение, а именно ссылку на объект в памяти. А объект уже может быть сложной структурой, например юнитом.
Любая переменная не примитивного типа, считается ссылкой.
Объектами считаются не только игровые объекты такие, как юниты, предметы, декорации и т.д. Но и хеш-таблицы, группы юнитов, группы игроков...
Важно понимать, что сама по себе ссылка, не может повлиять на объект. Мы можем менять объект или как-то еще взаимодействовать с ним только с помощью функций, в которые передаем ссылку и другие необходимые значения. Об одном исключении, когда ссылка сама по себе влияет на объект, мы узнаем в уроке по устранении утечек.
Также на один объект может быть много ссылок или не быть их вовсе.
Среди всех ссылочных типов можно выделить три основных: string, handle и code. Все они достойны отдельного урока для изучения. Минимальные знания о string у вас уже есть, а code еще рано изучать. В данном уроке мы рассмотрим тип handle. На его основе были созданы все типы данных кроме string, code, integer, real и boolean.

Handle

Тип handle являться прародителем всех оставшихся 90 ссылочных типов данных. Сам по себе он обозначает всё, у чего есть ИД (уникальный идентификатор). Что такое ИД мы разберем в конце урока, это довольно важный аспект.
Обычно, когда в уроках по jass затрагивают тип handle, обязательно начинают подробно рассказывать о наследовании. Для удобства, я разделю своё объяснение на две части, теоретическую и прикладную. В теоретической просто поймем, как оно там внутри работает. В прикладной разберем то, как вы сможете использовать наследование.

Теоретическая часть

Все типы, созданные на основе какого-то другого типа считаются его наследниками, то есть наследуются от него. Тип на основе которого создаются другие типы, называют родителем. При наследовании они копируют все свойства родителя. Так, например, все потомки handle получат от него поле с ИД. А еще существует тип widget у которого есть позиция и здоровье, все его наследники получат позицию и здоровье (разрушаемые декорации, предметы и юниты).

Прикладная часть

Создавать свои полноценные типы данных у нас не получится, даже несмотря на то, что возможность создавать свои типы существует. Имеет смысл использовать только уже созданные типы данных.
У наследования есть одно свойство, которое будет нам полезно, на место родителя всегда можно поставить наследника. Например, в функцию принимающую родителя, можно передать потомка вместо него. К примеру, есть такая функция:
native GetHandleId takes handle h returns integer
Она принимает тип handle, а возвращает его ИД в виде целого числа. Обычно мы могли передать в функцию только тот тип, который написан в её декларации, в данном случае это handle. Но так, как у handle есть наследники, то мы можем передать туда любого из них. Пример:
set udg_Unit = CreateUnit(Player(0), 'hfoo', 0, 0, 0)
set udg_Id = GetHandleId(udg_Unit) 
call BJDebugMsg("Ид только что созданного юнита: " + I2S( udg_Id ))
Сначала мы создали юнита и поместили его в глобальную переменную udg_Unit с типом unit. Затем мы передали только что созданного юнита в функцию GetHandleId, после чего мы поместили ИД в глобальную переменную udg_Id с типом integer. А в конце вывели сообщение с ИД на экран.
А еще в переменную родительского типа можно класть и наследников, но надобность в этом редко встречается на практике, а потому рассматривать эту возможность мы пока что не будем.

Значение null и общая информация

Для всех ссылочных типов данных, в том числе string и code, существует особенное значение null. Оно значит, что переменная ссылается на несуществующий объект.
Если передать значение null в нативную функцию, то ничего не произойдет, а сама функция вернет null. Функции и триггеры в которых будет вызвана нативная функция с параметром null нормально продолжат роботу после её вызова. Например, функция:
constant native GetUnitLoc takes unit whichUnit returns location
Принимает юнита, а возвращает его позицию. Если передать туда null, то она вернет null. Пример:
set udg_Pos = GetUnitLoc(null)
В глобальную переменную udg_Pos с типом location (точка) будет положено значение null. Мы передали в GetUnitLoc значение null и его же получили в ответ, так случилось потому, что у несуществующего объекта не может быть позиции в мире. У него вообще ничего нет и быть не может.
Над всеми ссылочными типами можно проводить две операции сравнения (==) и (!=). Их мы рассмотрим в следующих уроках.
Все знания о том, где используются и от кого наследуются те или иные типы данных, можно посмотреть здесь.

Уникальный идентификатор ID

У всего в игре есть свой уникальный номер в виде целого числа (тип integer), его зовут ID или ИД. Если быть точным, то он есть у всего что унаследовано от типа handle: юниты, тип юнита, предмет, локация, разрушаемое, способность, группа юнитов... Проще будет сказать у чего его нет: integer, real, boolean, string, code.
ID нужен для того чтобы точно сказать, кокой объект вы имеете в виду. Несмотря на то, что эту же задачу выполняет ссылка, некоторые функции принимают именно ИД. Например, уже знакомая нам функция:
native CreateUnit takes player id, integer unitid, real x, real y, real face returns unit
Она создает юнита и принимает ИД игрока, ИД типа юнита, координату х, координату у, и поворот. Вы видите, что у параметра id тип player? Нас ввели в заблуждение, это не ИД, а ссылка на игрока. А вот у параметра unitid тип integer, это действительно ИД и мы можем вписать туда число. Следующий код создаст пехотинца:
call CreateUnit(Player(0), 1751543663, 0, 0, 270)
1751543663 - это ИД обозначающий тип юнита "пехотинец".
Не очень удобно писать такие огромные цифры, поэтому используют более короткую запись, которую мы уже рассматривали в прошлом уроке. В записи четырьмя буквами число 1751543663 будет выглядеть так 'hfoo'.
Посмотреть какой ИД у юнита, декорации или способности можно в редакторе объектов. Для этого зайдите в редактор объектов и нажмите на вкладку Вид -> Показать названия переменных. Также это можно сделать нажав комбинацию клавиш Ctrl+D.
Теперь нам будут показаны ИД всех типов юнитов, декораций и способностей...
Для того чтобы вернуть всё обратно, нажмите те же клавиши или тот же пункт в меню.

`
ОЖИДАНИЕ РЕКЛАМЫ...