03 октября 2010

Скриптовой модуль, Demo-1

Вот и наступило время выложить описание первой демонстрационной программы связки Lua + Delphi, написанной мною недавно. Если вы не понимаете о чем идет речь, то, вероятно, стоит прочесть сообщение, в котором я как-то раз обещал описать демки, что выложил на всеобщее обозрение.

Итак, приступим к первой демонстрационной программе.Исходный код располагается в папке Demo-1.
По сути это простой калькулятор, демонстрирующий базовые элементы работы со скриптовым модулем. Посмотрим на форму. Два Edit'а слева содержат в себе значения операндов, посередине можно выбрать математический знак (+,-,*,/), нажав на кнопку Calc - в правый Edit выведется результат вычислений. Что же в этой программе необычного? Дело в том, что вычисления результата проходят внутри Lua скрипта, который и выдает значение в правое окошко. Чуть ниже располагается Memo, в который по необходимости будут выводиться Log-сообщения. Кнопка Reload необходима для перезагрузки файла-скрипта в память.
У формы определены обработчики двух событий: FormCreate() и FormDestroy(). В первом происходит создание объекта fScriptManager := TScriptManager.Create; а также запускается инициализация в методе Initialize() формы.
Остановимся на инициализации поподробнее.

Procedure TfrmMain.Initialize;
begin
  fScriptManager.LoadScriptFile('demo_1.lua');
  fScriptManager.OnCustomLogWriter := OnCustomLogWriter;
  Lua_Register(fScriptManager.LuaVM, PChar('Get_A'),   Get_A);
  Lua_Register(fScriptManager.LuaVM, PChar('Get_B'),   Get_B);
  Lua_Register(fScriptManager.LuaVM, PChar('Get_Operation'),   Get_Operation);
  Lua_Register(fScriptManager.LuaVM, PChar('Set_Result'),   Set_Result);
  Lua_Register(fScriptManager.LuaVM, PChar('Add_ToLog'),   Add_ToLog);
end;

Что в ней происходит?
  • Во-первых, компилируется файл-скрипт в память fScriptManager.LoadScriptFile('demo_1.lua');
  • Во-вторых, указывается функция-обработчик для вывода лог-сообщений fScriptManager.OnCustomLogWriter := OnCustomLogWriter;
  • В-третьих, регистрируются функции для Lua, чтобы скрипт мог взаимодействовать с хост-программой (под хост-программой подразумевается основная программа, наша с вами Demo-1, которая и запускает скрипты).
Что за функции мы регистрируем?
  • Get_A() - которая выдает в скрипт значение самого левого Edit'а; 
  • Get_B() выдает значение второго операнда; 
  • Get_Operation() выдает в скрипт порядковый номер операции, выбранной в ComboBox посередине; 
  • Set_Result() устанавливает значение в правый Edit, содержащий значение результата; с помощью Add_ToLog() из скрипта можно передавать текст, который отобразится в Memo.
Теперь взглянем на сам скрипт:
function main()
    local oper = Get_Operation();
    local a, b = Get_A(), Get_B();
    local c = 0;
 
    if oper == 0 then
        res = a + b;
    elseif oper == 1 then
        res = a - b;
    elseif oper == 2 then
        res = a * b;
    elseif oper == 3 then
        if math.abs(b) > 0.00001 then
            res = a / b;
        else
            res = '!!!';
            Add_ToLog('Division by zero');
        end;       
    end;

    Set_Result(res);
end;
Возможно, синтаксис покажется немного необычным - но к этому можно быстро привыкнуть. Зная, какие функции мы зарегистрировали для этого скрипта, можно с легкостью прочесть этот код. Сначала запрашиваются значения a, b, oper из хост-программы, а далее, в зависимости от операции, вычисляется результат, который подается как аргумент в функцию Set_Result(). Также имеется банальная проверка деления на нуль. Обратите внимание на множественное присваивание, допустимое в Lua:
local a, b = Get_A(), Get_B();
зарезервированное слово local указывает на то, что переменные a и b - локальны и будут использоваться только в функции main(). Само множественное присваивание заключается в возможности перечисления справа и слева от знака равенства нескольких аргументов, которые будут присвоены в соответствующем порядке. К примеру, множественное присваивание дает возможность удобного использования вроде такого: x, y, angle = Get_ObjectPosition(myObject)!
Итак, результат наших деяний на лицо:

вот такая незамысловатая программа у нас с вами получилась. Главное ее достоинство в кнопке Reload, нажав которую, мы мгновенно перезагрузим скрипт. При этом не требуется перекомпиляция программы - скрипт подхватывается на лету, так что можно с легкостью изменять логику программы, переписывая текст скрипта.

Сообщения, схожие по тематике:

0 коммент.:

Отправить комментарий