From 0f51f7e35883936a64857a12ca5a97eaa1c9e190 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 14 Aug 2016 16:26:31 +0200 Subject: Fixed cWorld:ChunkStay bindings. (#3319) Introduced new cLuaState::cOptionalCallback for representing optional callbacks (nil from Lua side). Introduced new cLuaState::cStackTable class for easy access to Lua table's elements. Fixes #3305. --- src/Bindings/LuaState.cpp | 122 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 12 deletions(-) (limited to 'src/Bindings/LuaState.cpp') diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index e6a94091e..fd29e8e34 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -264,6 +264,26 @@ bool cLuaState::cCallback::RefStack(cLuaState & a_LuaState, int a_StackPos) +//////////////////////////////////////////////////////////////////////////////// +// cLuaState::cOptionalCallback: + +bool cLuaState::cOptionalCallback::RefStack(cLuaState & a_LuaState, int a_StackPos) +{ + // If the stack pos is nil, make this an empty callback: + if (lua_isnil(a_LuaState, a_StackPos)) + { + Clear(); + return true; + } + + // Use default cCallback implementation: + return Super::RefStack(a_LuaState, a_StackPos); +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cLuaState::cTableRef: @@ -282,6 +302,45 @@ bool cLuaState::cTableRef::RefStack(cLuaState & a_LuaState, int a_StackPos) +//////////////////////////////////////////////////////////////////////////////// +// cLuaState::cStackTable: + +cLuaState::cStackTable::cStackTable(cLuaState & a_LuaState, int a_StackPos): + m_LuaState(a_LuaState), + m_StackPos(a_StackPos) +{ + ASSERT(lua_istable(a_LuaState, a_StackPos)); +} + + + + + +void cLuaState::cStackTable::ForEachArrayElement(std::function a_ElementCallback) const +{ + auto numElements = luaL_getn(m_LuaState, m_StackPos); + #ifdef _DEBUG + auto stackTop = lua_gettop(m_LuaState); + #endif + for (int idx = 1; idx <= numElements; idx++) + { + // Push the idx-th element of the array onto stack top and call the callback: + lua_rawgeti(m_LuaState, m_StackPos, idx); + auto shouldAbort = a_ElementCallback(m_LuaState, idx); + ASSERT(lua_gettop(m_LuaState) == stackTop + 1); // The element callback must not change the Lua stack below the value + lua_pop(m_LuaState, 1); + if (shouldAbort) + { + // The callback wants to abort + return; + } + } +} + + + + + //////////////////////////////////////////////////////////////////////////////// // cLuaState: @@ -1086,35 +1145,35 @@ bool cLuaState::GetStackValue(int a_StackPos, cCallbackPtr & a_Callback) -bool cLuaState::GetStackValue(int a_StackPos, cCallbackSharedPtr & a_Callback) +bool cLuaState::GetStackValue(int a_StackPos, cOptionalCallback & a_Callback) { - if (a_Callback == nullptr) - { - a_Callback = std::make_shared(); - } - return a_Callback->RefStack(*this, a_StackPos); + return a_Callback.RefStack(*this, a_StackPos); } -bool cLuaState::GetStackValue(int a_StackPos, cTableRef & a_TableRef) +bool cLuaState::GetStackValue(int a_StackPos, cOptionalCallbackPtr & a_Callback) { - return a_TableRef.RefStack(*this, a_StackPos); + if (a_Callback == nullptr) + { + a_Callback = cpp14::make_unique(); + } + return a_Callback->RefStack(*this, a_StackPos); } -bool cLuaState::GetStackValue(int a_StackPos, cTableRefPtr & a_TableRef) +bool cLuaState::GetStackValue(int a_StackPos, cCallbackSharedPtr & a_Callback) { - if (a_TableRef == nullptr) + if (a_Callback == nullptr) { - a_TableRef = cpp14::make_unique(); + a_Callback = std::make_shared(); } - return a_TableRef->RefStack(*this, a_StackPos); + return a_Callback->RefStack(*this, a_StackPos); } @@ -1145,6 +1204,45 @@ bool cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref) +bool cLuaState::GetStackValue(int a_StackPos, cStackTablePtr & a_StackTable) +{ + // Only allow tables to be stored in a_StackTable: + if (!lua_istable(m_LuaState, a_StackPos)) + { + return false; + } + + // Assign the StackTable to the specified stack position: + a_StackTable = cpp14::make_unique(*this, a_StackPos); + return true; +} + + + + + +bool cLuaState::GetStackValue(int a_StackPos, cTableRef & a_TableRef) +{ + return a_TableRef.RefStack(*this, a_StackPos); +} + + + + + +bool cLuaState::GetStackValue(int a_StackPos, cTableRefPtr & a_TableRef) +{ + if (a_TableRef == nullptr) + { + a_TableRef = cpp14::make_unique(); + } + return a_TableRef->RefStack(*this, a_StackPos); +} + + + + + bool cLuaState::GetStackValue(int a_StackPos, cTrackedRef & a_Ref) { return a_Ref.RefStack(*this, a_StackPos); -- cgit v1.2.3