From 799d1d595505acaa7f05a6d92db5f8f2d258f53e Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 8 Apr 2024 16:55:26 +0300 Subject: Add script termination option to 'Lua Scripts' floater --- indra/llcommon/llapp.cpp | 1 + indra/llcommon/lualistener.cpp | 8 +++++--- indra/llcommon/lualistener.h | 2 ++ indra/newview/llfloaterluascripts.cpp | 6 ++++++ indra/newview/llfloaterluascripts.h | 1 + indra/newview/llluamanager.cpp | 16 ++++++++++++++++ indra/newview/llluamanager.h | 5 ++++- indra/newview/skins/default/xui/en/menu_lua_scripts.xml | 8 ++++++++ 8 files changed, 43 insertions(+), 4 deletions(-) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index b99166991f..905db9e491 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -429,6 +429,7 @@ void LLApp::setStatus(EAppStatus status) statsd = LLSD::Integer(status); } LLEventPumps::instance().obtain("LLApp").post(llsd::map("status", statsd)); + LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close_all")); } } diff --git a/indra/llcommon/lualistener.cpp b/indra/llcommon/lualistener.cpp index 82e32860db..c11ab6b1c3 100644 --- a/indra/llcommon/lualistener.cpp +++ b/indra/llcommon/lualistener.cpp @@ -33,18 +33,20 @@ std::ostream& operator<<(std::ostream& out, const LuaListener& self) LuaListener::LuaListener(lua_State* L): super(getUniqueKey()), + mCoroName(LLCoros::getName()), mListener(new LLLeapListener( "LuaListener", [this](const std::string& pump, const LLSD& data) { return queueEvent(pump, data); })), // Listen for shutdown events on the "LLApp" LLEventPump. mShutdownConnection( - LLEventPumps::instance().obtain("LLApp").listen( + LLEventPumps::instance().obtain("LLLua").listen( LLEventPump::inventName("LuaState"), [this](const LLSD& status) { - const auto& statsd = status["status"]; - if (statsd.asString() != "running") + const auto& coro_name = status["coro"].asString(); + const auto& statsd = status["status"].asString(); + if ((statsd == "close_all") || ((statsd == "close") && (coro_name == mCoroName))) { // If a Lua script is still blocked in getNext() during // viewer shutdown, close the queue to wake up getNext(). diff --git a/indra/llcommon/lualistener.h b/indra/llcommon/lualistener.h index 40ccfba8fe..d349ee23fd 100644 --- a/indra/llcommon/lualistener.h +++ b/indra/llcommon/lualistener.h @@ -75,6 +75,8 @@ private: std::unique_ptr mListener; LLTempBoundListener mShutdownConnection; + + std::string mCoroName; }; #endif /* ! defined(LL_LUALISTENER_H) */ diff --git a/indra/newview/llfloaterluascripts.cpp b/indra/newview/llfloaterluascripts.cpp index bd845a97d6..8f6ccc50fa 100644 --- a/indra/newview/llfloaterluascripts.cpp +++ b/indra/newview/llfloaterluascripts.cpp @@ -45,6 +45,11 @@ LLFloaterLUAScripts::LLFloaterLUAScripts(const LLSD &key) { gViewerWindow->getWindow()->openFolder(mTargetFolderPath); }); + mCommitCallbackRegistrar.add("Script.Terminate", [this](LLUICtrl*, const LLSD &userdata) + { + LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close", "coro", mCoroName)); + LLLUAmanager::terminateScript(mCoroName); + }); } @@ -113,6 +118,7 @@ void LLFloaterLUAScripts::onScrollListRightClicked(LLUICtrl *ctrl, S32 x, S32 y) if (menu) { mTargetFolderPath = std::filesystem::path((item->getColumn(1)->getValue().asString())).parent_path().string(); + mCoroName = item->getValue().asString(); menu->show(x, y); LLMenuGL::showPopup(this, menu, x, y); } diff --git a/indra/newview/llfloaterluascripts.h b/indra/newview/llfloaterluascripts.h index 548bbd10f6..c7c888b55a 100644 --- a/indra/newview/llfloaterluascripts.h +++ b/indra/newview/llfloaterluascripts.h @@ -47,6 +47,7 @@ private: std::unique_ptr mUpdateTimer; LLScrollListCtrl* mScriptList; std::string mTargetFolderPath; + std::string mCoroName; LLHandle mContextMenuHandle; }; diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index 1d55313813..35a73aaabe 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -49,6 +49,7 @@ #include std::map LLLUAmanager::sScriptNames; +std::set LLLUAmanager::sTerminationList; lua_function(sleep, "sleep(seconds): pause the running coroutine") { @@ -188,6 +189,21 @@ void LLLUAmanager::runScriptFile(const std::string &filename, script_result_fn r // A script_finished_fn is used to initialize the LuaState. // It will be called when the LuaState is destroyed. LuaState L(finished_cb); + + static int index = 0; + lua_callbacks(L)->interrupt = [](lua_State *L, int gc) + { + if (gc >= 0) + return; + + std::set scripts = LLLUAmanager::getTerminationList(); + std::string coro = LLCoros::getName(); + if (scripts.find(coro) != scripts.end()) + { + sTerminationList.erase(coro); + lluau::error(L, "Script was terminated"); + } + }; std::string text{std::istreambuf_iterator(in_file), {}}; auto [count, result] = L.expr(filename, text); if (result_cb) diff --git a/indra/newview/llluamanager.h b/indra/newview/llluamanager.h index fe4db22fca..d671719bc4 100644 --- a/indra/newview/llluamanager.h +++ b/indra/newview/llluamanager.h @@ -85,9 +85,12 @@ public: static void runScriptOnLogin(); static const std::map getScriptNames() { return sScriptNames; } + static std::set getTerminationList() { return sTerminationList; } + static void terminateScript(std::string& coro_name) { sTerminationList.insert(coro_name); } private: - static std::map sScriptNames; + static std::map sScriptNames; + static std::set sTerminationList; }; class LLRequireResolver diff --git a/indra/newview/skins/default/xui/en/menu_lua_scripts.xml b/indra/newview/skins/default/xui/en/menu_lua_scripts.xml index 8f718abe17..645fee405d 100644 --- a/indra/newview/skins/default/xui/en/menu_lua_scripts.xml +++ b/indra/newview/skins/default/xui/en/menu_lua_scripts.xml @@ -8,4 +8,12 @@ + + + + -- cgit v1.2.3 From e6aa6d22a107161b0bf08a45e9a90e749a824d9b Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 9 Apr 2024 22:37:34 +0300 Subject: mac build fix - remove unused variable --- indra/newview/llluamanager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index 35a73aaabe..344ab1bb99 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -190,7 +190,6 @@ void LLLUAmanager::runScriptFile(const std::string &filename, script_result_fn r // It will be called when the LuaState is destroyed. LuaState L(finished_cb); - static int index = 0; lua_callbacks(L)->interrupt = [](lua_State *L, int gc) { if (gc >= 0) -- cgit v1.2.3 From 396ae60e1528515d0cbdfc4290b24ccb172998c8 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 12 Apr 2024 19:28:29 +0300 Subject: 'Lua Scripts' floater clean up --- indra/llcommon/lualistener.cpp | 4 ++-- indra/newview/llfloaterluascripts.cpp | 16 +++++++++++----- indra/newview/llfloaterluascripts.h | 2 -- indra/newview/llluamanager.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/indra/llcommon/lualistener.cpp b/indra/llcommon/lualistener.cpp index c11ab6b1c3..d4bd73a9fb 100644 --- a/indra/llcommon/lualistener.cpp +++ b/indra/llcommon/lualistener.cpp @@ -44,8 +44,8 @@ LuaListener::LuaListener(lua_State* L): LLEventPump::inventName("LuaState"), [this](const LLSD& status) { - const auto& coro_name = status["coro"].asString(); - const auto& statsd = status["status"].asString(); + auto coro_name = status["coro"].asString(); + auto statsd = status["status"].asString(); if ((statsd == "close_all") || ((statsd == "close") && (coro_name == mCoroName))) { // If a Lua script is still blocked in getNext() during diff --git a/indra/newview/llfloaterluascripts.cpp b/indra/newview/llfloaterluascripts.cpp index 8f6ccc50fa..30353a7210 100644 --- a/indra/newview/llfloaterluascripts.cpp +++ b/indra/newview/llfloaterluascripts.cpp @@ -43,12 +43,20 @@ LLFloaterLUAScripts::LLFloaterLUAScripts(const LLSD &key) { mCommitCallbackRegistrar.add("Script.OpenFolder", [this](LLUICtrl*, const LLSD &userdata) { - gViewerWindow->getWindow()->openFolder(mTargetFolderPath); + if (mScriptList->hasSelectedItem()) + { + std::string target_folder_path = std::filesystem::path((mScriptList->getFirstSelected()->getColumn(1)->getValue().asString())).parent_path().string(); + gViewerWindow->getWindow()->openFolder(target_folder_path); + } }); mCommitCallbackRegistrar.add("Script.Terminate", [this](LLUICtrl*, const LLSD &userdata) { - LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close", "coro", mCoroName)); - LLLUAmanager::terminateScript(mCoroName); + if (mScriptList->hasSelectedItem()) + { + std::string coro_name = mScriptList->getSelectedValue(); + LLEventPumps::instance().obtain("LLLua").post(llsd::map("status", "close", "coro", coro_name)); + LLLUAmanager::terminateScript(coro_name); + } }); } @@ -117,8 +125,6 @@ void LLFloaterLUAScripts::onScrollListRightClicked(LLUICtrl *ctrl, S32 x, S32 y) auto menu = mContextMenuHandle.get(); if (menu) { - mTargetFolderPath = std::filesystem::path((item->getColumn(1)->getValue().asString())).parent_path().string(); - mCoroName = item->getValue().asString(); menu->show(x, y); LLMenuGL::showPopup(this, menu, x, y); } diff --git a/indra/newview/llfloaterluascripts.h b/indra/newview/llfloaterluascripts.h index c7c888b55a..932c5c78dd 100644 --- a/indra/newview/llfloaterluascripts.h +++ b/indra/newview/llfloaterluascripts.h @@ -46,8 +46,6 @@ private: std::unique_ptr mUpdateTimer; LLScrollListCtrl* mScriptList; - std::string mTargetFolderPath; - std::string mCoroName; LLHandle mContextMenuHandle; }; diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index 344ab1bb99..853ed5a634 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -192,14 +192,14 @@ void LLLUAmanager::runScriptFile(const std::string &filename, script_result_fn r lua_callbacks(L)->interrupt = [](lua_State *L, int gc) { + // skip if we're interrupting only for garbage collection if (gc >= 0) return; - std::set scripts = LLLUAmanager::getTerminationList(); - std::string coro = LLCoros::getName(); - if (scripts.find(coro) != scripts.end()) + auto it = sTerminationList.find(LLCoros::getName()); + if (it != sTerminationList.end()) { - sTerminationList.erase(coro); + sTerminationList.erase(it); lluau::error(L, "Script was terminated"); } }; -- cgit v1.2.3