1
0

cLuaState::cRef can be unbound and re-bound.

This will allow us to store Lua references as member variables in classes and initialize those later than in the constructor.
This commit is contained in:
madmaxoft 2014-02-09 18:39:22 +01:00
parent 4bcaf302b9
commit 310a25c456
2 changed files with 63 additions and 12 deletions

View File

@ -1240,13 +1240,21 @@ int cLuaState::ReportFnCallErrors(lua_State * a_LuaState)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cLuaState::cRef:
cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) :
m_LuaState(a_LuaState)
cLuaState::cRef::cRef(void) :
m_LuaState(NULL),
m_Ref(LUA_REFNIL)
{
ASSERT(m_LuaState.IsValid());
lua_pushvalue(m_LuaState, a_StackPos); // Push a copy of the value at a_StackPos onto the stack
m_Ref = luaL_ref(m_LuaState, LUA_REGISTRYINDEX);
}
cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) :
m_LuaState(NULL),
m_Ref(LUA_REFNIL)
{
RefStack(a_LuaState, a_StackPos);
}
@ -1255,14 +1263,44 @@ cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) :
cLuaState::cRef::~cRef()
{
ASSERT(m_LuaState.IsValid());
if (IsValid())
if (m_LuaState != NULL)
{
luaL_unref(m_LuaState, LUA_REGISTRYINDEX, m_Ref);
UnRef();
}
}
void cLuaState::cRef::RefStack(cLuaState & a_LuaState, int a_StackPos)
{
ASSERT(a_LuaState.IsValid());
if (m_LuaState != NULL)
{
UnRef();
}
m_LuaState = &a_LuaState;
lua_pushvalue(a_LuaState, a_StackPos); // Push a copy of the value at a_StackPos onto the stack
m_Ref = luaL_ref(a_LuaState, LUA_REGISTRYINDEX);
}
void cLuaState::cRef::UnRef(void)
{
ASSERT(m_LuaState->IsValid()); // The reference should be destroyed before destroying the LuaState
if (IsValid())
{
luaL_unref(*m_LuaState, LUA_REGISTRYINDEX, m_Ref);
}
m_LuaState = NULL;
m_Ref = LUA_REFNIL;
}

View File

@ -65,14 +65,27 @@ class cLuaState
{
public:
/** Used for storing references to object in the global registry */
/** Used for storing references to object in the global registry.
Can be bound (contains a reference) or unbound (doesn't contain reference).
The reference can also be reset by calling RefStack(). */
class cRef
{
public:
/** Creates an unbound reference object. */
cRef(void);
/** Creates a reference in the specified LuaState for object at the specified StackPos */
cRef(cLuaState & a_LuaState, int a_StackPos);
~cRef();
/** Creates a reference to Lua object at the specified stack pos, binds this object to it.
Calls UnRef() first if previously bound to another reference. */
void RefStack(cLuaState & a_LuaState, int a_StackPos);
/** Removes the bound reference, resets the object to Unbound state. */
void UnRef(void);
/** Returns true if the reference is valid */
bool IsValid(void) const {return (m_Ref != LUA_REFNIL); }
@ -80,7 +93,7 @@ public:
operator int(void) const { return m_Ref; }
protected:
cLuaState & m_LuaState;
cLuaState * m_LuaState;
int m_Ref;
} ;