Я использую Lua API для переопределения мета-событий для моих собственных объектов C ++, обернутых как пользовательские данные. Однако некоторые мета-события могут принимать несколько аргументов, которые могут быть пользовательскими или обычными значениями, которые я могу преобразовать в пользовательские данные. Например, __add, __eq, __concat и т. Д.
Во-первых, для этих мета-событий, чей __add вызывается, если я складываю вместе две пользовательские данные, и вызывается ли он только один раз? Это уместно, если у меня есть два РАЗЛИЧНЫХ типа пользовательских данных с разными хуками __add (хотя было бы плохой практикой иметь разные возвращаемые результаты).
Во-вторых, для примера, подобного этому: 2 + userdata
вместо userdata + 2
, есть ли гарантия, что пользовательские данные всегда будут отображаться первыми в стеке? Это сделает мою реализацию значительно более простой, и я не нашел много документации о подробном поведении мета-событий, кроме __index.
Наконец, каково поведение Lua, если вы добавляете несколько объектов? Из тестов с метатаблицами, НЕ использующими C API, это выглядит как упорядочение PEMDAS. То есть userdata1 + 3 + userdata2 + userdata3 + nonuserdata
, но я не нашел ссылки, чтобы подтвердить это. __Add вызывается только один раз со всеми аргументами в стеке, вызывая __add первых пользовательских данных, или он распространяется из одного направления, создавая временные значения?
Вот пример того, как я беру аргументы из стека для __arg, что довольно просто, если порядок аргументов гарантирован.
if (unlikely(lua_gettop(L) != 2))
{
return LUA_FAILURE;
}
Val *v = CheckLuaUserdata(L, 1);
if (unlikely(!v))
{
return LUA_FAILURE;
}
bool allocated = false;
Val *arg2 = lua_mgr->PullLuaValFromGenericArg(L, 2, &allocated);
if (unlikely(!arg2))
{
return LUA_FAILURE;
}
Первый: левый. В случае A + B вызывается __add A.
Второе: нет, прости. Аргументы передаются по порядку (слева останется слева, справа останется справа)
http://lua-users.org/wiki/MetatableEvents
Наконец: я не совсем уверен. Я серьезно сомневаюсь, что он вызывает __add со всеми из них, и я бы подозреваемый он перемещается слева направо (по порядку операций в математике). Это, безусловно, следует порядку операций для 1 + 1/2.
Других решений пока нет …