Статус: вроде решено.Переключение Lua.Ref (близкого к LuaD LuaObject) на структуру, как было предложено в ответе, решило большинство проблем, связанных с освобождением ссылок, и я вернулся к аналогичному механизму, который использует LuaD.Подробнее об этом в конце.
В одном из моих проектов я работаю с интерфейсом Lua.В основном я позаимствовал идеи у LuaD.Механизм в LuaD использует lua_ref & lua_unref, чтобы иметь возможность перемещать ссылки на таблицы / функции lua в пространстве D, но это вызывает серьезные проблемы, потому что вызовы деструкторов и их порядок не гарантируются.LuaD обычно вызывает ошибки по крайней мере при выходе из программы.
Поскольку кажется, что LuaD больше не поддерживается, я решил написать свой собственный интерфейс для своих целей.Мой класс интерфейса Lua находится здесь: https://github.com/mkoskim/games/blob/master/engine/util/lua.d
Примеры использования можно найти здесь: https://github.com/mkoskim/games/blob/master/demo/luasketch/luademo.d
А в случае необходимости скрипт Lua, используемый примером, находится здесь: https://github.com/mkoskim/games/blob/master/demo/luasketch/data/test.lua
Интерфейс работает следующим образом:
Lua.opIndex помещает глобальную таблицу и индексный ключ в стек и возвращает объект Top.Например, lua["math"]
помещает в стек _G и "math".
Дальнейший доступ осуществляется через объект Top.Top.opIndex идет глубже в иерархии таблиц.Другие методы (call, get, set) являются «финальными» методами, которые выполняют операцию с таблицей и ключом наверху стека, а затем очищают стек.
Закрыть все работает нормально, за исключением того, что этот механизм имеет неприятную причуду / ошибку, которую я не знаю, как ее решить.Если вы не вызовете ни один из этих «финальных» методов, Top оставит таблицу и ключ в стеке:
lua["math"]["abs"].call(-1); // Works. Final method (call) called.
lua["math"]["abs"]; // table ref & key left to stack :(
Что я точно знаю, так это то, что игра с деструктором Top () не работает, поскольку он не вызывается сразу, когда на объект больше не ссылаются.
ПРИМЕЧАНИЕ. Если есть какой-то оператор, который вызывается при обращении к объекту как rvalue, я мог бы заменить call (), set () иМетоды get () с перегрузками операторов.
Вопросы:
Есть ли способ запретить пользователям писать такие выражения (получение объекта Top без вызова "final")методы)?Я действительно не хочу, чтобы пользователи писали, например, luafunc = lua["math"]["abs"]
, а потом пытались позвонить, потому что это не будет работать вообще.Не без того, чтобы начать играть с lua_ref & lua_unref и начать бороться с теми же проблемами, что и LuaD.
Есть ли какая-либо перегрузка оператора opAccess, то есть перегрузка того, что происходит при использовании объектакак значение?То есть выражение "a = b" -> "a.opAssign (b.opAccess)"?opCast не работает, он вызывается только с явными приведениями.
Есть еще предложения?Я внутренне чувствую, что ищу решение с неправильной стороны.Я чувствую, что проблема заключается в сфере метапрограммирования: я пытаюсь «охватить» вещи на уровне выражений, что, по моему мнению, не подходит для классов и объектов.
До сих пор я пытался сохранитьLuaD смотрит на интерфейс пользователя на стороне пользователя, но я думаю, что если бы я мог изменить интерфейс на что-то вроде следующего, я мог бы заставить его работать:
lua.call(["math", "abs"], 1); // call lua.math.abs(2)
lua.get(["table", "x", "y", "z"], 2); // lua table.x.y.z = 2
...
Синтаксически, который обеспечил бы эту ссылку на luaобъект, выбранный посредством индексации, наконец используется для чего-то в выражении, и стек будет очищен.
UPDATE: Как уже говорилось, изменение Lua.Ref для структурирования решаемых проблем, связанных сразыменование, и я снова использую механизм ссылок, похожий на LuaD.Я лично чувствую, что этот механизм соответствует синтаксису в стиле LuaD, который я использую, и это может быть довольно сложной задачей для правильной работы синтаксиса с другими механизмами.Я все еще открыт, чтобы услышать, есть ли у кого-то идеи, чтобы заставить его работать.
Система, которую я набросал для замены ссылок (для решения проблемы с объектами, содержащими ссылки, живущие дольше, чем песочница lua), вероятно, потребовала бы другой вид интерфейса, что-то похожее я набросал выше.