4

ユーザーデータ オブジェクトを使用して適切に動作するスクリプト システムがあります。ただし、通常のテーブルを取ることができるユーザーデータにプロパティが必要になりました。

私がすべきことは、通常のテーブルを作成し、現在のメタメソッドのセットを使用するようにメタテーブルを設定することだと思いますが、これを行う方法を理解するのに苦労しています-単純な微調整だと確信しています。今それ。

私の既存のコードは次のようになります。

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);
}

__gcクラスを削除するためのメタメソッドがありLuaWrapped::Ptrます(これは a のラッパーboost::shared_ptrです)。それはそのままにして、ポインターを通常のテーブルの lightuserdata フィールドに格納すると思います。


通常のテーブルの問題に対する実験的なカスタム メタテーブル (コメントでの議論による):

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):

ブール値、ユーザーデータ

4

1 に答える 1