diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 5236cd538a..fde7a63dbb 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -42,6 +42,20 @@ namespace MWLua { + namespace + { + struct AllowSaving + { + bool& mAllowSaving; + AllowSaving(bool& allowSaving) + : mAllowSaving(allowSaving) + { + mAllowSaving = true; + } + + ~AllowSaving() { mAllowSaving = false; } + }; + } static LuaUtil::LuaStateSettings createLuaStateSettings() { @@ -264,6 +278,7 @@ namespace MWLua // can teleport the player to the starting location before the first frame is rendered. mGlobalScripts.newGameStarted(); } + AllowSaving savingGuard(mAllowSaving); // We apply input events in `synchronizedUpdate` rather than in `update` in order to reduce input latency. mProcessingInputEvents = true; @@ -316,8 +331,6 @@ namespace MWLua void LuaManager::applyDelayedActions() { - if (mApplyingDelayedActions) - return; mApplyingDelayedActions = true; for (DelayedAction& action : mActionQueue) action.apply(); @@ -326,9 +339,6 @@ namespace MWLua if (mTeleportPlayerAction) mTeleportPlayerAction->apply(); mTeleportPlayerAction.reset(); - for (DelayedAction& action : mSaveActionQueue) - action.apply(); - mSaveActionQueue.clear(); mApplyingDelayedActions = false; } @@ -829,11 +839,6 @@ 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 9386ce0499..62d0de8f06 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -127,7 +127,6 @@ namespace MWLua // OSG Cull), so we need to queue it and apply from the main thread. 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; @@ -175,6 +174,8 @@ namespace MWLua void sendLocalEvent( const MWWorld::Ptr& target, const std::string& name, const std::optional& data = std::nullopt); + bool savingAllowed() const { return mAllowSaving; } + private: void initConfiguration(); LocalScripts* createLocalScripts(const MWWorld::Ptr& ptr, @@ -188,6 +189,7 @@ namespace MWLua bool mApplyingDelayedActions = false; bool mNewGameStarted = false; bool mReloadAllScriptsRequested = false; + bool mAllowSaving = false; LuaUtil::ScriptsConfiguration mConfiguration; LuaUtil::LuaState mLua; LuaUi::ResourceManager mUiResourceManager; @@ -235,7 +237,6 @@ 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 81f20af955..528e742c17 100644 --- a/apps/openmw/mwlua/menuscripts.cpp +++ b/apps/openmw/mwlua/menuscripts.cpp @@ -73,16 +73,15 @@ namespace MWLua return sol::nullopt; }; - 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); - }); + api["saveGame"] = [context](std::string_view description, sol::optional slotName) { + if (!context.mLuaManager->savingAllowed()) + throw std::runtime_error("The game cannot be saved at the moment"); + 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) { diff --git a/components/lua/scriptscontainer.cpp b/components/lua/scriptscontainer.cpp index f5b5605e37..36bdbca8b1 100644 --- a/components/lua/scriptscontainer.cpp +++ b/components/lua/scriptscontainer.cpp @@ -47,7 +47,7 @@ namespace LuaUtil } } - void ScriptsContainer::printError(int scriptId, std::string_view msg, const std::exception& e) + void ScriptsContainer::printError(int scriptId, std::string_view msg, const std::exception& e) const { Log(Debug::Error) << mNamePrefix << "[" << scriptPath(scriptId) << "] " << msg << ": " << e.what(); } @@ -408,7 +408,7 @@ namespace LuaUtil void ScriptsContainer::save(ESM::LuaScripts& data) { - if (UnloadedData* unloadedData = std::get_if(&mData)) + if (const UnloadedData* unloadedData = std::get_if(&mData)) { data.mScripts = unloadedData->mScripts; return; diff --git a/components/lua/scriptscontainer.hpp b/components/lua/scriptscontainer.hpp index 8eaaf2955f..275c300ac9 100644 --- a/components/lua/scriptscontainer.hpp +++ b/components/lua/scriptscontainer.hpp @@ -271,7 +271,7 @@ namespace LuaUtil // Returns script by id (throws an exception if doesn't exist) Script& getScript(int scriptId); - void printError(int scriptId, std::string_view msg, const std::exception& e); + void printError(int scriptId, std::string_view msg, const std::exception& e) const; const VFS::Path::Normalized& scriptPath(int scriptId) const {