From 32f54eb55507220dc632f2422d1b69a995757961 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Mon, 15 Sep 2025 20:17:08 +0200 Subject: [PATCH] Turn menu.saveGame into a delayed action --- CMakeLists.txt | 2 +- apps/openmw/mwlua/luamanagerimp.cpp | 10 ++++++++++ apps/openmw/mwlua/luamanagerimp.hpp | 4 +++- apps/openmw/mwlua/menuscripts.cpp | 18 +++++++++++------- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 834668e92a..63ed9edfe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...") set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MINOR 50) set(OPENMW_VERSION_RELEASE 0) -set(OPENMW_LUA_API_REVISION 95) +set(OPENMW_LUA_API_REVISION 96) set(OPENMW_POSTPROCESSING_API_REVISION 3) set(OPENMW_VERSION_COMMITHASH "") diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 0b760ccdf0..5236cd538a 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -316,6 +316,8 @@ namespace MWLua void LuaManager::applyDelayedActions() { + if (mApplyingDelayedActions) + return; mApplyingDelayedActions = true; for (DelayedAction& action : mActionQueue) action.apply(); @@ -324,6 +326,9 @@ namespace MWLua if (mTeleportPlayerAction) mTeleportPlayerAction->apply(); mTeleportPlayerAction.reset(); + for (DelayedAction& action : mSaveActionQueue) + action.apply(); + mSaveActionQueue.clear(); mApplyingDelayedActions = false; } @@ -824,6 +829,11 @@ namespace MWLua mTeleportPlayerAction = DelayedAction(&mLua, std::move(action), "TeleportPlayer"); } + void LuaManager::addSaveGameAction(std::function action) + { + mSaveActionQueue.emplace_back(&mLua, std::move(action), "SaveGame"); + } + void LuaManager::reportStats(unsigned int frameNumber, osg::Stats& stats) const { stats.setAttribute(frameNumber, "Lua UsedMemory", mLua.getTotalMemoryUsage()); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 42b18d236f..9386ce0499 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -125,8 +125,9 @@ namespace MWLua // Some changes to the game world can not be done from the scripting thread (because it runs in parallel with // OSG Cull), so we need to queue it and apply from the main thread. - void addAction(std::function action, std::string_view name = ""); + void addAction(std::function action, std::string_view name = {}); void addTeleportPlayerAction(std::function action); + void addSaveGameAction(std::function action); // Saving void write(ESM::ESMWriter& writer, Loading::Listener& progress) override; @@ -234,6 +235,7 @@ namespace MWLua }; std::vector mActionQueue; std::optional mTeleportPlayerAction; + std::vector mSaveActionQueue; std::vector> mUIMessages; std::vector> mInGameConsoleMessages; std::optional mDelayedUiModeChangedArg; diff --git a/apps/openmw/mwlua/menuscripts.cpp b/apps/openmw/mwlua/menuscripts.cpp index 6387a3dce1..81f20af955 100644 --- a/apps/openmw/mwlua/menuscripts.cpp +++ b/apps/openmw/mwlua/menuscripts.cpp @@ -8,6 +8,7 @@ #include "../mwstate/character.hpp" #include "context.hpp" +#include "luamanagerimp.hpp" namespace MWLua { @@ -72,13 +73,16 @@ namespace MWLua return sol::nullopt; }; - api["saveGame"] = [](std::string_view description, sol::optional slotName) { - MWBase::StateManager* manager = MWBase::Environment::get().getStateManager(); - const MWState::Character* character = manager->getCurrentCharacter(); - const MWState::Slot* slot = nullptr; - if (slotName) - slot = findSlot(character, *slotName); - manager->saveGame(description, slot); + api["saveGame"] = [context](std::string description, sol::optional slotName) { + context.mLuaManager->addSaveGameAction( + [description = std::move(description), slotName = std::move(slotName)]() { + MWBase::StateManager* manager = MWBase::Environment::get().getStateManager(); + const MWState::Character* character = manager->getCurrentCharacter(); + const MWState::Slot* slot = nullptr; + if (slotName) + slot = findSlot(character, *slotName); + manager->saveGame(description, slot); + }); }; auto getSaves = [](sol::state_view currentState, const MWState::Character& character) {