Войти
UDKСтатьи

Препроцессор UnrealScript

Автор:

Обзор
  Основы
  Область видимости
Применение макросов
Параметры макросов
Встроенные макросы
  define
  if / else / endif
  include
  isdefined
  undefine
  log / warn
  logd
  assert
Взаимодействие с командной строкой

Обзор

Теперь в движке Unreal Engine 3 компилятор UnrealScript поддерживает препроцессор. Препроцессор работает во многом также, как и препроцессор C++, и идеально подходит для реализации условной компиляции с помощью макросов.

Основы

Обработка макросов происходит до компиляции сценариев UnrealScript. Препроцессор является отдельной фазой сборки и он не относится к лексическим соглашениям языка UnrealScript.

Область видимости

Конкретные объявления макросов доступны только в том файле сценария, в котором они объявлены, и только в строках кода, расположенных ниже конкретного макроопределения. Однако, вы можете создать файл Globals.uci в корневой папке вашего проекта (например, Development\Src\MyProject\Globals.uci), и макросы, объявленные в этом файле, будут автоматически доступны для всех классов пакета (MyProject).

Применение макросов

Макрос определяется в коде путем помещения перед именем макроса ` (символа обратной кавычки). Например, макрос hello без параметров определяется следующим образом:

`hello

Также имя макроса может быть заключено в фигурные скобки {} после символа `:

`{hello}

Это позволяет "включать" определение макроса в середину текста без использования пробелов:

hippo`{hello}potamus

Но как объявить макрос hello? Применение встроенного макроса define очень похоже на использование макроса #define языка C++:
  1. Указать ключевое слово `define и поставить пробел;
  2. Указать имя нового макроса (и, возможно, список его параметров);
  3. Определить тело макроса.

Таким образом, макрос hello можно объявить следующим образом:

`define   hello   "Hello, World!"

В итоге, после обработки препроцессором макрос `hello в коде будет интерпретирован как "Hello, World!" (включая кавычки). Результаты интерпретации макроса, опять же, проверяются на наличие возможных макроопределений. Объявление макроса может включать в себя другие макроопределения, которые, в свою очередь, могут включать собственные и т.д. Все это позволяет создавать макросы с "бесконечной рекурсией".

Параметры макросов

Параметры макроопределения размещаются в скобках через запятую сразу после имени макроса. Открывающая скобка перед списком параметров должна находиться сразу после имени макроса, иначе параметры будут интерпретированы как определение макроса. Более подробно о параметрах макросов читайте в примечании к макросу define

Встроенные макросы

define

`define <macroname>[<(paramA[,paramB...])>] [<macrodefinition>]

Объявляет новый макрос. В случае, если не указаны параметры и не определено тело макроса, результатом интерпретации макроса будет пустая строка.

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

`define DeclareInt(x) var int `x;

Специальный макрос `# используется в макроопределении для получения числа параметров макроса.

if / else / endif


`if(<value>)

`else

`endif

Эти три макроса используются для реализации условной компиляции. При обработке препроцессором проверяется значение <value>, и, если оно соответствует непустой строке или оно вычисляется как истина, то оно расценивается как истинное. В противном случае оно расценивается как ложное.

Код, находящийся, либо между `if и `else (если `else присутствует), либо между `if и  `endif включается в процесс компиляции, если условие истинно. Если же условие ложно, то в  процесс компиляции включается текст, находящийся, либо между `else и `endif (если `else присутствует), либо не включается ничего.

Обратите внимание: макросы, находящиеся в участках кода, выброшенных из процесса компиляции, не интерпретируются (за исключением групп макросов `if/`else</strong>/`endif</strong>, которые интерпретируется только для отслеживания уровней вложенности).

include

`include(<filename>)

Включает текст файла <filename> в место определения макроса. По умолчанию, поиск файла <filename> осучетсвляется относительно каталога, заданного значением EditPackagesInPath раздела Editor.EditorEngine .ini файла вашей игры. Если указать только имя файла (т.е. без пути к нему), то его поиск будет осуществлен в каталоге классов текущего компилируемого пакета.

isdefined


`isdefined(<macroname>)

`notdefined(<macroname>)


Оценивает строку <macroname> как "1 ", если макрос объявлен (для макроса `isdefined</strong>) или не объявлен (для макроса `notdefined</strong>), независимо от значения объявления. Эти мпкросы полезны для реализации условной компиляции.

undefine

`undefine(<macroname>)

Удаляет текущее объявление <macroname>. Не применим к именам параметров макросов (`cond, `txt, `# и т.д.).

log / warn

`log(string OutputString, optional bool bRequiredCondition, optional name LogTag);

`warn(string OutputString, optional bool bRequiredCondition);

Враперы для функций LogInternal и WarnInternal, объявленных в Object.uc. Если параметр bRequiredCondition указан как true, то сообщения будут только занесены в журнал.

Оба макроса отключаются, если сценарий компилируется с параметром -final_release.

logd

`logd(string OutputString, optional bool bRequiredCondition, optional name LogTag);

Идентичен макросу `log за исключением того, что он включается только в сценарии, компилируемые в режиме отладки.

Макрос отключается, если сценарий компилируется с параметром -final_release.

assert

`assert(bool bCondition);

Врапер для внутренней функции Assert.

Макрос отключается, если сценарий компилируется с параметром -final_release.

Взаимодействие с командной строкой

Есть несколько параметров командной строки, влияющих на обработку сценариев препроцессором.

debug
Объявляет макрос `debug для всех сценариев
final_release
Объявляет макрос `final_release для всех сценариев, также отключает все отладочные враперы (`log, `logd, `warn, `assert).
nopreprocess
Отключает обработку всех макросов и комментариев.
intermediate
Заставляет препроцессор сохранить обработанные им версии файлов. Сохранение может занять много времени и места на диске для всего дерева исходных файлов, но может быть очень полезно при отслеживании ошибок в макроопределениях. Получившийся текст сохраняется в файлы:
GameDirectory/PreprocessedFiles/<PackageName>/<ClassName>.uc
Данный документ является переводом оригинального документа UnrealScript Preprocessor.

#UDK, #Unreal Development Kit

7 июня 2012