diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index ac5ce47e1..22f342467 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -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; +} + + + + diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index dda45bb28..1c9c99e69 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -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; } ;