Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #71, ОКТЯБРЬ 2006 г.

дублер каскадера

АЛЕКСАНДР ГЛАДЫШ

Спецвыпуск: Хакер, номер #071, стр. 071-068-6


for _, child in ipairs(data) do

if type(child) == “function” then

child(data)

end

end

end

Все параметризованные функции – ключевые слова, кроме корневого, можно реализовать по следующей схеме:

-- Вместо keyword_name нужно подставить имя ключевого слова

keyword_name = name_data(“keyword_name”) function(name, data)

process_child_keywords(data)

data.type_ = keyword_name

data.name_ = name

return function(dest)

if not dest.children_ then dest.children_ = { } end

table.insert(dest.children_, data)

end

end)

В реализации унарных ключевых слов, очевидно, что нужно опустить упоминание name_data, поскольку единственный аргумент передается за один вызов функции.

У корневого ключевого слова (gui_layout) не может быть предков, поэтому оно должно возвращать готовую таблицу с данными. В остальном, оно реализуется по той же схеме:

gui_layout= name_data(“gui_layout”) function(name, data)

process_child_keywords(data)

data.type_ = gui_layout

data.name_ = name

return data

end)

Недостаточное число аргументов

Приведенная выше реализация функции pipeline не позволяет эффективно обнаружить один из видов ошибок в данных – когда пользователь указывает недостаточное число аргументов для ключевого слова. Например, если для панели указано только имя:

panel “bad_panel”;

Как видно из его реализации, сборщик аргументов collector возвращает самого себя до тех пор, пока не наберет нужного числа аргументов. Поэтому в такой ситуации в списочной части таблицы данных ключевого слова-предка оказывается не результат работы функции – реализации ключевого слова-потомка sink, а сам сборщик.

Эту ошибку можно обнаружить, сделав сборщика из функции таблицей с заданным метаметодом __call (реализацией этого метаметода будет нынешнее тело функции-сборщика) и заданным (мета)полем, обозначающим, что это – сборщик.

В process_child_keywords при обнаружении таблицы вместо функции необходимо проверять значение этого поля. Если обнаружен сборщик, нужно выдавать ошибку о недостаточном количестве аргументов. Дополнительную отладочную информацию о природе сборщика (имя, типы, число аргументов) можно хранить в его же (мета)таблице.

Тем же способом можно реализовать задание значений аргументов по умолчанию – вместо выдачи ошибки нужно просто вызывать сборщик с этим значением (или значениями) до тех пор, пока он не наберет достаточное количество аргументов.

Если нужна поддержка значений параметров по умолчанию, их установку целесообразно вставить после обработки ключевых слов-потомков. Например, панели должны быть видимы по умолчанию, значит, для ключевого слова panel после вызова process_child_keywords нужно добавить строчку:

if data.visible == nil then data.visible = true end

На выходе для данных из листинга 1 будет сгенерированна примерно такая таблица (для экономии места описание панели «settings» пропущено):

{

type_ = “gui_layout”;

name_ = “gamegui”;

children_ = {

[1] = {

type_ = “panel”;

name_ = “mainmenu”;

modal = true;

visible = true;

children_ = {

[1] = { type_ = “button”; name_ = ”newgame”; };

Назад на стр. 071-068-5  Содержание  Вперед на стр. 071-068-7