From 47a497fa895fa5f353ba593d4bb232ea514e66c9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 9 Feb 2014 20:39:45 +0100 Subject: [PATCH] First working version of cLuaChunkStay. It works, but has random failures, probably due to threading issues. --- src/Bindings/LuaChunkStay.cpp | 45 ++++++++++++++++++++++++++------- src/Bindings/LuaChunkStay.h | 21 ++++++++++----- src/Bindings/ManualBindings.cpp | 41 ++++++++++++++++++++++++++++++ src/ChunkStay.h | 2 +- 4 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 606f7694f..f84964f56 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -11,20 +11,29 @@ +cLuaChunkStay::cLuaChunkStay(void) : + m_LuaState((lua_State *)NULL) // Want a detached Lua state by default +{ +} + + + + + void cLuaChunkStay::Enable( - cWorld & a_World, cLuaState & a_LuaState, - const cLuaState::cRef & a_OnChunkAvailable, const cLuaState::cRef & a_OnAllChunksAvailable + cWorld & a_World, lua_State * a_LuaState, + int a_OnChunkAvailableStackPos, int a_OnAllChunksAvailableStackPos ) { - if (m_LuaState != NULL) + if (m_LuaState.IsValid()) { LOGWARNING("LuaChunkStay: Already enabled. Ignoring this call."); - a_LuaState.LogStackTrace(); + cLuaState::LogStackTrace(a_LuaState); return; } - m_LuaState = &a_LuaState; - m_OnChunkAvailable = a_OnAllChunksAvailable; - m_OnAllChunksAvailable = a_OnAllChunksAvailable; + m_LuaState.Attach(a_LuaState); + m_OnChunkAvailable.RefStack(m_LuaState, a_OnChunkAvailableStackPos); + m_OnAllChunksAvailable.RefStack(m_LuaState, a_OnAllChunksAvailableStackPos); super::Enable(*a_World.GetChunkMap()); } @@ -32,9 +41,27 @@ void cLuaChunkStay::Enable( +void cLuaChunkStay::Disable(void) +{ + super::Disable(); + + // If the state was valid (bound to Lua functions), unbind those functions: + if (!m_LuaState.IsValid()) + { + return; + } + m_OnAllChunksAvailable.UnRef(); + m_OnChunkAvailable.UnRef(); + m_LuaState.Detach(); +} + + + + + void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ) { - m_LuaState->Call(m_OnChunkAvailable, a_ChunkX, a_ChunkZ); + m_LuaState.Call(m_OnChunkAvailable, a_ChunkX, a_ChunkZ); } @@ -43,7 +70,7 @@ void cLuaChunkStay::OnChunkAvailable(int a_ChunkX, int a_ChunkZ) void cLuaChunkStay::OnAllChunksAvailable(void) { - m_LuaState->Call(m_OnAllChunksAvailable); + m_LuaState.Call(m_OnAllChunksAvailable); } diff --git a/src/Bindings/LuaChunkStay.h b/src/Bindings/LuaChunkStay.h index e9d87d7f6..0ab73f669 100644 --- a/src/Bindings/LuaChunkStay.h +++ b/src/Bindings/LuaChunkStay.h @@ -24,23 +24,28 @@ class cLuaChunkStay public: // Allow Lua to construct objects of this class: - cLuaChunkStay(void) {} + cLuaChunkStay(void); // Allow Lua to garbage-collect objects of this class: - ~cLuaChunkStay() {} + ~cLuaChunkStay() { } // tolua_end - /** Enabled the ChunkStay for the specified world, with the specified Lua callbacks. + /** Enables the ChunkStay for the specified world, with the specified Lua callbacks. Exported in ManualBindings. */ void Enable( - cWorld & a_World, cLuaState & a_LuaState, - const cLuaState::cRef & a_OnChunkAvailable, const cLuaState::cRef & a_OnAllChunksAvailable + cWorld & a_World, lua_State * a_LuaState, + int a_OnChunkAvailableStackPos, int a_OnAllChunksAvailableStackPos ); + // tolua_begin + + /** Disables the ChunkStay. Cleans up the bound Lua state and callbacks */ + virtual void Disable(void); + protected: /** The Lua state associated with the callbacks. Only valid when enabled. */ - cLuaState * m_LuaState; + cLuaState m_LuaState; /** The Lua function to call in OnChunkAvailable. Only valid when enabled. */ cLuaState::cRef m_OnChunkAvailable; @@ -51,7 +56,9 @@ protected: // cChunkStay overrides: virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) override; virtual void OnAllChunksAvailable(void) override; -} ; // tolua_export +} ; + +// tolua_end diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 841ec5cf2..3571fd7ea 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -8,6 +8,7 @@ #include "PluginLua.h" #include "PluginManager.h" #include "LuaWindow.h" +#include "LuaChunkStay.h" #include "../Root.h" #include "../World.h" #include "../Entities/Player.h" @@ -1638,6 +1639,42 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) +static int tolua_cLuaChunkStay_Enable(lua_State * tolua_S) +{ + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cLuaChunkStay") || + !L.CheckParamUserType(2, "cWorld") || + !L.CheckParamFunction(3, 4) + ) + { + return 0; + } + + // Read the params: + cLuaChunkStay * ChunkStay = (cLuaChunkStay *)tolua_tousertype(tolua_S, 1, NULL); + if (ChunkStay == NULL) + { + LOGWARNING("cLuaChunkStay:Enable(): invalid self"); + L.LogStackTrace(); + return 0; + } + cWorld * World = (cWorld *)tolua_tousertype(tolua_S, 2, NULL); + if (World == NULL) + { + LOGWARNING("cLuaChunkStay:Enable(): invalid world parameter"); + L.LogStackTrace(); + return 0; + } + + ChunkStay->Enable(*World, tolua_S, 3, 4); + return 0; +} + + + + + static int tolua_cPlayer_GetGroups(lua_State* tolua_S) { cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); @@ -2403,6 +2440,10 @@ void ManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "LogStackTrace", tolua_cPluginManager_LogStackTrace); tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cLuaChunkStay"); + tolua_function(tolua_S, "Enable", tolua_cLuaChunkStay_Enable); + tolua_endmodule(tolua_S); + tolua_beginmodule(tolua_S, "cPlayer"); tolua_function(tolua_S, "GetGroups", tolua_cPlayer_GetGroups); tolua_function(tolua_S, "GetResolvedPermissions", tolua_cPlayer_GetResolvedPermissions); diff --git a/src/ChunkStay.h b/src/ChunkStay.h index a6274812e..1e9cd69e8 100644 --- a/src/ChunkStay.h +++ b/src/ChunkStay.h @@ -62,7 +62,7 @@ public: /** Disables the ChunkStay, the chunks are released and the ChunkStay object can be edited with Add() and Remove() again*/ - void Disable(void); + virtual void Disable(void); // tolua_end