From 6d4f6218a4d8e0a36186586a4252a60dbad7e374 Mon Sep 17 00:00:00 2001 From: jacob1 Date: Fri, 17 Feb 2023 21:58:57 -0500 Subject: [PATCH] Create wrapper around lua_pcall that properly tracks Lua execution time A bug existed before where certain events would not update Engine's lastTick. If the sim was lagging hard, then this could cause "script is not responding" errors to appear in unintentional situations. The starting execution time is tracked in LuaScriptInterface instead now, and set in tpt_lua_pcall --- src/gui/interface/Engine.h | 1 - src/lua/LegacyLuaAPI.cpp | 5 +++-- src/lua/LuaButton.cpp | 2 +- src/lua/LuaCheckbox.cpp | 2 +- src/lua/LuaScriptInterface.cpp | 34 +++++++++++++++++++--------------- src/lua/LuaScriptInterface.h | 4 ++++ src/lua/LuaSlider.cpp | 2 +- src/lua/LuaTextbox.cpp | 2 +- src/lua/LuaWindow.cpp | 28 ++++++++++++++-------------- 9 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/gui/interface/Engine.h b/src/gui/interface/Engine.h index 49b38dc3d..9656527ff 100644 --- a/src/gui/interface/Engine.h +++ b/src/gui/interface/Engine.h @@ -41,7 +41,6 @@ namespace ui inline bool Running() { return running_; } inline bool Broken() { return break_; } inline long unsigned int LastTick() { return lastTick; } - inline void LastTick(long unsigned int tick) { lastTick = tick; } void Exit(); void ConfirmExit(); void Break(); diff --git a/src/lua/LegacyLuaAPI.cpp b/src/lua/LegacyLuaAPI.cpp index dbba90a40..023beac2c 100644 --- a/src/lua/LegacyLuaAPI.cpp +++ b/src/lua/LegacyLuaAPI.cpp @@ -260,11 +260,12 @@ int luacon_elementwrite(lua_State* l) void luacon_hook(lua_State * l, lua_Debug * ar) { - if(ar->event == LUA_HOOKCOUNT && Platform::GetTime()-ui::Engine::Ref().LastTick() > 3000) + auto *luacon_ci = static_cast(commandInterface); + if (ar->event == LUA_HOOKCOUNT && Platform::GetTime() - luacon_ci->luaExecutionStart > 3000) { if(ConfirmPrompt::Blocking("Script not responding", "The Lua script may have stopped responding. There might be an infinite loop. Press \"Stop\" to stop it", "Stop")) luaL_error(l, "Error: Script not responding"); - ui::Engine::Ref().LastTick(Platform::GetTime()); + luacon_ci->luaExecutionStart = Platform::GetTime(); } } diff --git a/src/lua/LuaButton.cpp b/src/lua/LuaButton.cpp index c16b747aa..0a1734b71 100644 --- a/src/lua/LuaButton.cpp +++ b/src/lua/LuaButton.cpp @@ -73,7 +73,7 @@ void LuaButton::triggerAction() { lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); - if (lua_pcall(l, 1, 0, 0)) + if (tpt_lua_pcall(l, 1, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } diff --git a/src/lua/LuaCheckbox.cpp b/src/lua/LuaCheckbox.cpp index 475100e70..e3ca5bde0 100644 --- a/src/lua/LuaCheckbox.cpp +++ b/src/lua/LuaCheckbox.cpp @@ -72,7 +72,7 @@ void LuaCheckbox::triggerAction() lua_rawgeti(l, LUA_REGISTRYINDEX, actionFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); lua_pushboolean(l, checkbox->GetChecked()); - if (lua_pcall(l, 2, 0, 0)) + if (tpt_lua_pcall(l, 2, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } diff --git a/src/lua/LuaScriptInterface.cpp b/src/lua/LuaScriptInterface.cpp index c8a3dd27d..2b1ea9aec 100644 --- a/src/lua/LuaScriptInterface.cpp +++ b/src/lua/LuaScriptInterface.cpp @@ -436,8 +436,7 @@ tpt.partsdata = nil"); initLegacyProps(); - ui::Engine::Ref().LastTick(Platform::GetTime()); - if (luaL_loadbuffer(l, (const char *)eventcompat_lua, eventcompat_lua_size, "@[built-in eventcompat.lua]") || lua_pcall(l, 0, 0, 0)) + if (luaL_loadbuffer(l, (const char *)eventcompat_lua, eventcompat_lua_size, "@[built-in eventcompat.lua]") || tpt_lua_pcall(l, 0, 0, 0)) { throw std::runtime_error(ByteString("failed to load built-in eventcompat: ") + tpt_lua_toByteString(l, -1)); } @@ -462,7 +461,7 @@ void LuaScriptInterface::Init() { if (Platform::FileExists("autorun.lua")) { - if(luaL_loadfile(l, "autorun.lua") || lua_pcall(l, 0, 0, 0)) + if(luaL_loadfile(l, "autorun.lua") || tpt_lua_pcall(l, 0, 0, 0)) Log(CommandInterface::LogError, luacon_geterror()); else Log(CommandInterface::LogWarning, "Loaded autorun.lua"); @@ -3182,7 +3181,7 @@ static int luaUpdateWrapper(UPDATE_FUNC_ARGS) lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, surround_space); lua_pushinteger(luacon_ci->l, nt); - callret = lua_pcall(luacon_ci->l, 5, 1, 0); + callret = tpt_lua_pcall(luacon_ci->l, 5, 1, 0); if (callret) luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); if(lua_isboolean(luacon_ci->l, -1)){ @@ -3218,7 +3217,7 @@ static int luaGraphicsWrapper(GRAPHICS_FUNC_ARGS) lua_pushinteger(luacon_ci->l, *colr); lua_pushinteger(luacon_ci->l, *colg); lua_pushinteger(luacon_ci->l, *colb); - callret = lua_pcall(luacon_ci->l, 4, 10, 0); + callret = tpt_lua_pcall(luacon_ci->l, 4, 10, 0); if (callret) { luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); @@ -3264,7 +3263,7 @@ static void luaCreateWrapper(ELEMENT_CREATE_FUNC_ARGS) lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, t); lua_pushinteger(luacon_ci->l, v); - if (lua_pcall(luacon_ci->l, 5, 0, 0)) + if (tpt_lua_pcall(luacon_ci->l, 5, 0, 0)) { luacon_ci->Log(CommandInterface::LogError, "In create func: " + luacon_geterror()); lua_pop(luacon_ci->l, 1); @@ -3283,7 +3282,7 @@ static bool luaCreateAllowedWrapper(ELEMENT_CREATE_ALLOWED_FUNC_ARGS) lua_pushinteger(luacon_ci->l, x); lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, t); - if (lua_pcall(luacon_ci->l, 4, 1, 0)) + if (tpt_lua_pcall(luacon_ci->l, 4, 1, 0)) { luacon_ci->Log(CommandInterface::LogError, "In create allowed: " + luacon_geterror()); lua_pop(luacon_ci->l, 1); @@ -3309,7 +3308,7 @@ static void luaChangeTypeWrapper(ELEMENT_CHANGETYPE_FUNC_ARGS) lua_pushinteger(luacon_ci->l, y); lua_pushinteger(luacon_ci->l, from); lua_pushinteger(luacon_ci->l, to); - if (lua_pcall(luacon_ci->l, 5, 0, 0)) + if (tpt_lua_pcall(luacon_ci->l, 5, 0, 0)) { luacon_ci->Log(CommandInterface::LogError, "In change type: " + luacon_geterror()); lua_pop(luacon_ci->l, 1); @@ -3327,7 +3326,7 @@ static bool luaCtypeDrawWrapper(CTYPEDRAW_FUNC_ARGS) lua_pushinteger(luacon_ci->l, i); lua_pushinteger(luacon_ci->l, t); lua_pushinteger(luacon_ci->l, v); - if (lua_pcall(luacon_ci->l, 3, 1, 0)) + if (tpt_lua_pcall(luacon_ci->l, 3, 1, 0)) { luacon_ci->Log(CommandInterface::LogError, luacon_geterror()); lua_pop(luacon_ci->l, 1); @@ -4291,7 +4290,6 @@ static int PushGameControllerEvent(lua_State * l, const GameControllerEvent &eve bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event) { - ui::Engine::Ref().LastTick(Platform::GetTime()); bool cont = true; gameControllerEventHandlers[event.index()].Push(l); int len = lua_objlen(l, -1); @@ -4299,12 +4297,11 @@ bool LuaScriptInterface::HandleEvent(const GameControllerEvent &event) { lua_rawgeti(l, -1, i); int numArgs = PushGameControllerEvent(l, event); - int callret = lua_pcall(l, numArgs, 1, 0); + int callret = tpt_lua_pcall(l, numArgs, 1, 0); if (callret) { if (luacon_geterror() == "Error: Script not responding") { - ui::Engine::Ref().LastTick(Platform::GetTime()); for (int j = i; j <= len - 1; j++) { lua_rawgeti(l, -2, j + 1); @@ -4359,7 +4356,6 @@ int LuaScriptInterface::Command(String command) lastCode += "\n"; lastCode += command; ByteString tmp = ("return " + lastCode).ToUtf8(); - ui::Engine::Ref().LastTick(Platform::GetTime()); luaL_loadbuffer(l, tmp.data(), tmp.size(), "@console"); if (lua_type(l, -1) != LUA_TFUNCTION) { @@ -4379,7 +4375,7 @@ int LuaScriptInterface::Command(String command) else { lastCode = ""; - ret = lua_pcall(l, 0, LUA_MULTRET, 0); + ret = tpt_lua_pcall(l, 0, LUA_MULTRET, 0); if (ret) { lastError = luacon_geterror(); @@ -4714,7 +4710,7 @@ int tpt_lua_loadstring(lua_State *L, const ByteString &str) int tpt_lua_dostring(lua_State *L, const ByteString &str) { - return tpt_lua_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0); + return tpt_lua_loadstring(L, str) || tpt_lua_pcall(L, 0, LUA_MULTRET, 0); } bool tpt_lua_equalsString(lua_State *L, int index, const char *data, size_t size) @@ -4722,7 +4718,15 @@ bool tpt_lua_equalsString(lua_State *L, int index, const char *data, size_t size return lua_isstring(L, index) && lua_objlen(L, index) == size && !memcmp(lua_tostring(L, index), data, size); } +int tpt_lua_pcall(lua_State *L, int numArgs, int numResults, int errorFunc) +{ + auto *luacon_ci = static_cast(commandInterface); + luacon_ci->luaExecutionStart = Platform::GetTime(); + return lua_pcall(L, numArgs, numResults, errorFunc); +} + CommandInterface *CommandInterface::Create(GameController * c, GameModel * m) { return new LuaScriptInterface(c, m); } + diff --git a/src/lua/LuaScriptInterface.h b/src/lua/LuaScriptInterface.h index 3c1780d2f..d4e588d77 100644 --- a/src/lua/LuaScriptInterface.h +++ b/src/lua/LuaScriptInterface.h @@ -198,6 +198,7 @@ public: ui::Window * Window; lua_State *l; + long unsigned int luaExecutionStart = 0; std::map grabbed_components; LuaScriptInterface(GameController * c, GameModel * m); @@ -239,3 +240,6 @@ bool tpt_lua_equalsLiteral(lua_State *L, int index, const char (&lit)[N]) { return tpt_lua_equalsString(L, index, lit, N - 1U); } + +int tpt_lua_pcall(lua_State *L, int numArgs, int numResults, int errorFunc); + diff --git a/src/lua/LuaSlider.cpp b/src/lua/LuaSlider.cpp index 9208cbd1f..c177987ed 100644 --- a/src/lua/LuaSlider.cpp +++ b/src/lua/LuaSlider.cpp @@ -72,7 +72,7 @@ void LuaSlider::triggerOnValueChanged() lua_rawgeti(l, LUA_REGISTRYINDEX, onValueChangedFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); lua_pushinteger(l, slider->GetValue()); - if (lua_pcall(l, 2, 0, 0)) + if (tpt_lua_pcall(l, 2, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } diff --git a/src/lua/LuaTextbox.cpp b/src/lua/LuaTextbox.cpp index 477351281..be49df4af 100644 --- a/src/lua/LuaTextbox.cpp +++ b/src/lua/LuaTextbox.cpp @@ -60,7 +60,7 @@ void LuaTextbox::triggerOnTextChanged() { lua_rawgeti(l, LUA_REGISTRYINDEX, onTextChangedFunction); lua_rawgeti(l, LUA_REGISTRYINDEX, owner_ref); - if (lua_pcall(l, 1, 0, 0)) + if (tpt_lua_pcall(l, 1, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_optString(l, -1)); } diff --git a/src/lua/LuaWindow.cpp b/src/lua/LuaWindow.cpp index 25fa2d43c..a39fe97ce 100644 --- a/src/lua/LuaWindow.cpp +++ b/src/lua/LuaWindow.cpp @@ -224,7 +224,7 @@ void LuaWindow::triggerOnInitialized() if(onInitializedFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onInitializedFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -236,7 +236,7 @@ void LuaWindow::triggerOnExit() if(onExitFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onExitFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -249,7 +249,7 @@ void LuaWindow::triggerOnTick(float dt) { lua_rawgeti(l, LUA_REGISTRYINDEX, onTickFunction); lua_pushnumber(l, dt); - if(lua_pcall(l, 1, 0, 0)) + if(tpt_lua_pcall(l, 1, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -261,7 +261,7 @@ void LuaWindow::triggerOnDraw() if(onDrawFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onDrawFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -273,7 +273,7 @@ void LuaWindow::triggerOnFocus() if(onFocusFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onFocusFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -285,7 +285,7 @@ void LuaWindow::triggerOnBlur() if(onBlurFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onBlurFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -297,7 +297,7 @@ void LuaWindow::triggerOnTryExit() if(onTryExitFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onTryExitFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -309,7 +309,7 @@ void LuaWindow::triggerOnTryOkay() if(onTryOkayFunction) { lua_rawgeti(l, LUA_REGISTRYINDEX, onTryOkayFunction); - if(lua_pcall(l, 0, 0, 0)) + if(tpt_lua_pcall(l, 0, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -325,7 +325,7 @@ void LuaWindow::triggerOnMouseMove(int x, int y, int dx, int dy) lua_pushinteger(l, y); lua_pushinteger(l, dx); lua_pushinteger(l, dy); - if(lua_pcall(l, 4, 0, 0)) + if(tpt_lua_pcall(l, 4, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -340,7 +340,7 @@ void LuaWindow::triggerOnMouseDown(int x, int y, unsigned button) lua_pushinteger(l, x); lua_pushinteger(l, y); lua_pushinteger(l, button); - if(lua_pcall(l, 3, 0, 0)) + if(tpt_lua_pcall(l, 3, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -355,7 +355,7 @@ void LuaWindow::triggerOnMouseUp(int x, int y, unsigned button) lua_pushinteger(l, x); lua_pushinteger(l, y); lua_pushinteger(l, button); - if(lua_pcall(l, 3, 0, 0)) + if(tpt_lua_pcall(l, 3, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -370,7 +370,7 @@ void LuaWindow::triggerOnMouseWheel(int x, int y, int d) lua_pushinteger(l, x); lua_pushinteger(l, y); lua_pushinteger(l, d); - if(lua_pcall(l, 3, 0, 0)) + if(tpt_lua_pcall(l, 3, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -387,7 +387,7 @@ void LuaWindow::triggerOnKeyPress(int key, int scan, bool repeat, bool shift, bo lua_pushboolean(l, shift); lua_pushboolean(l, ctrl); lua_pushboolean(l, alt); - if(lua_pcall(l, 5, 0, 0)) + if(tpt_lua_pcall(l, 5, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); } @@ -404,7 +404,7 @@ void LuaWindow::triggerOnKeyRelease(int key, int scan, bool repeat, bool shift, lua_pushboolean(l, shift); lua_pushboolean(l, ctrl); lua_pushboolean(l, alt); - if(lua_pcall(l, 5, 0, 0)) + if(tpt_lua_pcall(l, 5, 0, 0)) { ci->Log(CommandInterface::LogError, tpt_lua_toString(l, -1)); }