Сначала небольшое предисловие. Как и обещал ранее, напишу в виде прямолинейного описания, о своем скриптовом модуле, что использую сейчас. Модуль простой, ничего особенного нет. Но, думаю, может чем и пригодится людям, только начинающим изучать Lua и стремящихся встроить поддержку скриптов в свою программу. К модулю приложил 4 демки, представляющими из себя простенькие программы, демонстрирующие способ привязывания скриптов к логике основного приложения. Вообще, скрипты в своих программах я использовать начал недавно, пожалуй, плотно занялся скриптами начиная с AiWar, где использование скриптов было обязательным условием конкурса. Потом начал преобразовывать работу с ними, изучать более оптимальные подходы и т.д. Предупрежу сразу: сам язык Lua знаю не шибко хорошо, поэтому супер накрученных мета-таблиц и имитации ООП не использую вообще. Цель рассказал, задачу поставил, обо всем предупредил, так что... в путь!... |
Итак, начну с того, что сам модуль uScriptManager состоит из главного класса TScriptManager и дополнительного TQueueFunction. Скриптовой класс обладает способностью строить очереди из функций, которые он должен выполнить. Далее, стоит только вызвать TScriptManager.DoAllScripts(), как вся очередь скриптов развернется, выполнится, а затем полностью очистится от только что проигранных скриптовых-объектов. Зачем все так сложно? Дело в том, что я любитель применять физические симуляции в своих программах. Зачастую, многие физические библиотеки не имеют возможности менять параметры объектов и системы в целом из произвольных мест, тем более из callback-функций, срабатывающих при вызове событий изнутри физического движка.
Например, столкнулись два тела, и я хочу в этот момент соединить их сочленением. Как будто гвоздь вбился в доску, и мне нужно создать сочленение в месте их контакта. Так вот, Box2d не позволит мне этого сделать из callback-функции столкновения объектов. Как быть? Эти события нужно только фиксировать, а выполнять различные действия после прохождения полного шага симуляции. Именно поэтому в модуле имеется дополнительный класс TQueueFunction, который и хранит внутри себя всю информацию о скриптовой функции, которую нужно будет выполнить. При вызове события теперь я вызываю TScriptManager.AddFunctionToQueue(), имеющий ряд параметров, таких как: aFunctionName - имя lua-функции, которую надо выполнить; aArguments - массив аргументов, передающихся в функцию (здесь я поленился и оставил возможность передавать только single-параметры); aSelfObject - ссылка на объект, численное значение которой будет доступно из скрипта через переменную self. Вот и все.
Вообще, для более адекватного понимания происходящих вещей рекомендую прочесть базовые уроки здесь и посмотреть/сохранить ссылки, данные в этом сообщении. Это убережет вас от непонимания таких вещей как регистрация функций в луа-машине, даст понимание функций вроде Lua_ToNumber()/Lua_ToString()/Lua_PushNumber() и т.д., по этим ссылкам сможете прочесть о стеке Lua и других простых, но важных вещах.
Давайте для закрепления пробежимся разок по обычной схеме работы с Lua.
Думаю, можно приступить к описанию демо-программ. Кстати, особо внимательные наверно заметили, что пропущена папка Demo-4, так и есть. Я сначала создал простенький пример, но потом он мне разонравился и я его убрал. Возможно, вы сами меня натолкнете на то, что внести в последний пример, что я упустил и чего не хватает во всех остальных программах.
Сначала скриншоты:
Кстати, хотел отметить, что писать здоровенные сообщения - не мой конёк, поэтому я разнесу описание демок по разным заметкам, чтобы было проще читать.
Например, столкнулись два тела, и я хочу в этот момент соединить их сочленением. Как будто гвоздь вбился в доску, и мне нужно создать сочленение в месте их контакта. Так вот, Box2d не позволит мне этого сделать из callback-функции столкновения объектов. Как быть? Эти события нужно только фиксировать, а выполнять различные действия после прохождения полного шага симуляции. Именно поэтому в модуле имеется дополнительный класс TQueueFunction, который и хранит внутри себя всю информацию о скриптовой функции, которую нужно будет выполнить. При вызове события теперь я вызываю TScriptManager.AddFunctionToQueue(), имеющий ряд параметров, таких как: aFunctionName - имя lua-функции, которую надо выполнить; aArguments - массив аргументов, передающихся в функцию (здесь я поленился и оставил возможность передавать только single-параметры); aSelfObject - ссылка на объект, численное значение которой будет доступно из скрипта через переменную self. Вот и все.
Вообще, для более адекватного понимания происходящих вещей рекомендую прочесть базовые уроки здесь и посмотреть/сохранить ссылки, данные в этом сообщении. Это убережет вас от непонимания таких вещей как регистрация функций в луа-машине, даст понимание функций вроде Lua_ToNumber()/Lua_ToString()/Lua_PushNumber() и т.д., по этим ссылкам сможете прочесть о стеке Lua и других простых, но важных вещах.
Давайте для закрепления пробежимся разок по обычной схеме работы с Lua.
- сначала создаем объект класса TScriptManager, который, в свою очередь, создаст виртуальную машину Lua, загрузит библиотеку и подготовит все к работе.
- регистрируем функции для сообщения хост-программы и луа-скриптов.
- загружаем скрипты с помощью метода TScriptManager.LoadScriptFile() или TScriptManager.LoadScriptStream()
- в любой момент времени теперь можем вызвать TScriptManager.DoScript() для выполнения скриптовой функции, ранее загруженной в память.
- убиваем объект, созданный в первом пункте.
Думаю, можно приступить к описанию демо-программ. Кстати, особо внимательные наверно заметили, что пропущена папка Demo-4, так и есть. Я сначала создал простенький пример, но потом он мне разонравился и я его убрал. Возможно, вы сами меня натолкнете на то, что внести в последний пример, что я упустил и чего не хватает во всех остальных программах.
Сначала скриншоты:
Кстати, хотел отметить, что писать здоровенные сообщения - не мой конёк, поэтому я разнесу описание демок по разным заметкам, чтобы было проще читать.
Ссылка на описание первой демо.
Ссылка на описание второй демо.
Ссылка на описание третьей демо.
Ссылка на описание пятой демо.
что может быть лучше RemObjects' Pascal Script?? Я вообще давненько собирался попробовать какую-нибудь новую (в смысле, для меня новую, а не то, чтобы в принципе) скриптовую библиотеку. Как только соберусь, обязательно начну с твоей фигни
ОтветитьУдалитьhinstance, это вовсе не фигня ;)
ОтветитьУдалить2Автор, когда будет следующая статья !?)