Adding userdata metadata to lua table

I have a scripting system that works well using userdata objects. However, now I want to have a property in my user data that can take a regular table.

I think I need to create a regular table and set the metatet to use my current set of metamethods, but I'm struggling to figure out how to do this - I'm sure this is a simple setup, I just can "Look right now."

My existing code looks like this:

void
LuaContext::push(lua_State* state, boost::shared_ptr<LuaWrapped> wrapped) {
    static struct luaL_Reg methods[] = {
        { "__index", LuaWrapped::static_get },
        { "__newindex", LuaWrapped::static_set },
        { "__len", LuaWrapped::static_len },
        { "__ipairs", LuaWrapped::static_ipairs },
        { "__pairs", LuaWrapped::static_pairs },
        { "__gc", LuaWrapped::static_gc },
        { "__eq", LuaWrapped::static_eq },
        { NULL, NULL }
    };

    LuaWrapped::Ptr **ptr = (LuaWrapped::Ptr **)lua_newuserdata(state, sizeof(LuaWrapped::Ptr *));
    *ptr = new LuaWrapped::Ptr(wrapped);

    if (luaL_newmetatable(state, "LuaWrapped")) {
        lua_pushstring(state, "__index");
        lua_pushvalue(state, -2);
        lua_settable(state, -3);
        luaL_openlib(state, NULL, methods, 0);
    }
    lua_setmetatable(state, -2);
}

The metamethod __gcis there to remove the class LuaWrapped::Ptr(which is a wrapper for boost::shared_ptr). I think I will leave this and save the pointer in the lightuserdata field in a regular table.


( ):

void
LuaContext::push(lua_State* state, boost::shared_ptr<LuaWrapped> wrapped) {
    static struct luaL_Reg methods[] = {
        { "__index", LuaWrapped::static_get },
        { "__newindex", LuaWrapped::static_set },
        { "__len", LuaWrapped::static_len },
        { "__ipairs", LuaWrapped::static_ipairs },
        { "__pairs", LuaWrapped::static_pairs },
        { "__gc", LuaWrapped::static_gc },
        { "__eq", LuaWrapped::static_eq },
        { NULL, NULL }
    };

    lua_newtable(state);
    LuaContext::push(state, "pointer");
    lua_pushlightuserdata(state, new LuaWrapped::Ptr(wrapped));
    lua_settable(state, -3);

    lua_newtable(state);
    luaL_openlib(state, NULL, methods, 0);
    lua_setmetatable(state, -2);
}

int
LuaWrapped::static_get(lua_State* state) {
    int argc = lua_gettop(state);
    for (int i = 1; i <= argc; i++) {
        const char *type = lua_typename(state, i);
        std::cout << type << std::endl;
    }
    ....

:

,

get (Lua 5.2, Ubuntu 14.04):

boolean, userdata​​p >

+4
1

- , / .

lua 5.2 lua_setuservalue lua_getuservalue . , .

lua 5.1 lua_setfenv lua_getfenv, .

+3

Source: https://habr.com/ru/post/1570782/


All Articles