From 3a98b945a881ca6fac57e16493581986b7c61c7d Mon Sep 17 00:00:00 2001 From: uramer Date: Sun, 23 Feb 2025 19:10:21 +0100 Subject: [PATCH] Keep MENU-registered input actions between games --- .../lua/test_inputactions.cpp | 4 +- apps/openmw/mwlua/inputbindings.cpp | 40 ++++++++++-------- apps/openmw/mwlua/luamanagerimp.cpp | 4 +- components/lua/inputactions.cpp | 42 +++++++++++++++++++ components/lua/inputactions.hpp | 20 ++------- 5 files changed, 72 insertions(+), 38 deletions(-) diff --git a/apps/components_tests/lua/test_inputactions.cpp b/apps/components_tests/lua/test_inputactions.cpp index cad17a5b99..b2a84f193c 100644 --- a/apps/components_tests/lua/test_inputactions.cpp +++ b/apps/components_tests/lua/test_inputactions.cpp @@ -38,10 +38,10 @@ namespace sol::state lua; LuaUtil::InputAction::Registry registry; LuaUtil::InputAction::Info a({ "a", LuaUtil::InputAction::Type::Boolean, "test", "a_name", "a_description", - sol::make_object(lua, false) }); + sol::make_object(lua, false), false }); registry.insert(a); LuaUtil::InputAction::Info b({ "b", LuaUtil::InputAction::Type::Boolean, "test", "b_name", "b_description", - sol::make_object(lua, false) }); + sol::make_object(lua, false), false }); registry.insert(b); LuaUtil::Callback bindA({ lua.load("return function() return true end")(), sol::table(lua, sol::create) }); LuaUtil::Callback bindBToA( diff --git a/apps/openmw/mwlua/inputbindings.cpp b/apps/openmw/mwlua/inputbindings.cpp index b9affcdfca..27c6714bb4 100644 --- a/apps/openmw/mwlua/inputbindings.cpp +++ b/apps/openmw/mwlua/inputbindings.cpp @@ -139,16 +139,18 @@ namespace MWLua })); api["actions"] = std::ref(context.mLuaManager->inputActions()); - api["registerAction"] = [manager = context.mLuaManager](sol::table options) { - LuaUtil::InputAction::Info parsedOptions; - parsedOptions.mKey = options["key"].get(); - parsedOptions.mType = options["type"].get(); - parsedOptions.mL10n = options["l10n"].get(); - parsedOptions.mName = options["name"].get(); - parsedOptions.mDescription = options["description"].get(); - parsedOptions.mDefaultValue = options["defaultValue"].get(); - manager->inputActions().insert(std::move(parsedOptions)); - }; + api["registerAction"] + = [manager = context.mLuaManager, persistent = context.mType == Context::Menu](sol::table options) { + LuaUtil::InputAction::Info parsedOptions; + parsedOptions.mKey = options["key"].get(); + parsedOptions.mType = options["type"].get(); + parsedOptions.mL10n = options["l10n"].get(); + parsedOptions.mName = options["name"].get(); + parsedOptions.mDescription = options["description"].get(); + parsedOptions.mDefaultValue = options["defaultValue"].get(); + parsedOptions.mPersistent = persistent; + manager->inputActions().insert(std::move(parsedOptions)); + }; api["bindAction"] = [manager = context.mLuaManager]( std::string_view key, const sol::table& callback, sol::table dependencies) { std::vector parsedDependencies; @@ -178,14 +180,16 @@ namespace MWLua }; api["triggers"] = std::ref(context.mLuaManager->inputTriggers()); - api["registerTrigger"] = [manager = context.mLuaManager](sol::table options) { - LuaUtil::InputTrigger::Info parsedOptions; - parsedOptions.mKey = options["key"].get(); - parsedOptions.mL10n = options["l10n"].get(); - parsedOptions.mName = options["name"].get(); - parsedOptions.mDescription = options["description"].get(); - manager->inputTriggers().insert(std::move(parsedOptions)); - }; + api["registerTrigger"] + = [manager = context.mLuaManager, persistent = context.mType == Context::Menu](sol::table options) { + LuaUtil::InputTrigger::Info parsedOptions; + parsedOptions.mKey = options["key"].get(); + parsedOptions.mL10n = options["l10n"].get(); + parsedOptions.mName = options["name"].get(); + parsedOptions.mDescription = options["description"].get(); + parsedOptions.mPersistent = persistent; + manager->inputTriggers().insert(std::move(parsedOptions)); + }; api["registerTriggerHandler"] = [manager = context.mLuaManager](std::string_view key, const sol::table& callback) { manager->inputTriggers().registerHandler(key, LuaUtil::Callback::fromLua(callback)); diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index aa33abda39..5fa2d9867c 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -654,8 +654,8 @@ namespace MWLua MWBase::Environment::get().getL10nManager()->dropCache(); mUiResourceManager.clear(); mLua.dropScriptCache(); - mInputActions.clear(); - mInputTriggers.clear(); + mInputActions.clear(true); + mInputTriggers.clear(true); initConfiguration(); ESM::LuaScripts globalData; diff --git a/components/lua/inputactions.cpp b/components/lua/inputactions.cpp index 7c7551ba60..b0c7fe2e9f 100644 --- a/components/lua/inputactions.cpp +++ b/components/lua/inputactions.cpp @@ -239,6 +239,29 @@ namespace LuaUtil } }); } + + void Registry::clear(bool force) + { + std::vector infoToKeep; + if (!force) + { + for (const Info& info : mInfo) + if (info.mPersistent) + infoToKeep.push_back(info); + } + mKeys.clear(); + mIds.clear(); + mInfo.clear(); + mHandlers.clear(); + mBindings.clear(); + mValues.clear(); + mBindingTree.clear(); + if (!force) + { + for (const Info& i : infoToKeep) + insert(i); + } + } } namespace InputTrigger @@ -292,5 +315,24 @@ namespace LuaUtil }), handlers.end()); } + + void Registry::clear(bool force) + { + std::vector infoToKeep; + if (!force) + { + for (const Info& info : mInfo) + if (info.mPersistent) + infoToKeep.push_back(info); + } + mInfo.clear(); + mHandlers.clear(); + mIds.clear(); + if (!force) + { + for (const Info& i : infoToKeep) + insert(i); + } + } } } diff --git a/components/lua/inputactions.hpp b/components/lua/inputactions.hpp index d05bb71f2c..83de556f9f 100644 --- a/components/lua/inputactions.hpp +++ b/components/lua/inputactions.hpp @@ -29,6 +29,7 @@ namespace LuaUtil::InputAction std::string mName; std::string mDescription; sol::main_object mDefaultValue; + bool mPersistent; }; class MultiTree @@ -73,16 +74,7 @@ namespace LuaUtil::InputAction { mHandlers[safeIdByKey(key)].push_back(handler); } - void clear() - { - mKeys.clear(); - mIds.clear(); - mInfo.clear(); - mHandlers.clear(); - mBindings.clear(); - mValues.clear(); - mBindingTree.clear(); - } + void clear(bool force = false); private: using Id = MultiTree::Node; @@ -110,6 +102,7 @@ namespace LuaUtil::InputTrigger std::string mL10n; std::string mName; std::string mDescription; + bool mPersistent; }; class Registry @@ -130,12 +123,7 @@ namespace LuaUtil::InputTrigger void insert(const Info& info); void registerHandler(std::string_view key, const LuaUtil::Callback& callback); void activate(std::string_view key); - void clear() - { - mInfo.clear(); - mHandlers.clear(); - mIds.clear(); - } + void clear(bool force = false); private: using Id = size_t;