Интерфейс для моего игрового движка построен с использованием языка разметки и Lua, аналогично HTML и javascript. Таким образом, визуальные элементы будут иметь обработчики для событий пользовательского интерфейса, таких как перемещение мыши или щелчок, и каждый раз, когда должен запускаться обработчик, механизм будет проверять, скомпилирован ли он, а если нет, скомпилирует его через luaL_loadstring
, Хандеры могут быть разделены либо дублированием элементов, либо назначением (this.onclick = that.onclick
).
Как настроить окружение куска кода lua перед его запуском? Идея состоит в том, чтобы сделать данные, относящиеся к элементам и событиям, доступными для чанка, а также связать их со средой родительского элемента пользовательского интерфейса. Lua 5.2 изменения удален lua_setfenv
поэтому я не уверен, как это сделать. Функция lua_load
позволяет указать среду, но, похоже, используется только для загрузки кода, а не для его запуска.
Вы можете использовать load (или loadfile) для загрузки чанка в другой среде. (В C вы должны загрузить чанк, а затем изменить значение его первого повышения.)
Установка значений выполняется с lua_setupvalue
. Итак, сначала загрузите ваш код, затем вставьте новую среду и вызовите lua_setupvalue
так же, как вы бы назвали lua_setfenv
до:
luaL_loadfile(L, "file.lua"); /* load and compile handler */
lua_getglobal(L, "my_environment"); /* push environment onto stack */
lua_setupvalue(L, -2, 1); /* pop environment and assign to upvalue#1 */
/* any other setup needed */
lua_pcall(L, ...); /* call handler */
Также с конца вашего вопроса:
Функция
lua_load
позволяет указать среду, но, похоже, используется только для загрузки кода, а не для его запуска.
На самом деле это не так; load
(функция Lua) позволяет вам указать среду, но lua_load
(функция C) нет.
Кроме того, хотя он «используется только для загрузки кода, а не для его запуска», он аналогичен luaL_loadstring
— в самом деле, luaL_loadstring
это просто обертка вокруг него. lua_load
является API-функцией более низкого уровня, которую можно использовать для реализации пользовательских загрузчиков (например, загрузки кода по сети или из сжатого файла). Так что, если вы уже комфортно загружаете код с luaL_loadstring
прежде чем запустить его с lua_pcall
, lua_load
должен выглядеть знакомым.
Других решений пока нет …