[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Self-referring userdata
- From: Daan Nusman <d.nusman@...>
- Date: Thu, 24 Mar 2011 17:11:23 +0100
Hi folks,
I'm wondering if there's a better way of doing this:
in a C userdata object, I want to call some Lua funcion with the same C
userdata as parameter. AFAIK, for this to work I need a reference to the
userdata, which I create when the userdata is created and then keep in
the userdata itself. Because this is a cyclic reference, I must create
an extra weak-valued registry to keep all those references in.
Is there a better way? In other words, can I push the userdata on the
stack given only the pointer to that userdata? That would be nnnnnice.
Extended example (broken code, this is meant as an illustration):
-------- Definition -----------
struct NuggetHandle
{
int m_SelfRef; // Reference to self userdata. This is
stored in the weak self-ref registry in m_Lib, NOT in LUA_REGISTRYINDEX!
This makes sure the ref is removed
// moar data
};
-------- Creation of the object --------
// Create new Lua Nugget object.
NuggetHandle* newNugget = (NuggetHandle*)lua_newuserdata(L, someSize);
luaL_getmetatable(L, NUGGET_LUA_TYPENAME);
lua_setmetatable(L, -2);
// Set self ref into weak registry
lua_rawgeti(L, LUA_REGISTRYINDEX,
nclass->m_Lib->m_SelfRefRegistry); // get self ref reg
lua_pushvalue(L, -2);
newNugget->m_SelfRef = luaL_ref(L, -2); // store into self
ref registry
lua_pop(L, 1); // pop self ref registry
-------- Calling a callback ---------------
void NuggetHandle::passOnCallback(lua_State* L)
{
// note that we only have the userdata pointer here, for example we got
// called from a system-defined UI callback
lua_pushSomeFunction(L); // push some Lua callback function on
the stack we want to call
// Push self onto Lua stack: ouch! get the weak registry, get
the reference, pop weak registry
lua_rawgeti(L, LUA_REGISTRYINDEX, m_Class->m_Lib->m_SelfRefRegistry);
lua_rawgeti(L, -1, m_SelfRef);
lua_remove(L, -2);
lua_pushstring(L, "yay more params");
lua_call(L, 2, 0); // first param: reference to self
userdata
}
Thanks,
Daan