2016-09-01 2 views
2

Я использую API Lua для переопределения мета-событий для моих собственных объектов C++, завернутых как userdata. Однако некоторые мета-события могут принимать несколько аргументов, которые могут быть пользовательскими данными или регулярными значениями, которые я могу преобразовать в пользовательские данные. Например, __add, __eq, __concat и т. Д.Lua Meta Event Argument Order

Во-первых, для этих мета-событий, чей __add вызывается, если я добавляю две пользовательские данные, и вызывает ли это вызов только один раз? Это имеет значение, если у меня есть два РАЗЛИЧНЫХ типа пользовательских данных с разными __add-крючками (хотя для них было бы плохой практикой иметь разные результаты возврата).

Во-вторых, для примера вроде этого: 2 + userdata вместо userdata + 2, есть ли гарантия, что пользовательские данные всегда будут отображаться сначала в стеке? Это значительно упростит мою реализацию, и я не нашел много документации по подробному поведению мета-событий, кроме __index.

И наконец, что такое поведение Lua, если вы добавляете несколько объектов? Из тестов с metatables, не использующих C API, это похоже на упорядочение PEMDAS. То есть userdata1 + 3 + userdata2 + userdata3 + nonuserdata, но я не нашел ссылки для подтверждения этого. Вызывается ли __add только один раз со всеми аргументами в стеке, вызывая __add из первых userdata или распространяется с одного направления, создавая временные значения rvalues?

Вот пример того, как я беру аргументы из стека для __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; 
    } 

ответ

2

Первый: левый. В случае A + B вызывается __add A.

Второй: Нет, извините. Аргументы передаются в порядке (слева останется слева, справа будет находиться справа)

http://lua-users.org/wiki/MetatableEvents

Наконец: Я не совсем уверен. Я серьезно сомневаюсь, что он вызывает __add со всеми из них, и я бы подозревал, он двигался слева направо (следуя порядку операций в математике). Это, безусловно, соответствует порядку операций для 1 + 1/2.

+0

Похоже, что это справа налево (по userdata), но в любом случае это одно за раз. благодаря – Leo