루아 클래스 개체를 스택에 푸시하려고합니다. 객체에 대한 포인터는 여러 함수에 의해 반환 될 수 있습니다.Lua 사용자 데이터 개체 관리
다른 말로하면 '==', '~ ='등을 사용할 수 있도록 userdata 값을 푸시해야합니다. 따라서 동일한 C++ 객체 인 경우 userdata 포인터가 동일해야합니다.
-- this should push the object onto the stack
local firstObject = GetClassObject();
firstObject:doSomething();
firstObject는 루아 스크립트에 의해 저장되고 나중에 코드에서 내가 다시이 작업을 수행해야합니다 같은 C++ 클래스 포인터가 어딘가에 이미 존재하는 경우
-- the c++ class pointer has not changed here
-- so I would like to push the same userdata pointer as in the first call...
local object = GetClassObject();
-- if I would not do this the following here would fail... :C
if object == firstObject then
...
내 누름 기능은 기본적으로 확인해야합니다 (아무리 내가 밀어도 객체가 1 : 1로 작동해야 함)
그렇지 않은 경우 새 userdata를 만들고 그것을 클래스 객체에 전달합니다.
template <typename T>
void Push(const T &tObject)
{
lua_State *L = GetLuaState();
// Here i need to check if such a C++ object (the same tObject)
// already exists!
//
// If so i want to push the associated userdata.
// Object didn't exist yet -> we need a new userdata
void *pUserData = lua_newuserdata(L, sizeof(tObject));
*reinterpret_cast<T*>(pUserData) = tObject;
}
template <typename T>
void Push(const T &tObject, const char *pszTable)
{
Push(tObject);
lua_State *L = GetLuaState();
luaL_getmetatable(L, pszTable);
lua_setmetatable(L, -2);
}
template <typename T>
T& Get(int nIndex)
{
T *pUserData = reinterpret_cast<T*>(lua_touserdata(GetLuaState(), nIndex));
if(pUserData == nullptr)
throw std::exception("Invalid userdata!");
return *pUserData;
}
template <typename T>
T& Get(int nIndex, const char *pszTable)
{
T *pUserData = reinterpret_cast<T*>(LuaToUData(nIndex, pszTable));
if(pUserData == nullptr)
throw std::exception("Invalid userdata!");
return *pUserData;
}
LuaToUData 내가 루아 오류가 발생하지 않도록 쓴 자신의 기능입니다 : 여기
내 코드의void* LuaToUData(int nIndex, const char *pszTable)
{
void *pUserData = lua_touserdata(g_luaState, nIndex);
if(pUserData != nullptr)
{
if(lua_getmetatable(g_luaState, nIndex) != 0)
{
lua_getfield(g_luaState, LUA_REGISTRYINDEX, pszTable);
bool bEqual = (lua_rawequal(g_luaState, -1, -2) == 1);
lua_pop(g_luaState, 2);
if(bEqual)
return pUserData;
}
}
return nullptr;
}
나는 당신이 여기서하려고하는 것을 정확히 해결하는 것이 어렵다는 것을 알고 있습니다. 당신이 만든 Lua userdata 인스턴스를 그냥 캐시하려고합니까? – Rook
나는 '==', '~ ='등을 사용할 수있는 능력을 유지하면서 userdata 값을 푸시하려고합니다. 따라서 userdata 포인터는 동일한 C++ 객체 인 경우 동일해야합니다. – user1478081
Lua userdata 객체는 참조에 의해 내부적으로 비교됩니다. 동일한 기본 포인터에서 생성 된 두 개의 사용자 데이터 인스턴스가 동일한 것으로 비교되어야합니다. 이 경우'=='이 작동하지 않는다고 말하고 있습니까? 그리고'__eq' 메타 테이블 엔트리를 오버라이드 시켰습니까? – Rook