Значения по умолчанию для структур
При объявлении структуры в UnrealScript можно дополнительно указать значения по умолчанию для свойства структуры. При каждом использовании структуры в UnrealScript ее члены будут инициализироваться этими значениями. Синтаксис идентичен блоку defaultproperties для класса - единственное исключение в том, что вы должны назвать блок structdefaultproperties. Например:
struct LinearColor
{
var() config float R, G, B, A;
structdefaultproperties
{
A=1.f
}
};
При каждом определении переменной LinearColor в UnrealScript, значение ее члена A будет установлено в 1.f. Также важно учесть, что блок defaultproperties класса переопределяет свойства по умолчанию для структуры. Если в вашем классе есть переменная типа LinearColor, любое значение, присвоенное ей в блоке defaultproperties заменит значение, определенное в блоке structdefaultproperties.
defaultproperties { NormalColor=(R=1.f,B=1.f,G=1.f) // value of A will be 1.0f for this property DarkColor=(R=1.f,B=1.f,G=1.f,A=0.2f) // value of A will be 0.2f for this property } |
Динамические массивы
Ранее мы рассмотрели статические массивы. Это означает, что размер (количество элементов в массиве) устанавливается во время компиляции и не может быть изменен. Динамические и статические массивы имеют следующие общие характеристики:
- Одинаковое время доступа - затраты времени на доступ к элементам массива не зависят от размера массива
- Нет ограничений на тим элемента - Вы можете создаывть массивы любых типов: целые числа, векторы, акторы и т.д. (с тем исключением, что логические типы действительны только для динамических массивов)
- Поведение при доступе - Вы можете получить доступ по индексу к любому элементу массива, и наоборот, попытка получить доступ к элементу по индексу, выходящему за границы массива, будет неудачной.
Динамические массивы обеспечивают способ получить функциональность статического массива с возможностью изменения числа элементов во время выполнения, в целях удовлетворения меняющихся потребностей. Для использования динамических массивов, мы должны знать несколько их особенностей.
Первое - это объявление переменной. Объявление динамического массива очень похоже на объявление любой другой переменной UnrealScript (то есть имеет вид var/local type varname). Для объявления динамического массива указызается тип array, а затем тип массива, заключенный в угловые скобки. Если тип массива содержит скобки (например class<Actor>), то вы должны поставить пробел между закрывающей скобкой типа и закрывающей скобкой объявления массива, иначе компилятор интерпретирует двойную угловую скобку как оператор >>. Примеры:
Объявление динамического массива целых чисел с именем IntList:
var array<int> IntList;
Объявление динамического массива типа class<PlayerController> с именем Players:
var array<class<PlayerController>> Players;
При запуске сценария IntList будет содержать 0 элементов. Динамическими массивами поддерживаются методы, позволяющие добавлять элементы в массив, изымать элементы из массива, а также произвольно увеличивать или уменьшать длину массива. Синтаксис вызова этих методов (использованием переменной IntList): IntList.MethodName(). Для динамических массивов доступны следующие методы:
- Add(int Count): увеличивает длину массива на Count элементов, идентично вызову FArray::AddZeroed().
- Insert(int Index, int Count): где Index - это индекс массива для вставки элементов, а Count число элементов для вставки. Все существующие элементы в этом месте массива смещаются вверх, а новые элементы создаются и вставляются в указанном месте. Вставка 5-ти элементов по индексу 3 смещтит вверх (на значение индекса) все элементы массива, начиная от индекс 3 на 5 элементов. Элемент, ранее распологавшийся по индексу 3 теперь будет расположен по индексу 8, элемент 4 теперь будет элементом 9 и так далее. Все добавленные элементы инициализируются значениями по умолчанию (ноль/нуль для всех типов, кроме структур, имеющих structdefaultproperties).
- Remove(int Index, int Count): где Index - это начальный индекс для удаления элементов из массива, и Count - это число удаляемых элементов. Это позволяет удалить группу элементов из массива, начиная с любого допустимого индекса. Обратите внимание, что значения индексов оставшихся элементов (начиная с индекса, равного Index+Count) изменятся в меньшую сторону. Имейте это в виду, если вы храните значения индексов динамических массивов.
- AddItem(Item): добавляет Item в конец массива, увеличивая длину массива на один элемент.
- RemoveItem(Item): удаляет все экземпляры Item, используя линейный поиск.
- InsertItem(int Index, Item): вставляет Item в массив по индексу Index, увеличивая длину массива на один элемент.
- Find(...) - находит индекс элемента в массиве. Есть две версии Find: стандартный поиск для элемента по значению, и специализированная версия для поиска структуры по значению одного из свойств структуры
- Find(Value): где Value - это значение для поиска. Возвращает индекс первого найденного элемента в массиве, который соответствует указанному значению, или -1, если это значение не было найдено. Value может быть представлено ??любым допустимым выражением.
- Find(PropertyName, Value): где PropertyName - это имя свойства структуры для поиска (должно иметь тип 'Name'), а Value - это искомое значение. Возвращает индекс первой найденной структуры в массиве, свойство с именем PropertyName которой соответствует значению, указанному Value, или -1, если это значение не было найдено. Value может быть представлено ??любым допустимым выражением.
- Sort(SortDelegate) - SortDelegate - это делегат для сортировки содержимого массива. SortDelegate должен иметь следующий вид:
- delegate int ExampleSort(ArrayType A, ArrayType B) { return A < B ? -1 : 0; } // отрицательное возвращаемое значение указывает, элементы должны поменяться местами
Переменная Length
Динамические массивы имеют переменную, называемую Length, значением которой является текущая длина (количество элементов) динамического массива. Для получения доступа к Length, применительно к нашему массиву IntList используется запись: IntList.Length. Мы можем не только прочитать, но и непосредственно установить значение переменной Length, что позволяет нам изменить количество элементов в массиве. При изменении переменной Length изменяется и длина массива. Например, если мы установим IntList.Length = 5, а затем установим IntList.Length = 10, дополнительные 5 элементов, добавленных последней операцией, добавляются в конец массива с сохранением первоначальных 5 элементов и их значений. Если мы уменьшим длину, то элементы будут сняты с конца массива. Обратите внимание, что при добавлении элементов в массив операцией Insert() или путем увеличения длины, элементы инициализируются в значения по умолчанию для типов переменных (0 для целых, None для ссылок на класс и т.д.). Следует также отметить, что вы можете увеличить длину динамического массива, обратившить по большему индексу, чем текущее значение длины массива. Это позволяет увеличивать массив так же, как если бы вы установили большее значение для Length.
OldLength = Array.length
Array.Length = OldLength + 1
Array[OldLength] = NewValue
Array[Array.Length] = NewValue
Array.AddItem(NewValue)
- это эквивалентные формы одной и той же операции.
Заметим, однако, что вы не можете увеличивать длину массива и получать доступ к его членам одновременно. Выражение:
Array[Array.length].myStructVariable = newVal
не будет работать.
Предостережение: переменная Length динамического массива никогда не должна увеличиваться или уменьшаться операторами '++','--','+=' или'-=', и вы не должны передавать Length в функцию в качестве параметра (если функция может изменить ее значение). Выполнение этих операций приведет к утечке памяти и сбоям. Устанавливайте значение Length только через оператор '=' (или через обращение по большему индексу, чем текущее значение длины массива).
Обратите внимание: array<bool> не поддерживается!
Последнее замечание: динамические массивы не реплицируются. Вы можете обойти это с помощью функции, реплицирующей индексы динамического массива и соответствующие значения элементов. Однако, при этом вы также должны учитывать временное рассогласование между клиентом и сервером.