2015-01-11 7 views
4

나는 userdata 객체를 사용하여 잘 작동하는 스크립팅 시스템을 가지고있다. 그러나, 나는 이제 일반 테이블을 가질 수있는 내 userdata에 대한 속성을 원합니다.lua 테이블에 메타 테이블 useratable 추가하기

정상적인 테이블을 만들고 메타 테이블을 설정하여 현재 사용중인 메타 메서드 집합을 사용한다고 생각합니다. 그러나이 작업을 수행하는 방법을 이해하는 데 어려움을 겪고 있습니다. 간단한 조정 만 수행하면됩니다. 지금은 그것을 볼 수 없다.

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 메타 메소드의 (a boost::shared_ptr에 래퍼 임) LuaWrapped::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에

예상 출력 :

테이블,

실제 문자열 get (Lua 5.2, Ubuntu 14.04)에서 출력 :

유저 데이터와 함께 임의의 데이터 저장 516,

부울, 유저 데이터

+0

사용자 데이터의 속성으로 테이블을 저장하거나 테이블을 사용자 데이터/개체 *로 사용할 수있게 하시겠습니까? –

+0

@etanreisner 표를 속성으로 사용하고 싶습니다. userdata metatable을 가진 일반 테이블을 사용하는 아이디어는 이것을 구현하는 방법처럼 보입니다 (하지만 다른 솔루션을 사용하게되어 매우 기쁩니다). –

+0

나는 왜 테이블을 엉망으로 만들려고하는지 알아 내려고하고있다. 요점은 userdata에 테이블을 저장하는 것이고 다른 점은 userdata에 다른 값을 저장하는 것입니다 (테이블을 userdata와 연결하고 그 안에 참조를 저장하면됩니다). 현재 사용자 데이터에 속성을 어떻게 저장하고 있습니까? –

답변

3

는 환경/uservalues가있는 유저 데이터 것입니다.

이 작업을 수행하는 방법은 lua_setuservaluelua_getuservalue 함수를 사용하여 테이블을 userdata와 연결하는 것입니다. 그런 다음이 테이블을 사용하여 사용자 데이터와 관련된 임의의 값을 저장하고 검색 할 수 있습니다.

루아 5.1에서보다 일반적인 환경 개념은 lua_setfenvlua_getfenv을 통해이 목적으로 사용되었지만 개념은 동일합니다.