From a628b043ec5c9021ca719fc6e0ddae5c8746d1c8 Mon Sep 17 00:00:00 2001 From: zerver Date: Thu, 23 Sep 2010 21:02:48 +0200 Subject: [PATCH] Split LuaHandle into Draw/Sim (can be disabled via DUAL_LUA_STATES) --- rts/Game/UI/KeyAutoBinder.cpp | 31 +-- rts/Game/UI/KeyAutoBinder.h | 4 +- rts/Game/UI/LuaUI.cpp | 43 ++-- rts/Game/UI/LuaUI.h | 4 +- rts/Lua/LuaCallInCheck.h | 36 +++- rts/Lua/LuaGaia.cpp | 22 +-- rts/Lua/LuaGaia.h | 4 +- rts/Lua/LuaHandle.cpp | 249 ++++++++++++++--------- rts/Lua/LuaHandle.h | 172 ++++++++++------ rts/Lua/LuaHandleSynced.cpp | 293 ++++++++++++++++++---------- rts/Lua/LuaHandleSynced.h | 39 ++-- rts/Lua/LuaLobby.cpp | 63 +++--- rts/Lua/LuaLobby.h | 7 +- rts/Lua/LuaOpenGL.cpp | 4 +- rts/Lua/LuaParser.cpp | 30 +-- rts/Lua/LuaRules.cpp | 106 +++++----- rts/Lua/LuaRules.h | 8 +- rts/Lua/LuaSyncedRead.cpp | 4 +- rts/Lua/LuaUnsyncedCtrl.cpp | 4 +- rts/Lua/LuaUnsyncedRead.cpp | 4 +- rts/Sim/Units/COB/LuaUnitScript.cpp | 5 +- rts/System/EventClient.cpp | 2 +- rts/System/EventClient.h | 4 +- rts/System/EventHandler.cpp | 7 +- rts/System/Platform/Threading.cpp | 23 +++ rts/System/Platform/Threading.h | 2 + rts/System/SpringApp.cpp | 28 +-- rts/System/SpringApp.h | 1 + rts/lib/gml/gml.cpp | 3 + rts/lib/gml/gml.h | 3 + 30 files changed, 746 insertions(+), 459 deletions(-) diff --git a/rts/Game/UI/KeyAutoBinder.cpp b/rts/Game/UI/KeyAutoBinder.cpp index f166853e4c3..8eeee9ad70f 100644 --- a/rts/Game/UI/KeyAutoBinder.cpp +++ b/rts/Game/UI/KeyAutoBinder.cpp @@ -11,6 +11,7 @@ #include "KeyBindings.h" #include "Game/GameSetup.h" #include "Sim/Misc/Team.h" +#include "Lua/LuaCallInCheck.h" #include "Lua/LuaConstGame.h" #include "Lua/LuaUnitDefs.h" #include "Lua/LuaWeaponDefs.h" @@ -54,11 +55,12 @@ static const string endlStr = "\r\n"; CKeyAutoBinder::CKeyAutoBinder() : CLuaHandle("KeyAutoBinder", 1234, false) { - if (L == NULL) { + if (!IsValid()) return; - } - LoadCompareFunc(); + BEGIN_ITERATE_LUA_STATES(); + + LoadCompareFunc(L); // load the standard libraries LUA_OPEN_LIB(L, luaopen_base); @@ -77,7 +79,10 @@ CKeyAutoBinder::CKeyAutoBinder() !AddEntriesToTable(L, "WeaponDefs", LuaWeaponDefs::PushEntries)) { logOutput.Print("KeyAutoBinder: error loading lua libraries\n"); } - lua_settop(L, 0); + + lua_settop(L, 0); + + END_ITERATE_LUA_STATES(); } @@ -98,11 +103,10 @@ string CKeyAutoBinder::LoadFile(const string& filename) const } -bool CKeyAutoBinder::LoadCode(const string& code, const string& debug) +bool CKeyAutoBinder::LoadCode(lua_State *L, const string& code, const string& debug) { - if (L == NULL) { + if (!IsValid()) return false; - } lua_settop(L, 0); @@ -126,7 +130,7 @@ bool CKeyAutoBinder::LoadCode(const string& code, const string& debug) } -bool CKeyAutoBinder::LoadCompareFunc() +bool CKeyAutoBinder::LoadCompareFunc(lua_State *L) { string code = endlStr; @@ -149,7 +153,7 @@ bool CKeyAutoBinder::LoadCompareFunc() logOutput.Print(code); } - if (!LoadCode(code, "Compare()")) { + if (!LoadCode(L, code, "Compare()")) { return false; } @@ -177,9 +181,10 @@ bool CKeyAutoBinder::BindBuildType(const string& keystr, const vector& sortCriteria, const vector& chords) { - if (L == NULL) { + if (!IsValid()) return false; - } + + SELECT_LUA_STATE(); lua_settop(L, 0); @@ -193,8 +198,8 @@ bool CKeyAutoBinder::BindBuildType(const string& keystr, logOutput.Print(sortCall); } - if (!LoadCode(reqCall, keystr + ":HasReqs()") || - !LoadCode(sortCall, keystr + ":IsBetter()")) { + if (!LoadCode(L, reqCall, keystr + ":HasReqs()") || + !LoadCode(L, sortCall, keystr + ":IsBetter()")) { return false; } diff --git a/rts/Game/UI/KeyAutoBinder.h b/rts/Game/UI/KeyAutoBinder.h index 880a8201fce..2b2c7c20c89 100644 --- a/rts/Game/UI/KeyAutoBinder.h +++ b/rts/Game/UI/KeyAutoBinder.h @@ -26,8 +26,8 @@ class CKeyAutoBinder : public CLuaHandle private: string LoadFile(const string& filename) const; - bool LoadCode(const string& code, const string& debug); - bool LoadCompareFunc(); + bool LoadCode(lua_State *L, const string& code, const string& debug); + bool LoadCompareFunc(lua_State *L); string MakeRequirementCall(const vector& requirements); string MakeSortCriteriaCall(const vector& sortCriteria); string AddUnitDefPrefix(const string& text, const string& pre) const; diff --git a/rts/Game/UI/LuaUI.cpp b/rts/Game/UI/LuaUI.cpp index 74188037d8a..74214faeef8 100644 --- a/rts/Game/UI/LuaUI.cpp +++ b/rts/Game/UI/LuaUI.cpp @@ -97,7 +97,7 @@ void CLuaUI::LoadHandler() new CLuaUI(); - if (luaUI->L == NULL) { + if (!luaUI->IsValid()) { delete luaUI; } } @@ -121,7 +121,9 @@ CLuaUI::CLuaUI() { luaUI = this; - if (L == NULL) { + BEGIN_ITERATE_LUA_STATES(); + + if (!IsValid()) { return; } @@ -172,7 +174,7 @@ CLuaUI::CLuaUI() lua_pushvalue(L, LUA_GLOBALSINDEX); - AddBasicCalls(); // into Global + AddBasicCalls(L); // into Global lua_pushstring(L, "Script"); lua_rawget(L, -2); @@ -203,7 +205,7 @@ CLuaUI::CLuaUI() } lua_settop(L, 0); - if (!LoadCode(code, "luaui.lua")) { + if (!LoadCode(L, code, "luaui.lua")) { KillLua(); return; } @@ -212,16 +214,18 @@ CLuaUI::CLuaUI() eventHandler.AddClient(this); // update extra call-ins - UnsyncedUpdateCallIn("WorldTooltip"); - UnsyncedUpdateCallIn("MapDrawCmd"); + UnsyncedUpdateCallIn(L, "WorldTooltip"); + UnsyncedUpdateCallIn(L, "MapDrawCmd"); lua_settop(L, 0); + + END_ITERATE_LUA_STATES(); } CLuaUI::~CLuaUI() { - if (L != NULL) { + if (L_Sim != NULL || L_Draw != NULL) { Shutdown(); KillLua(); } @@ -253,9 +257,9 @@ string CLuaUI::LoadFile(const string& filename) const } -bool CLuaUI::HasCallIn(const string& name) +bool CLuaUI::HasCallIn(lua_State *L, const string& name) { - if (L == NULL) { + if (!IsValid()) { return false; } @@ -274,14 +278,14 @@ bool CLuaUI::HasCallIn(const string& name) } -bool CLuaUI::UnsyncedUpdateCallIn(const string& name) +bool CLuaUI::UnsyncedUpdateCallIn(lua_State *L, const string& name) { // never allow this call-in if (name == "Explosion") { return false; } - if (HasCallIn(name)) { + if (HasCallIn(L, name)) { eventHandler.InsertEvent(this, name); } else { eventHandler.RemoveEvent(this, name); @@ -293,13 +297,13 @@ bool CLuaUI::UnsyncedUpdateCallIn(const string& name) void CLuaUI::UpdateTeams() { if (luaUI) { - luaUI->fullCtrl = gs->godMode; - luaUI->ctrlTeam = gs->godMode ? AllAccessTeam : - (gu->spectating ? NoAccessTeam : gu->myTeam); - luaUI->fullRead = gu->spectatingFullView; - luaUI->readTeam = luaUI->fullRead ? AllAccessTeam : gu->myTeam; - luaUI->readAllyTeam = luaUI->fullRead ? AllAccessTeam : gu->myAllyTeam; - luaUI->selectTeam = gu->spectatingFullSelect ? AllAccessTeam : gu->myTeam; + luaUI->SetFullCtrl(gs->godMode); + luaUI->SetCtrlTeam(gs->godMode ? AllAccessTeam : + (gu->spectating ? NoAccessTeam : gu->myTeam)); + luaUI->SetFullRead(gu->spectatingFullView); + luaUI->SetReadTeam(luaUI->GetFullRead() ? AllAccessTeam : gu->myTeam); + luaUI->SetReadAllyTeam(luaUI->GetFullRead() ? AllAccessTeam : gu->myAllyTeam); + luaUI->SetSelectTeam(gu->spectatingFullSelect ? AllAccessTeam : gu->myTeam); } } @@ -475,6 +479,7 @@ void CLuaUI::ShockFront(float power, const float3& pos, float areaOfEffect) bool CLuaUI::HasLayoutButtons() { GML_RECMUTEX_LOCK(lua); // HasLayoutButtons + SELECT_LUA_STATE(); lua_checkstack(L, 2); @@ -833,6 +838,8 @@ bool CLuaUI::GetLuaCmdDescList(lua_State* L, int index, bool CLuaUI::HasUnsyncedXCall(const string& funcName) { + SELECT_LUA_STATE(); + lua_getglobal(L, funcName.c_str()); const bool haveFunc = lua_isfunction(L, -1); lua_pop(L, 1); diff --git a/rts/Game/UI/LuaUI.h b/rts/Game/UI/LuaUI.h index 030e7987e9d..2b28532d120 100644 --- a/rts/Game/UI/LuaUI.h +++ b/rts/Game/UI/LuaUI.h @@ -43,8 +43,8 @@ class CLuaUI : public CLuaHandle }; public: // call-ins - bool HasCallIn(const string& name); - bool UnsyncedUpdateCallIn(const string& name); + bool HasCallIn(lua_State *L, const string& name); + bool UnsyncedUpdateCallIn(lua_State *L, const string& name); void GameFrame(int frameNum); diff --git a/rts/Lua/LuaCallInCheck.h b/rts/Lua/LuaCallInCheck.h index e184c98cbbc..ac420f12d0b 100644 --- a/rts/Lua/LuaCallInCheck.h +++ b/rts/Lua/LuaCallInCheck.h @@ -18,10 +18,38 @@ class LuaCallInCheck { }; +#define DUAL_LUA_STATES 1 + +#if DUAL_LUA_STATES +#define BEGIN_ITERATE_LUA_STATES() lua_State *L_Cur = L_Sim; do { lua_State * const L = L_Cur +#define END_ITERATE_LUA_STATES() if(L_Cur == L_Draw) break; L_Cur = L_Draw; } while(true) +#ifndef LUA_SYNCED_ONLY +#define SELECT_LUA_STATE() lua_State * const L = Threading::IsSimThread() ? L_Sim : L_Draw +#else +#define SELECT_LUA_STATE() +#endif +#if defined(USE_GML) && GML_ENABLE_SIM +#define GML_DRCMUTEX_LOCK(name) boost::recursive_mutex::scoped_lock name##lock(Threading::IsSimThread() ? name##simmutex : name##drawmutex ) +#else +#define GML_DRCMUTEX_LOCK(name) +#endif + +#else + +#define BEGIN_ITERATE_LUA_STATES() lua_State * const L = L_Sim +#define END_ITERATE_LUA_STATES() +#ifndef LUA_SYNCED_ONLY +#define SELECT_LUA_STATE() lua_State * const L = L_Sim +#else +#define SELECT_LUA_STATE() +#endif +#define GML_DRCMUTEX_LOCK(name) GML_RECMUTEX_LOCK(name) +#endif + #if DEBUG_LUA -# define LUA_CALL_IN_CHECK(L) LuaCallInCheck ciCheck((L), __FUNCTION__); +# define LUA_CALL_IN_CHECK(L) SELECT_LUA_STATE(); LuaCallInCheck ciCheck((L), __FUNCTION__) #else -# define LUA_CALL_IN_CHECK(L) +# define LUA_CALL_IN_CHECK(L) SELECT_LUA_STATE() #endif #ifdef USE_GML // hack to add some degree of thread safety to LUA @@ -30,9 +58,9 @@ class LuaCallInCheck { # if GML_ENABLE_SIM # undef LUA_CALL_IN_CHECK # if DEBUG_LUA -# define LUA_CALL_IN_CHECK(L) GML_RECMUTEX_LOCK(lua); GML_CALL_DEBUGGER(); LuaCallInCheck ciCheck((L), __FUNCTION__); +# define LUA_CALL_IN_CHECK(L) GML_DRCMUTEX_LOCK(lua); SELECT_LUA_STATE(); GML_CALL_DEBUGGER(); LuaCallInCheck ciCheck((L), __FUNCTION__); # else -# define LUA_CALL_IN_CHECK(L) GML_RECMUTEX_LOCK(lua); GML_CALL_DEBUGGER(); +# define LUA_CALL_IN_CHECK(L) GML_DRCMUTEX_LOCK(lua); SELECT_LUA_STATE(); GML_CALL_DEBUGGER(); # endif # endif #endif diff --git a/rts/Lua/LuaGaia.cpp b/rts/Lua/LuaGaia.cpp index 5cbb8bb5ec4..bd545c9ea15 100644 --- a/rts/Lua/LuaGaia.cpp +++ b/rts/Lua/LuaGaia.cpp @@ -47,7 +47,7 @@ void CLuaGaia::LoadHandler() new CLuaGaia(); - if (luaGaia->L == NULL) { + if (!luaGaia->IsValid()) { delete luaGaia; } } @@ -67,18 +67,18 @@ CLuaGaia::CLuaGaia() { luaGaia = this; - if (L == NULL) { + if (!IsValid()) { return; } teamsLocked = true; - fullCtrl = true; - fullRead = true; - ctrlTeam = AllAccessTeam; //teamHandler->GaiaTeamID(); - readTeam = AllAccessTeam; - readAllyTeam = AllAccessTeam; - selectTeam = teamHandler->GaiaTeamID(); + SetFullCtrl(true, true); + SetFullRead(true, true); + SetCtrlTeam(AllAccessTeam, true); //teamHandler->GaiaTeamID(); + SetReadTeam(AllAccessTeam, true); + SetReadAllyTeam(AllAccessTeam, true); + SetSelectTeam(teamHandler->GaiaTeamID(), true); Init(LuaGaiaSyncedFilename, LuaGaiaUnsyncedFilename, SPRING_VFS_MAP); } @@ -86,7 +86,7 @@ CLuaGaia::CLuaGaia() CLuaGaia::~CLuaGaia() { - if (L != NULL) { + if (L_Sim != NULL || L_Draw != NULL) { Shutdown(); KillLua(); } @@ -94,13 +94,13 @@ CLuaGaia::~CLuaGaia() } -bool CLuaGaia::AddSyncedCode() +bool CLuaGaia::AddSyncedCode(lua_State *L) { return true; } -bool CLuaGaia::AddUnsyncedCode() +bool CLuaGaia::AddUnsyncedCode(lua_State *L) { /*lua_pushstring(L, "UNSYNCED"); lua_gettable(L, LUA_REGISTRYINDEX);*/ diff --git a/rts/Lua/LuaGaia.h b/rts/Lua/LuaGaia.h index 7434a9f0ff5..8997d462c9c 100644 --- a/rts/Lua/LuaGaia.h +++ b/rts/Lua/LuaGaia.h @@ -16,8 +16,8 @@ class CLuaGaia : public CLuaHandleSynced static void FreeHandler(); protected: - bool AddSyncedCode(); - bool AddUnsyncedCode(); + bool AddSyncedCode(lua_State *L); + bool AddUnsyncedCode(lua_State *L); private: CLuaGaia(); diff --git a/rts/Lua/LuaHandle.cpp b/rts/Lua/LuaHandle.cpp index 23b95d522a7..b0fc271ffeb 100644 --- a/rts/Lua/LuaHandle.cpp +++ b/rts/Lua/LuaHandle.cpp @@ -44,13 +44,12 @@ extern boost::uint8_t *keys; +CLuaHandle::staticLuaContextData CLuaHandle::S_Sim; +CLuaHandle::staticLuaContextData CLuaHandle::S_Draw; + bool CLuaHandle::devMode = false; bool CLuaHandle::modUICtrl = true; -CLuaHandle* CLuaHandle::activeHandle = NULL; -bool CLuaHandle::activeFullRead = false; -int CLuaHandle::activeReadAllyTeam = CEventClient::NoAccessTeam; - /******************************************************************************/ /******************************************************************************/ @@ -59,7 +58,6 @@ CLuaHandle::CLuaHandle(const string& _name, int _order, bool _userMode) : CEventClient(_name, _order, false), // FIXME userMode (_userMode), killMe (false), - synced (false), #ifdef DEBUG printTracebacks(true), #else @@ -67,8 +65,11 @@ CLuaHandle::CLuaHandle(const string& _name, int _order, bool _userMode) #endif callinErrors(0) { - L = lua_open(); - luaopen_debug(L); + SetSynced(false, true); + L_Sim = lua_open(); + luaopen_debug(L_Sim); + L_Draw = lua_open(); + luaopen_debug(L_Draw); } @@ -79,21 +80,31 @@ CLuaHandle::~CLuaHandle() // free the lua state KillLua(); - if (this == activeHandle) { - activeHandle = NULL; + if (this == GetStaticLuaContextData(false).activeHandle) { + GetStaticLuaContextData(false).activeHandle = NULL; + } + if (this == GetStaticLuaContextData(true).activeHandle) { + GetStaticLuaContextData(true).activeHandle = NULL; } } void CLuaHandle::KillLua() { - if (L != NULL) { - CLuaHandle* orig = activeHandle; - SetActiveHandle(); - lua_close(L); + if (L_Sim != NULL) { + CLuaHandle* orig = GetActiveHandle(false); + SetActiveHandle(false); + lua_close(L_Sim); SetActiveHandle(orig); + L_Sim = NULL; + } + if (L_Draw != NULL) { + CLuaHandle* orig = GetActiveHandle(true); + SetActiveHandle(true); + lua_close(L_Draw); + SetActiveHandle(orig); + L_Draw = NULL; } - L = NULL; } @@ -102,12 +113,13 @@ void CLuaHandle::KillLua() int CLuaHandle::KillActiveHandle(lua_State* L) { - if (activeHandle) { + CLuaHandle* ah = GetActiveHandle(); + if (ah) { const int args = lua_gettop(L); if ((args >= 1) && lua_isstring(L, 1)) { - activeHandle->killMsg = lua_tostring(L, 1); + ah->killMsg = lua_tostring(L, 1); } - activeHandle->killMe = true; + ah->killMe = true; } return 0; } @@ -142,7 +154,7 @@ bool CLuaHandle::AddEntriesToTable(lua_State* L, const char* name, } -bool CLuaHandle::LoadCode(const string& code, const string& debug) +bool CLuaHandle::LoadCode(lua_State *L, const string& code, const string& debug) { lua_settop(L, 0); @@ -163,7 +175,7 @@ bool CLuaHandle::LoadCode(const string& code, const string& debug) return false; } - CLuaHandle* orig = activeHandle; + CLuaHandle* orig = GetActiveHandle(); SetActiveHandle(); error = lua_pcall(L, 0, 0, 0); SetActiveHandle(orig); @@ -189,6 +201,9 @@ void CLuaHandle::CheckStack() { GML_RECMUTEX_LOCK(lua); // CheckStack - avoid bogus errors due to concurrency + ExecuteRecvFromSynced(); + + SELECT_LUA_STATE(); const int top = lua_gettop(L); if (top != 0) { logOutput.Print("WARNING: %s stack check: top = %i\n", GetName().c_str(), top); @@ -197,10 +212,53 @@ void CLuaHandle::CheckStack() } +void CLuaHandle::ExecuteRecvFromSynced() { + GML_STDMUTEX_LOCK(recv); + + for(int i = 0; i < delayedRecvFromSynced.size(); ++i) { + std::vector &ddv = delayedRecvFromSynced[i]; + + LUA_CALL_IN_CHECK(L); + lua_checkstack(L, ddv.size() + 2); + + for(int d = 0; d < ddv.size(); ++d) { + DelayData &ddt = ddv[d]; + switch (ddt.type) { + case LUA_TBOOLEAN: { + lua_pushboolean(L, ddt.bol); + break; + } + case LUA_TNUMBER: { + lua_pushnumber(L, ddt.num); + break; + } + case LUA_TSTRING: { + lua_pushlstring(L, ddt.str.c_str(), ddt.str.size()); + break; + } + case LUA_TNIL: { + lua_pushnil(L); + break; + } + default: { + lua_pushnil(L); + logOutput.Print("RecvFromSynced (execute): Invalid type for argument %d", d + 1); + break; // unhandled type + } + } + } + + RecvFromSynced(ddv.size()); + } + + delayedRecvFromSynced.clear(); +} + + /******************************************************************************/ /******************************************************************************/ -int CLuaHandle::SetupTraceback() +int CLuaHandle::SetupTraceback(lua_State *L) { if (!printTracebacks) return 0; @@ -216,11 +274,12 @@ int CLuaHandle::RunCallInTraceback(int inArgs, int outArgs, int errfuncIndex, st feclearexcept(streflop::FPU_Exceptions(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW)); #endif - CLuaHandle* orig = activeHandle; + CLuaHandle* orig = GetActiveHandle(); SetActiveHandle(); //! limit gc just to the time the correct ActiveHandle is bound, //! because some object could use __gc and try to access the ActiveHandle //! outside of SetActiveHandle this can be an incorrect enviroment or even null -> crash + SELECT_LUA_STATE(); lua_gc(L,LUA_GCRESTART,0); const int error = lua_pcall(L, inArgs, outArgs, errfuncIndex); lua_gc(L,LUA_GCSTOP,0); @@ -273,7 +332,7 @@ void CLuaHandle::Shutdown() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("Shutdown"); if (!cmdStr.GetGlobalFunc(L)) { @@ -292,7 +351,7 @@ void CLuaHandle::Load(CArchiveBase* archive) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("Load"); if (!cmdStr.GetGlobalFunc(L)) { @@ -314,7 +373,7 @@ void CLuaHandle::GamePreload() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("GamePreload"); if (!cmdStr.GetGlobalFunc(L)) { @@ -333,7 +392,7 @@ void CLuaHandle::GameStart() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("GameStart"); if (!cmdStr.GetGlobalFunc(L)) { @@ -352,7 +411,7 @@ void CLuaHandle::GameOver(const std::vector& winningAllyTeams) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("GameOver"); if (!cmdStr.GetGlobalFunc(L)) { @@ -379,7 +438,7 @@ void CLuaHandle::TeamDied(int teamID) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("TeamDied"); if (!cmdStr.GetGlobalFunc(L)) { @@ -401,7 +460,7 @@ void CLuaHandle::TeamChanged(int teamID) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("TeamChanged"); if (!cmdStr.GetGlobalFunc(L)) { @@ -423,7 +482,7 @@ void CLuaHandle::PlayerChanged(int playerID) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("PlayerChanged"); if (!cmdStr.GetGlobalFunc(L)) { @@ -445,7 +504,7 @@ void CLuaHandle::PlayerRemoved(int playerID, int reason) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("PlayerRemoved"); if (!cmdStr.GetGlobalFunc(L)) { @@ -469,7 +528,7 @@ inline void CLuaHandle::UnitCallIn(const LuaHashString& hs, const CUnit* unit) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); if (!hs.GetGlobalFunc(L)) { // remove error handler @@ -493,7 +552,7 @@ void CLuaHandle::UnitCreated(const CUnit* unit, const CUnit* builder) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitCreated"); if (!cmdStr.GetGlobalFunc(L)) { @@ -530,7 +589,7 @@ void CLuaHandle::UnitFromFactory(const CUnit* unit, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitFromFactory"); if (!cmdStr.GetGlobalFunc(L)) { @@ -557,7 +616,7 @@ void CLuaHandle::UnitDestroyed(const CUnit* unit, const CUnit* attacker) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitDestroyed"); if (!cmdStr.GetGlobalFunc(L)) { @@ -570,7 +629,7 @@ void CLuaHandle::UnitDestroyed(const CUnit* unit, const CUnit* attacker) lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); - if (fullRead && (attacker != NULL)) { + if (GetFullRead() && (attacker != NULL)) { lua_pushnumber(L, attacker->id); lua_pushnumber(L, attacker->unitDef->id); lua_pushnumber(L, attacker->team); @@ -587,7 +646,7 @@ void CLuaHandle::UnitTaken(const CUnit* unit, int newTeam) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitTaken"); if (!cmdStr.GetGlobalFunc(L)) { @@ -611,7 +670,7 @@ void CLuaHandle::UnitGiven(const CUnit* unit, int oldTeam) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitGiven"); if (!cmdStr.GetGlobalFunc(L)) { @@ -644,7 +703,7 @@ void CLuaHandle::UnitCommand(const CUnit* unit, const Command& command) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 11); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitCommand"); if (!cmdStr.GetGlobalFunc(L)) { @@ -679,7 +738,7 @@ void CLuaHandle::UnitCmdDone(const CUnit* unit, int cmdID, int cmdTag) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 8); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitCmdDone"); if (!cmdStr.GetGlobalFunc(L)) { @@ -706,7 +765,7 @@ void CLuaHandle::UnitDamaged(const CUnit* unit, const CUnit* attacker, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 11); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitDamaged"); if (!cmdStr.GetGlobalFunc(L)) { @@ -721,7 +780,7 @@ void CLuaHandle::UnitDamaged(const CUnit* unit, const CUnit* attacker, lua_pushnumber(L, unit->team); lua_pushnumber(L, damage); lua_pushboolean(L, paralyzer); - if (fullRead) { + if (GetFullRead()) { lua_pushnumber(L, weaponID); argCount += 1; if (attacker != NULL) { @@ -743,7 +802,7 @@ void CLuaHandle::UnitExperience(const CUnit* unit, float oldExperience) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 8); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitExperience"); if (!cmdStr.GetGlobalFunc(L)) { @@ -771,6 +830,7 @@ void CLuaHandle::UnitSeismicPing(const CUnit* unit, int allyTeam, { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); + int readAllyTeam = GetReadAllyTeam(); if ((readAllyTeam >= 0) && (unit->losStatus[readAllyTeam] & LOS_INLOS)) { return; // don't need to see this ping } @@ -784,14 +844,14 @@ void CLuaHandle::UnitSeismicPing(const CUnit* unit, int allyTeam, lua_pushnumber(L, pos.y); lua_pushnumber(L, pos.z); lua_pushnumber(L, strength); - if (fullRead) { + if (GetFullRead()) { lua_pushnumber(L, allyTeam); lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); } // call the routine - RunCallIn(cmdStr, fullRead ? 7 : 4, 0); + RunCallIn(cmdStr, GetFullRead() ? 7 : 4, 0); return; } @@ -809,13 +869,13 @@ void CLuaHandle::LosCallIn(const LuaHashString& hs, lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->team); - if (fullRead) { + if (GetFullRead()) { lua_pushnumber(L, allyTeam); lua_pushnumber(L, unit->unitDef->id); } // call the routine - RunCallIn(hs, fullRead ? 4 : 2, 0); + RunCallIn(hs, GetFullRead() ? 4 : 2, 0); return; } @@ -855,7 +915,7 @@ void CLuaHandle::UnitLoaded(const CUnit* unit, const CUnit* transport) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 8); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitLoaded"); if (!cmdStr.GetGlobalFunc(L)) { @@ -881,7 +941,7 @@ void CLuaHandle::UnitUnloaded(const CUnit* unit, const CUnit* transport) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 8); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitUnloaded"); if (!cmdStr.GetGlobalFunc(L)) { @@ -969,7 +1029,7 @@ void CLuaHandle::FeatureCreated(const CFeature* feature) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("FeatureCreated"); if (!cmdStr.GetGlobalFunc(L)) { @@ -992,7 +1052,7 @@ void CLuaHandle::FeatureDestroyed(const CFeature* feature) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("FeatureDestroyed"); if (!cmdStr.GetGlobalFunc(L)) { @@ -1198,7 +1258,7 @@ void CLuaHandle::HandleLuaMsg(int playerID, int script, int mode, const std::vec /******************************************************************************/ -inline bool CLuaHandle::PushUnsyncedCallIn(const LuaHashString& hs) +inline bool CLuaHandle::PushUnsyncedCallIn(lua_State *L, const LuaHashString& hs) { // LuaUI keeps these call-ins in the Global table, // the synced handles keep them in the Registry table @@ -1220,7 +1280,7 @@ void CLuaHandle::Save(zipFile archive) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr("Save"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1239,7 +1299,7 @@ void CLuaHandle::Update() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("Update"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1255,7 +1315,7 @@ void CLuaHandle::ViewResize() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr("ViewResize"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1286,7 +1346,7 @@ bool CLuaHandle::DefaultCommand(const CUnit* unit, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("DefaultCommand"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; } @@ -1336,7 +1396,7 @@ void CLuaHandle::DrawGenesis() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("DrawGenesis"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1352,7 +1412,7 @@ void CLuaHandle::DrawWorld() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("DrawWorld"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1368,7 +1428,7 @@ void CLuaHandle::DrawWorldPreUnit() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("DrawWorldPreUnit"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1384,7 +1444,7 @@ void CLuaHandle::DrawWorldShadow() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("DrawWorldShadow"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1400,7 +1460,7 @@ void CLuaHandle::DrawWorldReflection() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("DrawWorldReflection"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1416,7 +1476,7 @@ void CLuaHandle::DrawWorldRefraction() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("DrawWorldRefraction"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1432,7 +1492,7 @@ void CLuaHandle::DrawScreen() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("DrawScreen"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1451,7 +1511,7 @@ void CLuaHandle::DrawScreenEffects() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("DrawScreenEffects"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1470,7 +1530,7 @@ void CLuaHandle::DrawInMiniMap() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("DrawInMiniMap"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return; } @@ -1510,7 +1570,7 @@ bool CLuaHandle::KeyPress(unsigned short key, bool isRepeat) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); static const LuaHashString cmdStr("KeyPress"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1553,7 +1613,7 @@ bool CLuaHandle::KeyRelease(unsigned short key) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr("KeyRelease"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1593,7 +1653,7 @@ bool CLuaHandle::MousePress(int x, int y, int button) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr("MousePress"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1624,7 +1684,7 @@ int CLuaHandle::MouseRelease(int x, int y, int button) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr("MouseRelease"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1655,7 +1715,7 @@ bool CLuaHandle::MouseMove(int x, int y, int dx, int dy, int button) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); static const LuaHashString cmdStr("MouseMove"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1688,7 +1748,7 @@ bool CLuaHandle::MouseWheel(bool up, float value) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("MouseWheel"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1717,7 +1777,7 @@ bool CLuaHandle::JoystickEvent(const std::string& event, int val1, int val2) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); const LuaHashString cmdStr(event); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined, do not take the event } @@ -1746,7 +1806,7 @@ bool CLuaHandle::IsAbove(int x, int y) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("IsAbove"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined } @@ -1776,7 +1836,7 @@ string CLuaHandle::GetTooltip(int x, int y) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("GetTooltip"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return ""; // the call is not defined } @@ -1806,7 +1866,7 @@ bool CLuaHandle::ConfigCommand(const string& command) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr("ConfigureLayout"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return true; // the call is not defined } @@ -1828,7 +1888,7 @@ bool CLuaHandle::CommandNotify(const Command& cmd) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr("CommandNotify"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined } @@ -1878,7 +1938,7 @@ bool CLuaHandle::AddConsoleLine(const string& msg, const CLogSubsystem& /**/) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr("AddConsoleLine"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return true; // the call is not defined } @@ -1904,7 +1964,7 @@ bool CLuaHandle::GroupChanged(int groupID) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr("GroupChanged"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined } @@ -1930,7 +1990,7 @@ string CLuaHandle::WorldTooltip(const CUnit* unit, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); static const LuaHashString cmdStr("WorldTooltip"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return ""; // the call is not defined } @@ -1983,7 +2043,7 @@ bool CLuaHandle::MapDrawCmd(int playerID, int type, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); static const LuaHashString cmdStr("MapDrawCmd"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; // the call is not defined } @@ -2048,7 +2108,7 @@ bool CLuaHandle::GameSetup(const string& state, bool& ready, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr("GameSetup"); - if (!PushUnsyncedCallIn(cmdStr)) { + if (!PushUnsyncedCallIn(L, cmdStr)) { return false; } @@ -2086,7 +2146,7 @@ bool CLuaHandle::GameSetup(const string& state, bool& ready, /******************************************************************************/ /******************************************************************************/ -bool CLuaHandle::AddBasicCalls() +bool CLuaHandle::AddBasicCalls(lua_State *L) { HSTR_PUSH(L, "Script"); lua_newtable(L); { @@ -2113,62 +2173,63 @@ bool CLuaHandle::AddBasicCalls() lua_getglobal(L, "math"); LuaBitOps::PushEntries(L); lua_pop(L, 1); + return true; } int CLuaHandle::CallOutGetName(lua_State* L) { - lua_pushstring(L, activeHandle->GetName().c_str()); + lua_pushstring(L, GetActiveHandle()->GetName().c_str()); return 1; } int CLuaHandle::CallOutGetSynced(lua_State* L) { - lua_pushboolean(L, activeHandle->synced); + lua_pushboolean(L, GetActiveHandle()->GetSynced()); return 1; } int CLuaHandle::CallOutGetFullCtrl(lua_State* L) { - lua_pushboolean(L, activeHandle->fullCtrl); + lua_pushboolean(L, GetActiveHandle()->GetFullCtrl()); return 1; } int CLuaHandle::CallOutGetFullRead(lua_State* L) { - lua_pushboolean(L, activeHandle->fullRead); + lua_pushboolean(L, GetActiveHandle()->GetFullRead()); return 1; } int CLuaHandle::CallOutGetCtrlTeam(lua_State* L) { - lua_pushnumber(L, activeHandle->ctrlTeam); + lua_pushnumber(L, GetActiveHandle()->GetCtrlTeam()); return 1; } int CLuaHandle::CallOutGetReadTeam(lua_State* L) { - lua_pushnumber(L, activeHandle->readTeam); + lua_pushnumber(L, GetActiveHandle()->GetReadTeam()); return 1; } int CLuaHandle::CallOutGetReadAllyTeam(lua_State* L) { - lua_pushnumber(L, activeHandle->readAllyTeam); + lua_pushnumber(L, GetActiveHandle()->GetReadAllyTeam()); return 1; } int CLuaHandle::CallOutGetSelectTeam(lua_State* L) { - lua_pushnumber(L, activeHandle->selectTeam); + lua_pushnumber(L, GetActiveHandle()->GetSelectTeam()); return 1; } @@ -2216,24 +2277,30 @@ int CLuaHandle::CallOutGetCallInList(lua_State* L) int CLuaHandle::CallOutSyncedUpdateCallIn(lua_State* L) { + if(!Threading::IsSimThread()) + return 0; // FIXME: If this can be called from a non-sim context, this code is insufficient const int args = lua_gettop(L); if ((args != 1) || !lua_isstring(L, 1)) { luaL_error(L, "Incorrect arguments to UpdateCallIn()"); } const string name = lua_tostring(L, 1); - activeHandle->SyncedUpdateCallIn(name); + CLuaHandle *lh = GetActiveHandle(); + lh->SyncedUpdateCallIn(lh->GetActiveState(), name); return 0; } int CLuaHandle::CallOutUnsyncedUpdateCallIn(lua_State* L) { + if(Threading::IsSimThread()) + return 0; // FIXME: If this can be called from a sim context, this code is insufficient const int args = lua_gettop(L); if ((args != 1) || !lua_isstring(L, 1)) { luaL_error(L, "Incorrect arguments to UpdateCallIn()"); } const string name = lua_tostring(L, 1); - activeHandle->UnsyncedUpdateCallIn(name); + CLuaHandle *lh = GetActiveHandle(); + lh->UnsyncedUpdateCallIn(lh->GetActiveState(), name); return 0; } diff --git a/rts/Lua/LuaHandle.h b/rts/Lua/LuaHandle.h index df3efe4f8bb..6021d8b8034 100644 --- a/rts/Lua/LuaHandle.h +++ b/rts/Lua/LuaHandle.h @@ -19,6 +19,8 @@ using std::set; #include "LuaRBOs.h" //FIXME#include "LuaVBOs.h" #include "LuaDisplayLists.h" +#include "System/Platform/Threading.h" +#include "System/LogOutput.h" #define LUA_HANDLE_ORDER_RULES 100 @@ -49,6 +51,7 @@ class CLuaHandle : public CEventClient public: inline bool CanCtrlTeam(int team) { + int ctrlTeam = GetCtrlTeam(); if (ctrlTeam < 0) { return (ctrlTeam == AllAccessTeam); } else { @@ -56,6 +59,7 @@ class CLuaHandle : public CEventClient } } inline bool CanReadAllyTeam(int allyTeam) { + int readAllyTeam = GetReadAllyTeam(); if (readAllyTeam < 0) { return (readAllyTeam == AllAccessTeam); } else { @@ -63,14 +67,24 @@ class CLuaHandle : public CEventClient } } - bool GetSynced() const { return synced; } +#define SET_CONTEXT_DATA(v) if(all) { D_Sim.v = _##v; D_Draw.v = _##v; } else GetLuaContextData().v = _##v + inline void SetFullRead(bool _fullRead, bool all = false) { SET_CONTEXT_DATA(fullRead); } + inline bool GetFullRead() const { return GetLuaContextData().fullRead; } + inline void SetFullCtrl(bool _fullCtrl, bool all = false) { SET_CONTEXT_DATA(fullCtrl); } + inline bool GetFullCtrl() const { return GetLuaContextData().fullCtrl; } + inline void SetCtrlTeam(int _ctrlTeam, bool all = false) { SET_CONTEXT_DATA(ctrlTeam); } + inline int GetCtrlTeam() const { return GetLuaContextData().ctrlTeam; } + inline void SetReadTeam(int _readTeam, bool all = false) { SET_CONTEXT_DATA(readTeam); } + inline int GetReadTeam() const { return GetLuaContextData().readTeam; } + inline void SetReadAllyTeam(int _readAllyTeam, bool all = false) { SET_CONTEXT_DATA(readAllyTeam); } + inline int GetReadAllyTeam() const { return GetLuaContextData().readAllyTeam; } + inline void SetSelectTeam(int _selectTeam, bool all = false) { SET_CONTEXT_DATA(selectTeam); } + inline int GetSelectTeam() const { return GetLuaContextData().selectTeam; } + inline void SetSynced(bool _synced, bool all = false) { if(!IsDrawCallIn() || all) synced = _synced; } + inline bool GetSynced() const { return IsDrawCallIn() ? false : synced; } + bool GetUserMode() const { return userMode; } - bool GetFullRead() const { return fullRead; } - bool GetFullCtrl() const { return fullCtrl; } - int GetReadTeam() const { return readTeam; } - int GetReadAllyTeam() const { return readAllyTeam; } - int GetCtrlTeam() const { return ctrlTeam; } - int GetSelectTeam() const { return selectTeam; } + bool WantsToDie() const { return killMe; } @@ -86,10 +100,10 @@ class CLuaHandle : public CEventClient const bool userMode; public: // call-ins - virtual bool HasCallIn(const string& name) { return false; } // FIXME - bool WantsEvent(const string& name) { return HasCallIn(name); } // FIXME - virtual bool SyncedUpdateCallIn(const string& name) { return false; } - virtual bool UnsyncedUpdateCallIn(const string& name) { return false; } + virtual bool HasCallIn(lua_State *L, const string& name) { return false; } // FIXME + bool WantsEvent(const string& name) { return HasCallIn(GetActiveState(), name); } // FIXME + virtual bool SyncedUpdateCallIn(lua_State *L, const string& name) { return false; } + virtual bool UnsyncedUpdateCallIn(lua_State *L, const string& name) { return false; } void Shutdown(); @@ -210,22 +224,40 @@ class CLuaHandle : public CEventClient return 0; } + struct DelayData { + int type; + std::string str; + float num; + bool bol; + }; + void ExecuteRecvFromSynced(); + virtual void RecvFromSynced(int args) { logOutput.Print("Error - Unsynced Lua Handle attempted RecvFromSynced"); } + std::vector< std::vector > delayedRecvFromSynced; + protected: CLuaHandle(const string& name, int order, bool userMode); virtual ~CLuaHandle(); void KillLua(); - void SetActiveHandle(); - void SetActiveHandle(CLuaHandle*); + inline void SetActiveHandle(bool draw = IsDrawCallIn()); + inline void SetActiveHandle(CLuaHandle* lh, bool draw = IsDrawCallIn()); + + inline lua_State *GetActiveState() { +#if DUAL_LUA_STATES + return Threading::IsSimThread() ? L_Sim : L_Draw; +#else + return L_Sim; +#endif + } - bool AddBasicCalls(); - bool LoadCode(const string& code, const string& debug); + bool AddBasicCalls(lua_State *L); + bool LoadCode(lua_State *L, const string& code, const string& debug); bool AddEntriesToTable(lua_State* L, const char* name, bool (*entriesFunc)(lua_State*)); /// returns stack index of traceback function - int SetupTraceback(); + int SetupTraceback(lua_State *L); /// returns error code and sets traceback on error int RunCallInTraceback(int inArgs, int outArgs, int errfuncIndex, std::string& traceback); /// returns false and prints message to log on error @@ -238,28 +270,42 @@ class CLuaHandle : public CEventClient void LosCallIn(const LuaHashString& hs, const CUnit* unit, int allyTeam); void UnitCallIn(const LuaHashString& hs, const CUnit* unit); - bool PushUnsyncedCallIn(const LuaHashString& hs); + bool PushUnsyncedCallIn(lua_State *L, const LuaHashString& hs); inline bool CheckModUICtrl() { return modUICtrl || userMode; } + inline bool IsValid() const { return (L_Sim != NULL) && (L_Draw != NULL); } + protected: - lua_State* L; + + bool synced; // FIXME -- remove this once the lua_State split is done + // (use the constant CEventClient version ...) + + struct luaContextData { + luaContextData() : fullCtrl(false), fullRead(false), ctrlTeam(CEventClient::NoAccessTeam), + readTeam(0), readAllyTeam(0), selectTeam(CEventClient::NoAccessTeam) {} + bool fullCtrl; + bool fullRead; + int ctrlTeam; + int readTeam; + int readAllyTeam; + int selectTeam; + }; + + lua_State* L_Sim; + lua_State* L_Draw; + + luaContextData D_Sim; + luaContextData D_Draw; + + const luaContextData &GetLuaContextData() const { return IsDrawCallIn() ? D_Draw : D_Sim; } + luaContextData &GetLuaContextData() { return IsDrawCallIn() ? D_Draw : D_Sim; } bool killMe; string killMsg; - bool synced; // FIXME -- remove this once the lua_State split is done - // (use the constant CEventClient version ...) - - bool fullCtrl; - bool fullRead; bool printTracebacks; - int ctrlTeam; - int readTeam; - int readAllyTeam; - int selectTeam; - //FIXME LuaArrays arrays; LuaShaders shaders; LuaTextures textures; @@ -289,25 +335,29 @@ class CLuaHandle : public CEventClient static int CallOutUnsyncedUpdateCallIn(lua_State* L); public: // static - static const CLuaHandle* GetActiveHandle() { return activeHandle; } + static inline CLuaHandle* GetActiveHandle(bool draw = IsDrawCallIn()) { + return GetStaticLuaContextData(draw).activeHandle; + } - static bool ActiveCanCtrlTeam(int team) { - return activeHandle->CanCtrlTeam(team); + static inline bool ActiveCanCtrlTeam(int team) { + return GetActiveHandle()->CanCtrlTeam(team); } - static bool ActiveCanReadAllyTeam(int allyTeam) { - return activeHandle->CanReadAllyTeam(allyTeam); + static inline bool ActiveCanReadAllyTeam(int allyTeam) { + return GetActiveHandle()->CanReadAllyTeam(allyTeam); } - static const bool& GetActiveFullRead() { return activeFullRead; } - static const int& GetActiveReadAllyTeam() { return activeReadAllyTeam; } -//FIXME static LuaArrays& GetActiveArrays() { return activeHandle->arrays; } - static LuaShaders& GetActiveShaders() { return activeHandle->shaders; } - static LuaTextures& GetActiveTextures() { return activeHandle->textures; } -//FIXME static LuaVBOs& GetActiveVBOs() { return activeHandle->vbos; } - static LuaFBOs& GetActiveFBOs() { return activeHandle->fbos; } - static LuaRBOs& GetActiveRBOs() { return activeHandle->rbos; } + static inline const bool GetActiveFullRead() { return GetStaticLuaContextData().activeFullRead; } + static inline void SetActiveFullRead(bool fr) { GetStaticLuaContextData().activeFullRead = fr; } + static inline const int GetActiveReadAllyTeam() { return GetStaticLuaContextData().activeReadAllyTeam; } + static inline void SetActiveReadAllyTeam(int rat) { GetStaticLuaContextData().activeReadAllyTeam = rat; } +//FIXME static LuaArrays& GetActiveArrays() { return GetActiveHandle()->arrays; } + static LuaShaders& GetActiveShaders() { return GetActiveHandle()->shaders; } + static LuaTextures& GetActiveTextures() { return GetActiveHandle()->textures; } +//FIXME static LuaVBOs& GetActiveVBOs() { return GetActiveHandle()->vbos; } + static LuaFBOs& GetActiveFBOs() { return GetActiveHandle()->fbos; } + static LuaRBOs& GetActiveRBOs() { return GetActiveHandle()->rbos; } static CLuaDisplayLists& GetActiveDisplayLists() { - return activeHandle->displayLists; + return GetActiveHandle()->displayLists; } static void SetDevMode(bool value) { devMode = value; } @@ -318,37 +368,45 @@ class CLuaHandle : public CEventClient static void HandleLuaMsg(int playerID, int script, int mode, const std::vector& msg); + static inline bool IsDrawCallIn() { + return !Threading::IsSimThread(); + } protected: // static - static CLuaHandle* activeHandle; - static bool activeFullRead; - static int activeReadAllyTeam; - static bool devMode; // allows real file access static bool modUICtrl; // allows non-user scripts to use UI controls // FIXME: because CLuaUnitScript needs to access RunCallIn / activeHandle friend class CLuaUnitScript; + private: + struct staticLuaContextData { + staticLuaContextData() : activeFullRead(false), activeReadAllyTeam(CEventClient::NoAccessTeam), activeHandle(NULL) {} + bool activeFullRead; + int activeReadAllyTeam; + CLuaHandle* activeHandle; + }; + static staticLuaContextData S_Sim; + static staticLuaContextData S_Draw; + + static staticLuaContextData &GetStaticLuaContextData(bool draw = IsDrawCallIn()) { return draw ? S_Draw : S_Sim; } }; -inline void CLuaHandle::SetActiveHandle() +inline void CLuaHandle::SetActiveHandle(bool draw) { - activeHandle = this; - activeFullRead = this->fullRead; - activeReadAllyTeam = this->readAllyTeam; + SetActiveHandle(this, draw); } - -inline void CLuaHandle::SetActiveHandle(CLuaHandle* lh) +inline void CLuaHandle::SetActiveHandle(CLuaHandle* lh, bool draw) { - activeHandle = lh; + GetStaticLuaContextData(draw).activeHandle = lh; if (lh) { - activeFullRead = lh->fullRead; - activeReadAllyTeam = lh->readAllyTeam; + SetActiveFullRead(lh->GetFullRead()); + SetActiveReadAllyTeam(lh->GetReadAllyTeam()); } } + inline bool CLuaHandle::RunCallIn(const LuaHashString& hs, int inArgs, int outArgs) { return RunCallInTraceback(hs, inArgs, outArgs, 0); @@ -357,9 +415,9 @@ inline bool CLuaHandle::RunCallIn(const LuaHashString& hs, int inArgs, int outAr inline bool CLuaHandle::RunCallInUnsynced(const LuaHashString& hs, int inArgs, int outArgs) { - synced = false; + SetSynced(false); const bool retval = RunCallIn(hs, inArgs, outArgs); - synced = !userMode; + SetSynced(!userMode); return retval; } diff --git a/rts/Lua/LuaHandleSynced.cpp b/rts/Lua/LuaHandleSynced.cpp index 1fe30270433..f4de37b3cb4 100644 --- a/rts/Lua/LuaHandleSynced.cpp +++ b/rts/Lua/LuaHandleSynced.cpp @@ -69,9 +69,9 @@ LuaRulesParams::HashMap CLuaHandleSynced::gameParamsMap; CLuaHandleSynced::CLuaHandleSynced(const string& _name, int _order) : CLuaHandle(_name, _order, false), - allowChanges(false), teamsLocked(false) { + SetAllowChanges(false, true); printTracebacks = true; } @@ -89,11 +89,11 @@ void CLuaHandleSynced::Init(const string& syncedFile, const string& unsyncedFile, const string& modes) { - if (L == NULL) { + if (!IsValid()) { return; } - if (fullCtrl) { + if (GetFullCtrl()) { for (int w = 0; w < weaponDefHandler->numWeaponDefs; w++) { watchWeapons.push_back(false); } @@ -106,6 +106,8 @@ void CLuaHandleSynced::Init(const string& syncedFile, return; } + BEGIN_ITERATE_LUA_STATES(); + // load the standard libraries LUA_OPEN_LIB(L, luaopen_base); LUA_OPEN_LIB(L, luaopen_math); @@ -133,34 +135,37 @@ void CLuaHandleSynced::Init(const string& syncedFile, // use gs->randFloat() for the synchronized code, and disable randomseed() // (this first copies the original functions to the registry for unsynced) - if (!SyncifyRandomFuncs()) { + if (!SyncifyRandomFuncs(L)) { KillLua(); return; } - CLuaHandle* origHandle = activeHandle; + CLuaHandle* origHandle = GetActiveHandle(); SetActiveHandle(); - allowChanges = true; - synced = true; + SetAllowChanges(true, true); + SetSynced(true, true); - const bool haveSynced = SetupSynced(syncedCode, syncedFile); - if (L == NULL) { + const bool haveSynced = SetupSynced(L, syncedCode, syncedFile); + if (!IsValid()) { SetActiveHandle(origHandle); return; } - allowChanges = false; - synced = false; + SetAllowChanges(false, true); + SetSynced(false, true); - const bool haveUnsynced = SetupUnsynced(unsyncedCode, unsyncedFile); - if (L == NULL) { + // FIXME: for the split lua state, we currently add synced AND unsynced code to both states + // to make sure HasCallIn et al do not return different results depending on active state. + // The problem is that synchronization is needed if HasCallIn would query both states. + const bool haveUnsynced = SetupUnsynced(L, unsyncedCode, unsyncedFile); + if (!IsValid()) { SetActiveHandle(origHandle); return; } - synced = true; - allowChanges = true; + SetSynced(true, true); + SetAllowChanges(true, true); if (!haveSynced && !haveUnsynced) { KillLua(); @@ -172,18 +177,20 @@ void CLuaHandleSynced::Init(const string& syncedFile, eventHandler.AddClient(this); SetActiveHandle(origHandle); + + END_ITERATE_LUA_STATES(); } -bool CLuaHandleSynced::SetupSynced(const string& code, const string& filename) +bool CLuaHandleSynced::SetupSynced(lua_State *L, const string& code, const string& filename) { - if ((L == NULL) || code.empty()) { + if (!IsValid() || code.empty()) { return false; } lua_pushvalue(L, LUA_GLOBALSINDEX); - AddBasicCalls(); // into Global + AddBasicCalls(L); // into Global lua_pushstring(L, "Script"); lua_rawget(L, -2); @@ -223,14 +230,14 @@ bool CLuaHandleSynced::SetupSynced(const string& code, const string& filename) } // add code from the sub-class - if (!AddSyncedCode()) { + if (!AddSyncedCode(L)) { KillLua(); return false; } lua_settop(L, 0); - if (!LoadCode(code, filename)) { + if (!LoadCode(L, code, filename)) { KillLua(); return false; } @@ -239,9 +246,9 @@ bool CLuaHandleSynced::SetupSynced(const string& code, const string& filename) } -bool CLuaHandleSynced::SetupUnsynced(const string& code, const string& filename) +bool CLuaHandleSynced::SetupUnsynced(lua_State *L, const string& code, const string& filename) { - if ((L == NULL) || code.empty()) { + if (!IsValid() || code.empty()) { return false; } @@ -252,7 +259,7 @@ bool CLuaHandleSynced::SetupUnsynced(const string& code, const string& filename) unsyncedStr.GetRegistry(L); - AddBasicCalls(); // into UNSYNCED + AddBasicCalls(L); // into UNSYNCED // remove Script.Kill() lua_pushstring(L, "Script"); @@ -293,22 +300,22 @@ bool CLuaHandleSynced::SetupUnsynced(const string& code, const string& filename) } lua_pushstring(L, "math"); lua_newtable(L); - lua_getglobal(L, "math"); LightCopyTable(-2, -1); lua_pop(L, 1); + lua_getglobal(L, "math"); LightCopyTable(L, -2, -1); lua_pop(L, 1); lua_rawset(L, -3); lua_pushstring(L, "table"); lua_newtable(L); - lua_getglobal(L, "table"); LightCopyTable(-2, -1); lua_pop(L, 1); + lua_getglobal(L, "table"); LightCopyTable(L, -2, -1); lua_pop(L, 1); lua_rawset(L, -3); lua_pushstring(L, "string"); lua_newtable(L); - lua_getglobal(L, "string"); LightCopyTable(-2, -1); lua_pop(L, 1); + lua_getglobal(L, "string"); LightCopyTable(L, -2, -1); lua_pop(L, 1); lua_rawset(L, -3); lua_pushstring(L, "coroutine"); lua_newtable(L); - lua_getglobal(L, "coroutine"); LightCopyTable(-2, -1); lua_pop(L, 1); + lua_getglobal(L, "coroutine"); LightCopyTable(L, -2, -1); lua_pop(L, 1); lua_rawset(L, -3); - if (!CopyRealRandomFuncs()) { + if (!CopyRealRandomFuncs(L)) { KillLua(); return false; } @@ -331,33 +338,33 @@ bool CLuaHandleSynced::SetupUnsynced(const string& code, const string& filename) NULL }; for (const char** l = labels; *l != NULL; l++) { - CopyGlobalToUnsynced(*l); + CopyGlobalToUnsynced(L, *l); } // add code from the sub-class unsyncedStr.GetRegistry(L); - if (!AddUnsyncedCode()) { + if (!AddUnsyncedCode(L)) { KillLua(); return false; } lua_settop(L, 0); - if (!LoadUnsyncedCode(code, filename)) { + if (!LoadUnsyncedCode(L, code, filename)) { KillLua(); return false; } - if (!SetupUnsyncedFunction("RecvFromSynced") || - !SetupUnsyncedFunction("Update") || - !SetupUnsyncedFunction("DrawGenesis") || - !SetupUnsyncedFunction("DrawWorld") || - !SetupUnsyncedFunction("DrawWorldPreUnit") || - !SetupUnsyncedFunction("DrawWorldShadow") || - !SetupUnsyncedFunction("DrawWorldReflection") || - !SetupUnsyncedFunction("DrawWorldRefraction") || - !SetupUnsyncedFunction("DrawScreenEffects") || - !SetupUnsyncedFunction("DrawScreen") || - !SetupUnsyncedFunction("DrawInMiniMap")) { + if (!SetupUnsyncedFunction(L, "RecvFromSynced") || + !SetupUnsyncedFunction(L, "Update") || + !SetupUnsyncedFunction(L, "DrawGenesis") || + !SetupUnsyncedFunction(L, "DrawWorld") || + !SetupUnsyncedFunction(L, "DrawWorldPreUnit") || + !SetupUnsyncedFunction(L, "DrawWorldShadow") || + !SetupUnsyncedFunction(L, "DrawWorldReflection") || + !SetupUnsyncedFunction(L, "DrawWorldRefraction") || + !SetupUnsyncedFunction(L, "DrawScreenEffects") || + !SetupUnsyncedFunction(L, "DrawScreen") || + !SetupUnsyncedFunction(L, "DrawInMiniMap")) { return false; } @@ -365,7 +372,7 @@ bool CLuaHandleSynced::SetupUnsynced(const string& code, const string& filename) } -bool CLuaHandleSynced::SyncifyRandomFuncs() +bool CLuaHandleSynced::SyncifyRandomFuncs(lua_State *L) { // adjust the math.random() and math.randomseed() calls lua_getglobal(L, "math"); @@ -402,7 +409,7 @@ bool CLuaHandleSynced::SyncifyRandomFuncs() } -bool CLuaHandleSynced::CopyRealRandomFuncs() +bool CLuaHandleSynced::CopyRealRandomFuncs(lua_State *L) { lua_pushstring(L, "math"); lua_rawget(L, -2); @@ -423,7 +430,7 @@ bool CLuaHandleSynced::CopyRealRandomFuncs() } -bool CLuaHandleSynced::SetupUnsyncedFunction(const char* funcName) +bool CLuaHandleSynced::SetupUnsyncedFunction(lua_State *L, const char* funcName) { // copy the function from UNSYNCED into // the registry, and setfenv() it to UNSYNCED @@ -460,7 +467,7 @@ bool CLuaHandleSynced::SetupUnsyncedFunction(const char* funcName) } -bool CLuaHandleSynced::CopyGlobalToUnsynced(const char* name) +bool CLuaHandleSynced::CopyGlobalToUnsynced(lua_State *L, const char* name) { lua_settop(L, 0); unsyncedStr.GetRegistry(L); @@ -475,7 +482,7 @@ bool CLuaHandleSynced::CopyGlobalToUnsynced(const char* name) } -bool CLuaHandleSynced::LightCopyTable(int dstIndex, int srcIndex) +bool CLuaHandleSynced::LightCopyTable(lua_State *L, int dstIndex, int srcIndex) { // use positive indices if (dstIndex < 0) { dstIndex = lua_gettop(L) + dstIndex + 1; } @@ -503,7 +510,7 @@ bool CLuaHandleSynced::LightCopyTable(int dstIndex, int srcIndex) } -bool CLuaHandleSynced::LoadUnsyncedCode(const string& code, const string& debug) +bool CLuaHandleSynced::LoadUnsyncedCode(lua_State *L, const string& code, const string& debug) { lua_settop(L, 0); @@ -523,7 +530,7 @@ bool CLuaHandleSynced::LoadUnsyncedCode(const string& code, const string& debug) } lua_setfenv(L, -2); - CLuaHandle* orig = activeHandle; + CLuaHandle* orig = GetActiveHandle(); SetActiveHandle(); error = lua_pcall(L, 0, 0, 0); SetActiveHandle(orig); @@ -558,9 +565,9 @@ string CLuaHandleSynced::LoadFile(const string& filename, } -bool CLuaHandleSynced::HasCallIn(const string& name) +bool CLuaHandleSynced::HasCallIn(lua_State *L, const string& name) { - if (L == NULL) { + if (!IsValid()) { return false; } @@ -588,13 +595,13 @@ bool CLuaHandleSynced::HasCallIn(const string& name) } -bool CLuaHandleSynced::SyncedUpdateCallIn(const string& name) +bool CLuaHandleSynced::SyncedUpdateCallIn(lua_State *L, const string& name) { if ((name == "RecvFromSynced") || eventHandler.IsUnsynced(name)) { return false; } - if (HasCallIn(name)) { + if (HasCallIn(L, name)) { eventHandler.InsertEvent(this, name); } else { eventHandler.RemoveEvent(this, name); @@ -603,20 +610,20 @@ bool CLuaHandleSynced::SyncedUpdateCallIn(const string& name) } -bool CLuaHandleSynced::UnsyncedUpdateCallIn(const string& name) +bool CLuaHandleSynced::UnsyncedUpdateCallIn(lua_State *L, const string& name) { if ((name != "RecvFromSynced") && !eventHandler.IsUnsynced(name)) { return false; } if (name != "RecvFromSynced") { - if (HasCallIn(name)) { + if (HasCallIn(L, name)) { eventHandler.InsertEvent(this, name); } else { eventHandler.RemoveEvent(this, name); } } - SetupUnsyncedFunction(name.c_str()); + SetupUnsyncedFunction(L, name.c_str()); return true; } @@ -636,7 +643,7 @@ bool CLuaHandleSynced::Initialize(const string& syncData) return true; } - int errfunc = SetupTraceback() ? -2 : 0; + int errfunc = SetupTraceback(L) ? -2 : 0; logOutput.Print("Initialize errfunc=%d\n", errfunc); lua_pushlstring(L, syncData.c_str(), syncData.size()); @@ -705,7 +712,7 @@ void CLuaHandleSynced::GameFrame(int frameNumber) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); - int errfunc = SetupTraceback(); + int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("GameFrame"); if (!cmdStr.GetGlobalFunc(L)) { @@ -758,37 +765,85 @@ bool CLuaHandleSynced::GotChatMsg(const string& msg, int playerID) /******************************************************************************/ + + +void CLuaHandleSynced::DelayRecvFromSynced(lua_State* srcState, int args) { + std::vector ddvec; + for(int i = 1; i <= args; ++i) { + const int type = lua_type(srcState, i); + DelayData ddata; + ddata.type = type; + switch (type) { + case LUA_TBOOLEAN: { + ddata.bol = lua_toboolean(srcState, i); + break; + } + case LUA_TNUMBER: { + ddata.num = lua_tonumber(srcState, i); + break; + } + case LUA_TSTRING: { + size_t len; + const char* data = lua_tolstring(srcState, i, &len); + ddata.str.resize(len); + memcpy(&ddata.str[0], data, len); + break; + } + case LUA_TNIL: { + break; + } + default: { + logOutput.Print("RecvFromSynced (delay): Invalid type for argument %d", i); + break; // nil + } + } + ddvec.push_back(ddata); + } + + GML_STDMUTEX_LOCK(recv); + + delayedRecvFromSynced.push_back(ddvec); +} + + void CLuaHandleSynced::RecvFromSynced(int args) { - //LUA_CALL_IN_CHECK(L); -- not valid here + SELECT_LUA_STATE(); + static const LuaHashString cmdStr("RecvFromSynced"); - if (!cmdStr.GetRegistryFunc(L)) { - return; // the call is not defined + //LUA_CALL_IN_CHECK(L); -- not valid here + +#if DUAL_LUA_STATES + if(L == L_Sim) { // Sim thread sends to unsynced --> delay it + DelayRecvFromSynced(L, args); + return; } + // Draw thread, delayed already, execute it +#endif + if (!cmdStr.GetRegistryFunc(L)) + return; // the call is not defined lua_insert(L, 1); // place the function // call the routine - allowChanges = false; - synced = false; + SetAllowChanges(false); + SetSynced(false); RunCallIn(cmdStr, args, 0); - synced = true; - allowChanges = true; - - return; + SetSynced(true); + SetAllowChanges(true); } bool CLuaHandleSynced::RecvLuaMsg(const string& msg, int playerID) { //FIXME: is there a reason to disallow gamestate changes in RecvLuaMsg? - const bool prevAllowChanges = allowChanges; - allowChanges = false; + const bool prevAllowChanges = GetAllowChanges(); + SetAllowChanges(false); const bool retval = CLuaHandle::RecvLuaMsg(msg, playerID); - allowChanges = prevAllowChanges; + SetAllowChanges(prevAllowChanges); return retval; } @@ -802,6 +857,8 @@ bool CLuaHandleSynced::RecvLuaMsg(const string& msg, int playerID) bool CLuaHandleSynced::HasSyncedXCall(const string& funcName) { + SELECT_LUA_STATE(); + lua_pushvalue(L, LUA_GLOBALSINDEX); if (!lua_istable(L, -1)) { lua_pop(L, 1); @@ -817,6 +874,8 @@ bool CLuaHandleSynced::HasSyncedXCall(const string& funcName) bool CLuaHandleSynced::HasUnsyncedXCall(const string& funcName) { + SELECT_LUA_STATE(); + unsyncedStr.GetRegistry(L); // push the UNSYNCED table if (!lua_istable(L, -1)) { lua_pop(L, 1); @@ -830,7 +889,7 @@ bool CLuaHandleSynced::HasUnsyncedXCall(const string& funcName) } -int CLuaHandleSynced::XCall(lua_State* srcState, const string& funcName) +int CLuaHandleSynced::XCall(lua_State* L, lua_State* srcState, const string& funcName) { // expecting an environment table if (!lua_istable(L, -1)) { @@ -886,19 +945,38 @@ int CLuaHandleSynced::XCall(lua_State* srcState, const string& funcName) int CLuaHandleSynced::SyncedXCall(lua_State* srcState, const string& funcName) { + SELECT_LUA_STATE(); + + if (L != L_Sim) + return 0; + lua_pushvalue(L, LUA_GLOBALSINDEX); - const int retval = XCall(srcState, funcName); + const int retval = XCall(L, srcState, funcName); return retval; } int CLuaHandleSynced::UnsyncedXCall(lua_State* srcState, const string& funcName) { - const bool prevSynced = synced; - synced = false; + SELECT_LUA_STATE(); + +#if DUAL_LUA_STATES + if (L == L_Sim) { + GML_RECMUTEX_LOCK(luadraw); // Called from Sim, need to lock draw thread during XCall + + const bool prevSynced = GetSynced(); + SetSynced(false); + unsyncedStr.GetRegistry(L_Draw); // push the UNSYNCED table + const int retval = XCall(L_Draw, srcState, funcName); + SetSynced(prevSynced); + return retval; + } +#endif + const bool prevSynced = GetSynced(); + SetSynced(false); unsyncedStr.GetRegistry(L); // push the UNSYNCED table - const int retval = XCall(srcState, funcName); - synced = prevSynced; + const int retval = XCall(L, srcState, funcName); + SetSynced(prevSynced); return retval; } @@ -978,6 +1056,7 @@ int CLuaHandleSynced::SendToUnsynced(lua_State* L) } CLuaHandleSynced* lhs = GetActiveHandle(); lhs->RecvFromSynced(args); + return 0; } @@ -994,12 +1073,12 @@ int CLuaHandleSynced::CallAsTeam(lua_State* L) } // save the current access - const bool prevFullCtrl = lhs->fullCtrl; - const bool prevFullRead = lhs->fullRead; - const int prevCtrlTeam = lhs->ctrlTeam; - const int prevReadTeam = lhs->readTeam; - const int prevReadAllyTeam = lhs->readAllyTeam; - const int prevSelectTeam = lhs->selectTeam; + const bool prevFullCtrl = lhs->GetFullCtrl(); + const bool prevFullRead = lhs->GetFullRead(); + const int prevCtrlTeam = lhs->GetCtrlTeam(); + const int prevReadTeam = lhs->GetReadTeam(); + const int prevReadAllyTeam = lhs->GetReadAllyTeam(); + const int prevSelectTeam = lhs->GetSelectTeam(); // parse the new access if (lua_isnumber(L, 1)) { @@ -1008,16 +1087,16 @@ int CLuaHandleSynced::CallAsTeam(lua_State* L) luaL_error(L, "Bad teamID in SetCtrlTeam"); } // ctrl - lhs->ctrlTeam = teamID; - lhs->fullCtrl = (lhs->ctrlTeam == CEventClient::AllAccessTeam); + lhs->SetCtrlTeam(teamID); + lhs->SetFullCtrl(lhs->GetCtrlTeam() == CEventClient::AllAccessTeam); // read - lhs->readTeam = teamID; - lhs->readAllyTeam = (teamID < 0) ? teamID : teamHandler->AllyTeam(teamID); - lhs->fullRead = (lhs->readAllyTeam == CEventClient::AllAccessTeam); - activeFullRead = lhs->fullRead; - activeReadAllyTeam = lhs->readAllyTeam; + lhs->SetReadTeam(teamID); + lhs->SetReadAllyTeam((teamID < 0) ? teamID : teamHandler->AllyTeam(teamID)); + lhs->SetFullRead(lhs->GetReadAllyTeam() == CEventClient::AllAccessTeam); + SetActiveFullRead(lhs->GetFullRead()); + SetActiveReadAllyTeam(lhs->GetReadAllyTeam()); // select - lhs->selectTeam = teamID; + lhs->SetSelectTeam(teamID); } else if (lua_istable(L, 1)) { const int table = 1; @@ -1032,18 +1111,18 @@ int CLuaHandleSynced::CallAsTeam(lua_State* L) } if (key == "ctrl") { - lhs->ctrlTeam = teamID; - lhs->fullCtrl = (lhs->ctrlTeam == CEventClient::AllAccessTeam); + lhs->SetCtrlTeam(teamID); + lhs->SetFullCtrl(lhs->GetCtrlTeam() == CEventClient::AllAccessTeam); } else if (key == "read") { - lhs->readTeam = teamID; - lhs->readAllyTeam = (teamID < 0) ? teamID : teamHandler->AllyTeam(teamID); - lhs->fullRead = (lhs->readAllyTeam == CEventClient::AllAccessTeam); - activeFullRead = lhs->fullRead; - activeReadAllyTeam = lhs->readAllyTeam; + lhs->SetReadTeam(teamID); + lhs->SetReadAllyTeam((teamID < 0) ? teamID : teamHandler->AllyTeam(teamID)); + lhs->SetFullRead(lhs->GetReadAllyTeam() == CEventClient::AllAccessTeam); + SetActiveFullRead(lhs->GetFullRead()); + SetActiveReadAllyTeam(lhs->GetReadAllyTeam()); } else if (key == "select") { - lhs->selectTeam = teamID; + lhs->SetSelectTeam(teamID); } } } @@ -1055,17 +1134,17 @@ int CLuaHandleSynced::CallAsTeam(lua_State* L) const int funcArgs = lua_gettop(L) - 2; // protected call so that the permissions are always reverted - const int error = lua_pcall(lhs->L, funcArgs, LUA_MULTRET, 0); + const int error = lua_pcall(lhs->GetActiveState(), funcArgs, LUA_MULTRET, 0); // revert the permissions - lhs->fullCtrl = prevFullCtrl; - lhs->fullRead = prevFullRead; - lhs->ctrlTeam = prevCtrlTeam; - lhs->readTeam = prevReadTeam; - lhs->readAllyTeam = prevReadAllyTeam; - lhs->selectTeam = prevSelectTeam; - activeFullRead = prevFullRead; - activeReadAllyTeam = prevReadAllyTeam; + lhs->SetFullCtrl(prevFullCtrl); + lhs->SetFullRead(prevFullRead); + lhs->SetCtrlTeam(prevCtrlTeam); + lhs->SetReadTeam(prevReadTeam); + lhs->SetReadAllyTeam(prevReadAllyTeam); + lhs->SetSelectTeam(prevSelectTeam); + SetActiveFullRead(prevFullRead); + SetActiveReadAllyTeam(prevReadAllyTeam); if (error != 0) { logOutput.Print("error = %i, %s, %s\n", diff --git a/rts/Lua/LuaHandleSynced.h b/rts/Lua/LuaHandleSynced.h index 47e65fc4dfe..0d713b9a464 100644 --- a/rts/Lua/LuaHandleSynced.h +++ b/rts/Lua/LuaHandleSynced.h @@ -24,24 +24,26 @@ class CLuaHandleSynced : public CLuaHandle bool Initialize(const string& syncData); string GetSyncData(); - bool GetAllowChanges() const { return allowChanges; } + inline bool GetAllowChanges() const { return IsDrawCallIn() ? false : allowChanges; } + inline void SetAllowChanges(bool ac, bool all = false) { if(!IsDrawCallIn() || all) allowChanges = ac; } public: // call-ins - bool HasCallIn(const string& name); - virtual bool SyncedUpdateCallIn(const string& name); - virtual bool UnsyncedUpdateCallIn(const string& name); + bool HasCallIn(lua_State *L, const string& name); + virtual bool SyncedUpdateCallIn(lua_State *L, const string& name); + virtual bool UnsyncedUpdateCallIn(lua_State *L, const string& name); void GameFrame(int frameNumber); bool GotChatMsg(const string& msg, int playerID); bool RecvLuaMsg(const string& msg, int playerID); - void RecvFromSynced(int args); // not an engine call-in + void DelayRecvFromSynced(lua_State* srcState, int args); + virtual void RecvFromSynced(int args); // not an engine call-in bool SyncedActionFallback(const string& line, int playerID); public: // custom call-in bool HasSyncedXCall(const string& funcName); bool HasUnsyncedXCall(const string& funcName); - int XCall(lua_State* srcState, const string& funcName); + int XCall(lua_State* L, lua_State* srcState, const string& funcName); int SyncedXCall(lua_State* srcState, const string& funcName); int UnsyncedXCall(lua_State* srcState, const string& funcName); @@ -51,29 +53,30 @@ class CLuaHandleSynced : public CLuaHandle void Init(const string& syncedFile, const string& unsyncedFile, const string& modes); - bool SetupSynced(const string& code, const string& filename); - bool SetupUnsynced(const string& code, const string& filename); + bool SetupSynced(lua_State *L, const string& code, const string& filename); + bool SetupUnsynced(lua_State *L, const string& code, const string& filename); // hooks to add code during initialization - virtual bool AddSyncedCode() = 0; - virtual bool AddUnsyncedCode() = 0; + virtual bool AddSyncedCode(lua_State *L) = 0; + virtual bool AddUnsyncedCode(lua_State *L) = 0; string LoadFile(const string& filename, const string& modes) const; - bool CopyGlobalToUnsynced(const char* name); - bool SetupUnsyncedFunction(const char* funcName); - bool LoadUnsyncedCode(const string& code, const string& debug); - bool SyncifyRandomFuncs(); - bool CopyRealRandomFuncs(); - bool LightCopyTable(int dstIndex, int srcIndex); + bool CopyGlobalToUnsynced(lua_State *L, const char* name); + bool SetupUnsyncedFunction(lua_State *L, const char* funcName); + bool LoadUnsyncedCode(lua_State *L, const string& code, const string& debug); + bool SyncifyRandomFuncs(lua_State *L); + bool CopyRealRandomFuncs(lua_State *L); + bool LightCopyTable(lua_State *L, int dstIndex, int srcIndex); protected: static CLuaHandleSynced* GetActiveHandle() { - return dynamic_cast(activeHandle); + return dynamic_cast(CLuaHandle::GetActiveHandle()); } - protected: + private: bool allowChanges; + protected: bool teamsLocked; // disables CallAsTeam() map textCommands; // name, help diff --git a/rts/Lua/LuaLobby.cpp b/rts/Lua/LuaLobby.cpp index 646847fd8c8..d39a797af93 100644 --- a/rts/Lua/LuaLobby.cpp +++ b/rts/Lua/LuaLobby.cpp @@ -33,10 +33,9 @@ inline LuaLobby* toLuaLobby(lua_State* L, int idx) /******************************************************************************/ /******************************************************************************/ - -LuaLobby::LuaLobby(lua_State* _L) : L(_L) +LuaLobby::LuaLobby(lua_State* L) : L_Sim(luaUI->L_Sim), L_Draw(luaUI->L_Draw) { - if (L != luaUI->L) { + if (L != L_Sim && L != L_Draw) { luaL_error(L, "Tried to create a LuaLobby object in a non-LuaUI enviroment!"); } } @@ -179,7 +178,7 @@ int LuaLobby::meta_newindex(lua_State* L) /******************************************************************************/ /******************************************************************************/ -inline bool LuaLobby::PushCallIn(const LuaHashString& name) +inline bool LuaLobby::PushCallIn(lua_State *L, const LuaHashString& name) { // get callin lua function lua_rawgeti(L, LUA_REGISTRYINDEX, luaRefEvents); @@ -359,7 +358,7 @@ void LuaLobby::DoneConnecting(bool succes, const std::string& err) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -375,7 +374,7 @@ void LuaLobby::ServerGreeting(const std::string& serverVer, const std::string& s LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -393,7 +392,7 @@ void LuaLobby::RegisterDenied(const std::string& reason) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -408,7 +407,7 @@ void LuaLobby::RegisterAccepted() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -421,7 +420,7 @@ void LuaLobby::LoginDenied(const std::string& reason) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -436,7 +435,7 @@ void LuaLobby::LoginEnd() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -449,7 +448,7 @@ void LuaLobby::Aggreement(const std::string& text) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -464,7 +463,7 @@ void LuaLobby::Motd(const std::string& text) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -479,7 +478,7 @@ void LuaLobby::ServerMessage(const std::string& text) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -494,7 +493,7 @@ void LuaLobby::ServerMessageBox(const std::string& text, const std::string& url) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -510,7 +509,7 @@ void LuaLobby::AddUser(const std::string& name, const std::string& country, int LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -527,7 +526,7 @@ void LuaLobby::RemoveUser(const std::string& name) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -542,7 +541,7 @@ void LuaLobby::UserStatusUpdate(const std::string& name, ClientStatus status) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 8); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -562,7 +561,7 @@ void LuaLobby::ChannelInfo(const std::string& channel, unsigned users) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -578,7 +577,7 @@ void LuaLobby::ChannelInfoEnd() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -591,7 +590,7 @@ void LuaLobby::Mutelist(const std::string& channel, std::list list) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -613,7 +612,7 @@ void LuaLobby::Joined(const std::string& channame) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -628,7 +627,7 @@ void LuaLobby::ChannelMember(const std::string& channame, const std::string& nam LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -645,7 +644,7 @@ void LuaLobby::ChannelMemberLeft(const std::string& channame, const std::string& LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -662,7 +661,7 @@ void LuaLobby::JoinFailed(const std::string& channame, const std::string& reason LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -678,7 +677,7 @@ void LuaLobby::ChannelMemberKicked(const std::string& channame, const std::strin LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -695,7 +694,7 @@ void LuaLobby::ChannelTopic(const std::string& channame, const std::string& auth LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -713,7 +712,7 @@ void LuaLobby::ChannelMessage(const std::string& channel, const std::string& tex LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -729,7 +728,7 @@ void LuaLobby::Said(const std::string& channel, const std::string& user, const s LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -746,7 +745,7 @@ void LuaLobby::SaidEx(const std::string& channel, const std::string& user, const LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -763,7 +762,7 @@ void LuaLobby::SaidPrivate(const std::string& user, const std::string& text) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -779,7 +778,7 @@ void LuaLobby::Disconnected() LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } @@ -792,7 +791,7 @@ void LuaLobby::NetworkError(const std::string& msg) LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr(__FUNCTION__); - if (!PushCallIn(cmdStr)) { + if (!PushCallIn(L, cmdStr)) { return; } diff --git a/rts/Lua/LuaLobby.h b/rts/Lua/LuaLobby.h index 8490fe96a24..ff81f194e40 100644 --- a/rts/Lua/LuaLobby.h +++ b/rts/Lua/LuaLobby.h @@ -11,7 +11,7 @@ struct LuaHashString; class LuaLobby : public Connection { - LuaLobby(lua_State* L); + LuaLobby(lua_State* _L_Sim); ~LuaLobby(); public: @@ -26,11 +26,12 @@ class LuaLobby : public Connection static int meta_newindex(lua_State* L); private: - lua_State* L; + lua_State* L_Sim; + lua_State* L_Draw; int luaRef; // saves userdata int luaRefEvents; // saves table with callin lua functions - bool PushCallIn(const LuaHashString& name); + bool PushCallIn(lua_State *L, const LuaHashString& name); private: static int CreateLobby(lua_State* L); diff --git a/rts/Lua/LuaOpenGL.cpp b/rts/Lua/LuaOpenGL.cpp index 1b6fe6036de..72c602ca47a 100644 --- a/rts/Lua/LuaOpenGL.cpp +++ b/rts/Lua/LuaOpenGL.cpp @@ -1652,8 +1652,8 @@ int LuaOpenGL::FeatureShape(lua_State* L) /******************************************************************************/ /******************************************************************************/ -static const bool& fullRead = CLuaHandle::GetActiveFullRead(); -static const int& readAllyTeam = CLuaHandle::GetActiveReadAllyTeam(); +#define fullRead CLuaHandle::GetActiveFullRead() +#define readAllyTeam CLuaHandle::GetActiveReadAllyTeam() static inline CUnit* ParseDrawUnit(lua_State* L, const char* caller, int index) diff --git a/rts/Lua/LuaParser.cpp b/rts/Lua/LuaParser.cpp index 69ce53d23b0..b1708dd0ef4 100644 --- a/rts/Lua/LuaParser.cpp +++ b/rts/Lua/LuaParser.cpp @@ -148,7 +148,7 @@ void LuaParser::SetupEnv() bool LuaParser::Execute() { - if (L == NULL) { + if (!IsValid()) { errorLog = "could not initialize LUA library"; return false; } @@ -251,7 +251,7 @@ LuaTable LuaParser::GetRoot() void LuaParser::PushParam() { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } if (initDepth > 0) { lua_rawset(L, -3); } else { @@ -262,7 +262,7 @@ void LuaParser::PushParam() void LuaParser::GetTable(const string& name, bool overwrite) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushstring(L, name.c_str()); @@ -284,7 +284,7 @@ void LuaParser::GetTable(const string& name, bool overwrite) void LuaParser::GetTable(int index, bool overwrite) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushnumber(L, index); @@ -306,7 +306,7 @@ void LuaParser::GetTable(int index, bool overwrite) void LuaParser::EndTable() { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } assert(initDepth > 0); initDepth--; PushParam(); @@ -317,7 +317,7 @@ void LuaParser::EndTable() void LuaParser::AddFunc(const string& key, int (*func)(lua_State*)) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } if (func == NULL) { return; } lua_pushstring(L, key.c_str()); lua_pushcfunction(L, func); @@ -327,7 +327,7 @@ void LuaParser::AddFunc(const string& key, int (*func)(lua_State*)) void LuaParser::AddInt(const string& key, int value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushstring(L, key.c_str()); lua_pushnumber(L, value); PushParam(); @@ -336,7 +336,7 @@ void LuaParser::AddInt(const string& key, int value) void LuaParser::AddBool(const string& key, bool value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushstring(L, key.c_str()); lua_pushboolean(L, value); PushParam(); @@ -345,7 +345,7 @@ void LuaParser::AddBool(const string& key, bool value) void LuaParser::AddFloat(const string& key, float value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushstring(L, key.c_str()); lua_pushnumber(L, value); PushParam(); @@ -354,7 +354,7 @@ void LuaParser::AddFloat(const string& key, float value) void LuaParser::AddString(const string& key, const string& value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushstring(L, key.c_str()); lua_pushstring(L, value.c_str()); PushParam(); @@ -365,7 +365,7 @@ void LuaParser::AddString(const string& key, const string& value) void LuaParser::AddFunc(int key, int (*func)(lua_State*)) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } if (func == NULL) { return; } lua_pushnumber(L, key); lua_pushcfunction(L, func); @@ -375,7 +375,7 @@ void LuaParser::AddFunc(int key, int (*func)(lua_State*)) void LuaParser::AddInt(int key, int value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushnumber(L, key); lua_pushnumber(L, value); PushParam(); @@ -384,7 +384,7 @@ void LuaParser::AddInt(int key, int value) void LuaParser::AddBool(int key, bool value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushnumber(L, key); lua_pushboolean(L, value); PushParam(); @@ -393,7 +393,7 @@ void LuaParser::AddBool(int key, bool value) void LuaParser::AddFloat(int key, float value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushnumber(L, key); lua_pushnumber(L, value); PushParam(); @@ -402,7 +402,7 @@ void LuaParser::AddFloat(int key, float value) void LuaParser::AddString(int key, const string& value) { - if ((L == NULL) || (initDepth < 0)) { return; } + if (!IsValid() || (initDepth < 0)) { return; } lua_pushnumber(L, key); lua_pushstring(L, value.c_str()); PushParam(); diff --git a/rts/Lua/LuaRules.cpp b/rts/Lua/LuaRules.cpp index 05d2395bcf1..2934ca390c9 100644 --- a/rts/Lua/LuaRules.cpp +++ b/rts/Lua/LuaRules.cpp @@ -58,7 +58,7 @@ void CLuaRules::LoadHandler() new CLuaRules(); - if (luaRules->L == NULL) { + if (!luaRules->IsValid()) { delete luaRules; } } @@ -78,55 +78,59 @@ CLuaRules::CLuaRules() { luaRules = this; - if (L == NULL) { + if (!IsValid()) { return; } - fullCtrl = true; - fullRead = true; - ctrlTeam = AllAccessTeam; - readTeam = AllAccessTeam; - readAllyTeam = AllAccessTeam; - selectTeam = AllAccessTeam; + SetFullCtrl(true, true); + SetFullRead(true, true); + SetCtrlTeam(AllAccessTeam, true); + SetReadTeam(AllAccessTeam, true); + SetReadAllyTeam(AllAccessTeam, true); + SetSelectTeam(AllAccessTeam, true); Init(LuaRulesSyncedFilename, LuaRulesUnsyncedFilename, SPRING_VFS_MOD); - if (L == NULL) { + if (!IsValid()) { return; } - haveCommandFallback = HasCallIn("CommandFallback"); - haveAllowCommand = HasCallIn("AllowCommand"); - haveAllowUnitCreation = HasCallIn("AllowUnitCreation"); - haveAllowUnitTransfer = HasCallIn("AllowUnitTransfer"); - haveAllowUnitBuildStep = HasCallIn("AllowUnitBuildStep"); - haveAllowFeatureCreation = HasCallIn("AllowFeatureCreation"); - haveAllowFeatureBuildStep = HasCallIn("AllowFeatureBuildStep"); - haveAllowResourceLevel = HasCallIn("AllowResourceLevel"); - haveAllowResourceTransfer = HasCallIn("AllowResourceTransfer"); - haveAllowDirectUnitControl = HasCallIn("AllowDirectUnitControl"); - haveAllowStartPosition = HasCallIn("AllowStartPosition"); - - haveMoveCtrlNotify = HasCallIn("MoveCtrlNotify"); - haveTerraformComplete = HasCallIn("TerraformComplete"); - haveAllowWeaponTargetCheck = HasCallIn("AllowWeaponTargetCheck"); - haveAllowWeaponTarget = HasCallIn("AllowWeaponTarget"); - haveUnitPreDamaged = HasCallIn("UnitPreDamaged"); - haveShieldPreDamaged = HasCallIn("ShieldPreDamaged"); - - haveDrawUnit = HasCallIn("DrawUnit"); - haveDrawFeature = HasCallIn("DrawFeature"); - haveAICallIn = HasCallIn("AICallIn"); - - SetupUnsyncedFunction("DrawUnit"); - SetupUnsyncedFunction("DrawFeature"); - SetupUnsyncedFunction("AICallIn"); + BEGIN_ITERATE_LUA_STATES(); + + haveCommandFallback = HasCallIn(L, "CommandFallback"); + haveAllowCommand = HasCallIn(L, "AllowCommand"); + haveAllowUnitCreation = HasCallIn(L, "AllowUnitCreation"); + haveAllowUnitTransfer = HasCallIn(L, "AllowUnitTransfer"); + haveAllowUnitBuildStep = HasCallIn(L, "AllowUnitBuildStep"); + haveAllowFeatureCreation = HasCallIn(L, "AllowFeatureCreation"); + haveAllowFeatureBuildStep = HasCallIn(L, "AllowFeatureBuildStep"); + haveAllowResourceLevel = HasCallIn(L, "AllowResourceLevel"); + haveAllowResourceTransfer = HasCallIn(L, "AllowResourceTransfer"); + haveAllowDirectUnitControl = HasCallIn(L, "AllowDirectUnitControl"); + haveAllowStartPosition = HasCallIn(L, "AllowStartPosition"); + + haveMoveCtrlNotify = HasCallIn(L, "MoveCtrlNotify"); + haveTerraformComplete = HasCallIn(L, "TerraformComplete"); + haveAllowWeaponTargetCheck = HasCallIn(L, "AllowWeaponTargetCheck"); + haveAllowWeaponTarget = HasCallIn(L, "AllowWeaponTarget"); + haveUnitPreDamaged = HasCallIn(L, "UnitPreDamaged"); + haveShieldPreDamaged = HasCallIn(L, "ShieldPreDamaged"); + + haveDrawUnit = HasCallIn(L, "DrawUnit"); + haveDrawFeature = HasCallIn(L, "DrawFeature"); + haveAICallIn = HasCallIn(L, "AICallIn"); + + SetupUnsyncedFunction(L, "DrawUnit"); + SetupUnsyncedFunction(L, "DrawFeature"); + SetupUnsyncedFunction(L, "AICallIn"); + + END_ITERATE_LUA_STATES(); } CLuaRules::~CLuaRules() { - if (L != NULL) { + if (L_Sim != NULL || L_Draw != NULL) { Shutdown(); KillLua(); } @@ -141,7 +145,7 @@ CLuaRules::~CLuaRules() } -bool CLuaRules::AddSyncedCode() +bool CLuaRules::AddSyncedCode(lua_State *L) { lua_getglobal(L, "Script"); LuaPushNamedCFunc(L, "PermitHelperAIs", PermitHelperAIs); @@ -151,7 +155,7 @@ bool CLuaRules::AddSyncedCode() } -bool CLuaRules::AddUnsyncedCode() +bool CLuaRules::AddUnsyncedCode(lua_State *L) { lua_pushstring(L, "UNSYNCED"); lua_gettable(L, LUA_REGISTRYINDEX); @@ -176,10 +180,10 @@ bool CLuaRules::AddUnsyncedCode() // LuaRules Call-Ins // -bool CLuaRules::SyncedUpdateCallIn(const string& name) +bool CLuaRules::SyncedUpdateCallIn(lua_State *L, const string& name) { #define UPDATE_HAVE_CALLIN(callinName) \ - have ## callinName = HasCallIn( #callinName ); + have ## callinName = HasCallIn( L, #callinName ); if (name == "CommandFallback" ) { UPDATE_HAVE_CALLIN(CommandFallback); } else if (name == "AllowCommand" ) { UPDATE_HAVE_CALLIN(AllowCommand); } @@ -199,7 +203,7 @@ bool CLuaRules::SyncedUpdateCallIn(const string& name) else if (name == "AllowWeaponTargetCheck") { UPDATE_HAVE_CALLIN(AllowWeaponTargetCheck); } else if (name == "AllowWeaponTarget" ) { UPDATE_HAVE_CALLIN(AllowWeaponTarget); } else { - return CLuaHandleSynced::SyncedUpdateCallIn(name); + return CLuaHandleSynced::SyncedUpdateCallIn(L, name); } #undef UPDATE_HAVE_CALLIN @@ -207,13 +211,13 @@ bool CLuaRules::SyncedUpdateCallIn(const string& name) } -bool CLuaRules::UnsyncedUpdateCallIn(const string& name) +bool CLuaRules::UnsyncedUpdateCallIn(lua_State *L, const string& name) { - if (name == "DrawUnit" ) { haveDrawUnit = HasCallIn("DrawUnit" ); } - else if (name == "DrawFeature") { haveDrawFeature = HasCallIn("DrawFeature"); } - else if (name == "AICallIn" ) { haveAICallIn = HasCallIn("AICallIn" ); } + if (name == "DrawUnit" ) { haveDrawUnit = HasCallIn(L, "DrawUnit" ); } + else if (name == "DrawFeature") { haveDrawFeature = HasCallIn(L, "DrawFeature"); } + else if (name == "AICallIn" ) { haveAICallIn = HasCallIn(L, "AICallIn" ); } - return CLuaHandleSynced::UnsyncedUpdateCallIn(name); + return CLuaHandleSynced::UnsyncedUpdateCallIn(L, name); } @@ -776,7 +780,7 @@ bool CLuaRules::UnitPreDamaged(const CUnit* unit, const CUnit* attacker, LUA_CALL_IN_CHECK(L); lua_checkstack(L, 11); - const int errfunc = SetupTraceback(); + const int errfunc = SetupTraceback(L); static const LuaHashString cmdStr("UnitPreDamaged"); if (!cmdStr.GetGlobalFunc(L)) { @@ -791,7 +795,7 @@ bool CLuaRules::UnitPreDamaged(const CUnit* unit, const CUnit* attacker, lua_pushnumber(L, unit->team); lua_pushnumber(L, damage); lua_pushboolean(L, paralyzer); - if (fullRead) { + if (GetFullRead()) { lua_pushnumber(L, weaponID); argCount += 1; if (attacker != NULL) { @@ -836,7 +840,7 @@ bool CLuaRules::ShieldPreDamaged( LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5 + 1); - const int errfunc(SetupTraceback()); + const int errfunc(SetupTraceback(L)); static const LuaHashString cmdStr("ShieldPreDamaged"); bool ret = false; @@ -880,7 +884,7 @@ bool CLuaRules::AllowWeaponTargetCheck(unsigned int attackerID, unsigned int att LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3 + 1); - const int errfunc(SetupTraceback()); + const int errfunc(SetupTraceback(L)); static const LuaHashString cmdStr("AllowWeaponTargetCheck"); bool ret = false; @@ -916,7 +920,7 @@ bool CLuaRules::AllowWeaponTarget( LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4 + 2); - const int errfunc(SetupTraceback()); + const int errfunc(SetupTraceback(L)); static const LuaHashString cmdStr("AllowWeaponTarget"); bool ret = false; diff --git a/rts/Lua/LuaRules.h b/rts/Lua/LuaRules.h index 9987cdf8b58..5f5ff75fb0b 100644 --- a/rts/Lua/LuaRules.h +++ b/rts/Lua/LuaRules.h @@ -32,8 +32,8 @@ class CLuaRules : public CLuaHandleSynced static void FreeHandler(); public: // call-ins - bool SyncedUpdateCallIn(const string& name); - bool UnsyncedUpdateCallIn(const string& name); + bool SyncedUpdateCallIn(lua_State *L, const string& name); + bool UnsyncedUpdateCallIn(lua_State *L, const string& name); bool CommandFallback(const CUnit* unit, const Command& cmd); bool AllowCommand(const CUnit* unit, const Command& cmd, bool fromSynced); @@ -85,8 +85,8 @@ class CLuaRules : public CLuaHandleSynced ~CLuaRules(); protected: - bool AddSyncedCode(); - bool AddUnsyncedCode(); + bool AddSyncedCode(lua_State *L); + bool AddUnsyncedCode(lua_State *L); int UnpackCobArg(lua_State* L); diff --git a/rts/Lua/LuaSyncedRead.cpp b/rts/Lua/LuaSyncedRead.cpp index 45a8142c0c5..c32d62ee721 100644 --- a/rts/Lua/LuaSyncedRead.cpp +++ b/rts/Lua/LuaSyncedRead.cpp @@ -92,8 +92,8 @@ enum UnitAllegiance { /******************************************************************************/ /******************************************************************************/ -static const bool& fullRead = CLuaHandle::GetActiveFullRead(); -static const int& readAllyTeam = CLuaHandle::GetActiveReadAllyTeam(); +#define fullRead CLuaHandle::GetActiveFullRead() +#define readAllyTeam CLuaHandle::GetActiveReadAllyTeam() /******************************************************************************/ diff --git a/rts/Lua/LuaUnsyncedCtrl.cpp b/rts/Lua/LuaUnsyncedCtrl.cpp index e9548a295f3..5be9ec29283 100644 --- a/rts/Lua/LuaUnsyncedCtrl.cpp +++ b/rts/Lua/LuaUnsyncedCtrl.cpp @@ -90,8 +90,8 @@ const int CMD_INDEX_OFFSET = 1; // starting index for command descriptions CUnitSet LuaUnsyncedCtrl::drawCmdQueueUnits; -static const bool& fullRead = CLuaHandle::GetActiveFullRead(); -static const int& readAllyTeam = CLuaHandle::GetActiveReadAllyTeam(); +#define fullRead CLuaHandle::GetActiveFullRead() +#define readAllyTeam CLuaHandle::GetActiveReadAllyTeam() /******************************************************************************/ diff --git a/rts/Lua/LuaUnsyncedRead.cpp b/rts/Lua/LuaUnsyncedRead.cpp index a93ab5634cb..336d311c724 100644 --- a/rts/Lua/LuaUnsyncedRead.cpp +++ b/rts/Lua/LuaUnsyncedRead.cpp @@ -69,8 +69,8 @@ const int CMD_INDEX_OFFSET = 1; // starting index for command descriptions /******************************************************************************/ /******************************************************************************/ -static const bool& fullRead = CLuaHandle::GetActiveFullRead(); -static const int& readAllyTeam = CLuaHandle::GetActiveReadAllyTeam(); +#define fullRead CLuaHandle::GetActiveFullRead() +#define readAllyTeam CLuaHandle::GetActiveReadAllyTeam() /******************************************************************************/ diff --git a/rts/Sim/Units/COB/LuaUnitScript.cpp b/rts/Sim/Units/COB/LuaUnitScript.cpp index 4e50f7a09cc..172acbcdf42 100644 --- a/rts/Sim/Units/COB/LuaUnitScript.cpp +++ b/rts/Sim/Units/COB/LuaUnitScript.cpp @@ -1,6 +1,7 @@ /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ #define DEBUG_LUA 0 +#define LUA_SYNCED_ONLY #include "LuaUnitScript.h" @@ -167,7 +168,7 @@ CUnitScript* CLuaUnitScript::activeScript; CLuaUnitScript::CLuaUnitScript(lua_State* L, CUnit* unit) : CUnitScript(unit, unit->localmodel->pieces) - , handle(CLuaHandle::activeHandle), L(L) + , handle(CLuaHandle::GetActiveHandle()), L(L) , scriptIndex(LUAFN_Last, LUA_NOREF) , inKilled(false) { @@ -294,7 +295,7 @@ void CLuaUnitScript::RemoveCallIn(const string& fname) void CLuaUnitScript::ShowScriptError(const string& msg) { // if we are in the same handle, we can truely raise an error - if (CLuaHandle::activeHandle == handle) { + if (CLuaHandle::GetActiveHandle() == handle) { luaL_error(L, "Lua UnitScript error: %s", msg.c_str()); } else { diff --git a/rts/System/EventClient.cpp b/rts/System/EventClient.cpp index ce01ec62b85..31038098bfb 100644 --- a/rts/System/EventClient.cpp +++ b/rts/System/EventClient.cpp @@ -10,7 +10,7 @@ CEventClient::CEventClient(const std::string& _name, int _order, bool _synced) : name(_name) , order(_order) - , synced(_synced) + , synced_(_synced) { } diff --git a/rts/System/EventClient.h b/rts/System/EventClient.h index 25ce9672fbf..90ac7260fcf 100644 --- a/rts/System/EventClient.h +++ b/rts/System/EventClient.h @@ -34,7 +34,7 @@ class CEventClient public: inline const std::string& GetName() const { return name; } inline int GetOrder() const { return order; } - inline bool GetSynced() const { return synced; } + inline bool GetSynced() const { return synced_; } // used by the eventHandler to register // call-ins when an EventClient is being added @@ -50,7 +50,7 @@ class CEventClient private: const std::string name; const int order; - const bool synced; + const bool synced_; protected: CEventClient(const std::string& name, int order, bool synced); diff --git a/rts/System/EventHandler.cpp b/rts/System/EventHandler.cpp index abdefaf70db..74f107ce449 100644 --- a/rts/System/EventHandler.cpp +++ b/rts/System/EventHandler.cpp @@ -402,14 +402,15 @@ void CEventHandler::Load(CArchiveBase* archive) } #ifdef USE_GML -#define GML_DRAW_CALLIN_SELECTOR() if(!gc->enableDrawCallIns) return; +#define GML_DRAW_CALLIN_SELECTOR() if(!gc->enableDrawCallIns) return #else #define GML_DRAW_CALLIN_SELECTOR() #endif void CEventHandler::Update() { - GML_DRAW_CALLIN_SELECTOR() + GML_DRAW_CALLIN_SELECTOR(); + const int count = listUpdate.size(); if (count <= 0) @@ -439,7 +440,7 @@ void CEventHandler::ViewResize() #define DRAW_CALLIN(name) \ void CEventHandler:: Draw ## name () \ { \ - GML_DRAW_CALLIN_SELECTOR() \ + GML_DRAW_CALLIN_SELECTOR(); \ const int count = listDraw ## name.size(); \ if (count <= 0) { \ return; \ diff --git a/rts/System/Platform/Threading.cpp b/rts/System/Platform/Threading.cpp index 1c6bf4055c8..a2c985ac1e9 100644 --- a/rts/System/Platform/Threading.cpp +++ b/rts/System/Platform/Threading.cpp @@ -1,12 +1,20 @@ /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */ #include "Threading.h" +#include "Rendering/GL/myGL.h" namespace Threading { static bool haveMainThreadID = false; static boost::thread *mainThread = NULL; static boost::thread::id mainThreadID; static std::runtime_error *threadError = NULL; +#ifdef USE_GML + static int const noThreadID = -1; + static int simThreadID = noThreadID; +#else + static boost::thread::id noThreadID; + static boost::thread::id simThreadID; +#endif void SetMainThread(boost::thread *mt) { if (!haveMainThreadID) { @@ -20,6 +28,21 @@ namespace Threading { return mainThread; } + void SetSimThread(bool set) { +#ifdef USE_GML // gmlThreadNumber is likely to be much faster than boost::this_thread::get_id() + simThreadID = set ? gmlThreadNumber : noThreadID; +#else + simThreadID = set ? boost::this_thread::get_id() : noThreadID; +#endif + } + bool IsSimThread() { +#ifdef USE_GML + return gmlThreadNumber == simThreadID; +#else + return boost::this_thread::get_id() == simThreadID; +#endif + } + void SetThreadError(const std::string &s) { threadError = new std::runtime_error(s); } diff --git a/rts/System/Platform/Threading.h b/rts/System/Platform/Threading.h index d370fa634fc..b66c16e6719 100644 --- a/rts/System/Platform/Threading.h +++ b/rts/System/Platform/Threading.h @@ -8,6 +8,8 @@ namespace Threading { void SetMainThread(boost::thread *mt); boost::thread *GetMainThread(); + void SetSimThread(bool set); + bool IsSimThread(); void SetThreadError(const std::string &s); std::runtime_error GetThreadError(); bool IsMainThread(); diff --git a/rts/System/SpringApp.cpp b/rts/System/SpringApp.cpp index 9b01cb94ad8..9ea742032b1 100644 --- a/rts/System/SpringApp.cpp +++ b/rts/System/SpringApp.cpp @@ -981,6 +981,16 @@ void SpringApp::Startup() } } +bool SpringApp::UpdateSim(CGameController *ac) +{ + GML_MSTMUTEX_LOCK(sim); // UpdateSim + + Threading::SetSimThread(true); + bool ret = ac->Update(); + Threading::SetSimThread(false); + return ret; +} + #if defined(USE_GML) && GML_ENABLE_SIM volatile int gmlMultiThreadSim; volatile int gmlStartSim; @@ -1004,12 +1014,8 @@ int SpringApp::Sim() CrashHandler::ClearSimWDT(); gmlProcessor->ExpandAuxQueue(); - { - GML_MSTMUTEX_LOCK(sim); // Sim - - if(!activeController->Update()) - return 0; - } + if(!UpdateSim(activeController)) + return 0; gmlProcessor->GetQueue(); } @@ -1048,20 +1054,16 @@ int SpringApp::Update() #if defined(USE_GML) && GML_ENABLE_SIM if (gmlMultiThreadSim) { if (!gs->frameNum) { - GML_MSTMUTEX_LOCK(sim); // Update - - activeController->Update(); + UpdateSim(activeController); if (gs->frameNum) { gmlStartSim = 1; } } } else { - GML_MSTMUTEX_LOCK(sim); // Update - - activeController->Update(); + UpdateSim(activeController); } #else - if (!activeController->Update()) { + if (!UpdateSim(activeController)) { ret = 0; } else { #endif diff --git a/rts/System/SpringApp.h b/rts/System/SpringApp.h index d2d5437c34e..1d905ed84a0 100644 --- a/rts/System/SpringApp.h +++ b/rts/System/SpringApp.h @@ -36,6 +36,7 @@ class SpringApp bool SetSDLVideoMode(); //!< Sets SDL video mode void SetProcessAffinity(int) const; int Update(); //!< Run simulation and draw + bool UpdateSim(CGameController *ac); #if defined(USE_GML) && GML_ENABLE_SIM int Sim(); //!< Simulation loop diff --git a/rts/lib/gml/gml.cpp b/rts/lib/gml/gml.cpp index 98bc970ae0e..816ea688e96 100644 --- a/rts/lib/gml/gml.cpp +++ b/rts/lib/gml/gml.cpp @@ -231,6 +231,7 @@ boost::mutex rflashmutex; boost::mutex rpiecemutex; boost::mutex rfeatmutex; boost::mutex drawmutex; +boost::mutex recvmutex; #include boost::recursive_mutex unitmutex; @@ -245,6 +246,8 @@ boost::recursive_mutex &qnummutex=quadmutex; boost::recursive_mutex &groupmutex=selmutex; boost::recursive_mutex &grpselmutex=selmutex; boost::recursive_mutex laycmdmutex; +boost::recursive_mutex luasimmutex; +boost::recursive_mutex luadrawmutex; gmlMutex simmutex; #endif diff --git a/rts/lib/gml/gml.h b/rts/lib/gml/gml.h index b8fca7774fa..5fb669af195 100644 --- a/rts/lib/gml/gml.h +++ b/rts/lib/gml/gml.h @@ -187,6 +187,7 @@ extern boost::mutex rflashmutex; extern boost::mutex rpiecemutex; extern boost::mutex rfeatmutex; extern boost::mutex drawmutex; +extern boost::mutex recvmutex; #include extern boost::recursive_mutex unitmutex; @@ -201,6 +202,8 @@ extern boost::recursive_mutex &qnummutex; extern boost::recursive_mutex &groupmutex; extern boost::recursive_mutex &grpselmutex; extern boost::recursive_mutex laycmdmutex; +extern boost::recursive_mutex luasimmutex; +extern boost::recursive_mutex luadrawmutex; extern gmlMutex simmutex;