summaryrefslogtreecommitdiffstats
path: root/src/Bindings/LuaState.cpp
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2017-01-09 15:56:16 +0100
committerGitHub <noreply@github.com>2017-01-09 15:56:16 +0100
commitf62711f97cd8b337ca4823bb6d1834f324762fc7 (patch)
treeb50c1f2e89f1fc6f8b3c41097d9eae7690d291fd /src/Bindings/LuaState.cpp
parentAdded 1.11 smelting recipes and fuels (#3526) (diff)
downloadcuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.tar
cuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.tar.gz
cuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.tar.bz2
cuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.tar.lz
cuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.tar.xz
cuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.tar.zst
cuberite-f62711f97cd8b337ca4823bb6d1834f324762fc7.zip
Diffstat (limited to '')
-rw-r--r--src/Bindings/LuaState.cpp82
1 files changed, 67 insertions, 15 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 50ce04f7c..61d206109 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -44,9 +44,69 @@ extern "C"
const cLuaState::cRet cLuaState::Return = {};
const cLuaState::cNil cLuaState::Nil = {};
-/** Each Lua state stores a pointer to its creating cLuaState in Lua globals, under this name.
-This way any cLuaState can reference the main cLuaState's TrackedCallbacks, mutex etc. */
-static const char * g_CanonLuaStateGlobalName = "_CuberiteInternal_CanonLuaState";
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// cCanonLuaStates:
+
+/** Tracks the canon cLuaState instances for each lua_State pointer.
+Used for tracked refs - the ref needs to be tracked by a single cLuaState (the canon state), despite being created from a different (attached) cLuaState.
+The canon state must be available without accessing the Lua state itself (so it cannot be stored within Lua). */
+class cCanonLuaStates
+{
+public:
+ /** Returns the canon Lua state for the specified lua_State pointer. */
+ static cLuaState * GetCanonState(lua_State * a_LuaState)
+ {
+ auto & inst = GetInstance();
+ cCSLock lock(inst.m_CS);
+ auto itr = inst.m_CanonStates.find(a_LuaState);
+ if (itr == inst.m_CanonStates.end())
+ {
+ return nullptr;
+ }
+ return itr->second;
+ }
+
+ /** Adds a new canon cLuaState instance to the map.
+ Used when a new Lua state is created, this informs the map that a new canon Lua state should be tracked. */
+ static void Add(cLuaState & a_LuaState)
+ {
+ auto & inst = GetInstance();
+ cCSLock lock(inst.m_CS);
+ ASSERT(inst.m_CanonStates.find(a_LuaState) == inst.m_CanonStates.end());
+ inst.m_CanonStates[a_LuaState.operator lua_State *()] = &a_LuaState;
+ }
+
+ /** Removes the bindings between the specified canon state and its lua_State pointer.
+ Used when a Lua state is being closed. */
+ static void Remove(cLuaState & a_LuaState)
+ {
+ auto & inst = GetInstance();
+ cCSLock lock(inst.m_CS);
+ auto itr = inst.m_CanonStates.find(a_LuaState);
+ ASSERT(itr != inst.m_CanonStates.end());
+ inst.m_CanonStates.erase(itr);
+ }
+
+protected:
+ /** The mutex protecting m_CanonStates against multithreaded access. */
+ cCriticalSection m_CS;
+
+ /** Map of lua_State pointers to their canon cLuaState instances. */
+ std::map<lua_State *, cLuaState *> m_CanonStates;
+
+
+ /** Returns the singleton instance of this class. */
+ static cCanonLuaStates & GetInstance(void)
+ {
+ static cCanonLuaStates canonLuaStates;
+ return canonLuaStates;
+ }
+};
@@ -426,10 +486,7 @@ void cLuaState::Create(void)
luaL_openlibs(m_LuaState);
m_IsOwned = true;
cLuaStateTracker::Add(*this);
-
- // Add the CanonLuaState value into the Lua state, so that we can get it from anywhere:
- lua_pushlightuserdata(m_LuaState, reinterpret_cast<void *>(this));
- lua_setglobal(m_LuaState, g_CanonLuaStateGlobalName);
+ cCanonLuaStates::Add(*this);
}
@@ -493,6 +550,7 @@ void cLuaState::Close(void)
}
}
+ cCanonLuaStates::Remove(*this);
cLuaStateTracker::Del(*this);
lua_close(m_LuaState);
m_LuaState = nullptr;
@@ -2146,15 +2204,9 @@ void cLuaState::LogStackValues(lua_State * a_LuaState, const char * a_Header)
-cLuaState * cLuaState::QueryCanonLuaState(void)
+cLuaState * cLuaState::QueryCanonLuaState(void) const
{
- // Get the CanonLuaState global from Lua:
- auto cb = WalkToNamedGlobal(g_CanonLuaStateGlobalName);
- if (!cb.IsValid())
- {
- return nullptr;
- }
- return reinterpret_cast<cLuaState *>(lua_touserdata(m_LuaState, -1));
+ return cCanonLuaStates::GetCanonState(m_LuaState);
}