diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 8f1abceafc..e7f7fa9dde 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include "../mwbase/windowmanager.hpp" @@ -62,6 +63,11 @@ namespace MWLua mGlobalScripts.setSerializer(mGlobalSerializer.get()); } + LuaManager::~LuaManager() + { + LuaUi::clearSettings(); + } + void LuaManager::initConfiguration() { mConfiguration.init(MWBase::Environment::get().getESMStore()->getLuaScriptsCfg()); @@ -551,6 +557,7 @@ namespace MWLua LuaUi::clearGameInterface(); LuaUi::clearMenuInterface(); + LuaUi::clearSettings(); MWBase::Environment::get().getWindowManager()->setConsoleMode(""); MWBase::Environment::get().getL10nManager()->dropCache(); mUiResourceManager.clear(); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 965aa67fab..56a30f24e0 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -35,6 +35,7 @@ namespace MWLua LuaManager(const VFS::Manager* vfs, const std::filesystem::path& libsDir); LuaManager(const LuaManager&) = delete; LuaManager(LuaManager&&) = delete; + ~LuaManager(); // Called by engine.cpp when the environment is fully initialized. void init(); diff --git a/apps/openmw/mwlua/uibindings.cpp b/apps/openmw/mwlua/uibindings.cpp index 54d8523b4d..061dc4821a 100644 --- a/apps/openmw/mwlua/uibindings.cpp +++ b/apps/openmw/mwlua/uibindings.cpp @@ -247,6 +247,7 @@ namespace MWLua { "Center", LuaUi::Alignment::Center }, { "End", LuaUi::Alignment::End } })); api["registerSettingsPage"] = &LuaUi::registerSettingsPage; + api["removeSettingsPage"] = &LuaUi::registerSettingsPage; api["texture"] = [luaManager = context.mLuaManager](const sol::table& options) { LuaUi::TextureData data; diff --git a/components/lua_ui/registerscriptsettings.hpp b/components/lua_ui/registerscriptsettings.hpp index fb794468da..ba36aff904 100644 --- a/components/lua_ui/registerscriptsettings.hpp +++ b/components/lua_ui/registerscriptsettings.hpp @@ -8,6 +8,7 @@ namespace LuaUi // implemented in scriptsettings.cpp void registerSettingsPage(const sol::table& options); void clearSettings(); + void removeSettingsPage(std::string_view key); } #endif // !OPENMW_LUAUI_REGISTERSCRIPTSETTINGS diff --git a/components/lua_ui/scriptsettings.cpp b/components/lua_ui/scriptsettings.cpp index e92d1d8958..514e6ce632 100644 --- a/components/lua_ui/scriptsettings.cpp +++ b/components/lua_ui/scriptsettings.cpp @@ -40,6 +40,11 @@ namespace LuaUi allPages.push_back(options); } + void removeSettingsPage(const sol::table& options) + { + std::erase_if(allPages, [options](const sol::table& it) { return it == options; }); + } + void clearSettings() { allPages.clear(); @@ -47,10 +52,10 @@ namespace LuaUi void attachPageAt(size_t index, LuaAdapter* adapter) { + adapter->detach(); if (index < allPages.size()) { ScriptSettingsPage page = parse(allPages[index]); - adapter->detach(); if (page.mElement.get()) adapter->attach(page.mElement); } diff --git a/components/lua_ui/util.cpp b/components/lua_ui/util.cpp index ac5e63e405..fe47de3b1d 100644 --- a/components/lua_ui/util.cpp +++ b/components/lua_ui/util.cpp @@ -46,8 +46,6 @@ namespace LuaUi void clearGameInterface() { - // TODO: move settings clearing logic to Lua? - clearSettings(); while (!Element::sGameElements.empty()) Element::sGameElements.begin()->second->destroy(); } diff --git a/files/data/scripts/omw/settings/menu.lua b/files/data/scripts/omw/settings/menu.lua index 61fce3015e..d20d75bf30 100644 --- a/files/data/scripts/omw/settings/menu.lua +++ b/files/data/scripts/omw/settings/menu.lua @@ -423,17 +423,27 @@ local function updateGlobalGroups() end local menuGroups = {} +local menuPages = {} -local function resetGroups() +local function reset() for pageKey, page in pairs(groups) do for groupKey in pairs(page) do if not menuGroups[groupKey] then page[groupKey] = nil end end - local renderedOptions = renderPage(pages[pageKey]) - for k, v in pairs(renderedOptions) do - pageOptions[pageKey][k] = v + if pageOptions[pageKey] then + pageOptions[pageKey].element.destroy() + if not menuPages[pageKey] then + pageOptions[pageKey].element.destroy() + ui.removeSettingsPage(pageOptions[pageKey]) + pageOptions[pageKey] = nil + else + local renderedOptions = renderPage(pages[pageKey]) + for k, v in pairs(renderedOptions) do + pageOptions[pageKey][k] = v + end + end end end end @@ -477,7 +487,10 @@ return { interfaceName = 'Settings', interface = { version = 1, - registerPage = registerPage, + registerPage = function(options) + registerPage(options) + menuPages[options] = true + end, registerRenderer = registerRenderer, registerGroup = function(options) common.registerGroup(options) @@ -492,7 +505,7 @@ return { if menu.getState() == menu.STATE.Running then updateGlobalGroups() else - resetGroups() + reset() end updatePlayerGroups() end, diff --git a/files/lua_api/openmw/ui.lua b/files/lua_api/openmw/ui.lua index 8582996c4f..a99b1e782e 100644 --- a/files/lua_api/openmw/ui.lua +++ b/files/lua_api/openmw/ui.lua @@ -93,6 +93,11 @@ -- @function [parent=#ui] registerSettingsPage -- @param #SettingsPageOptions page +--- +-- Removes the settings page +-- @function [parent=#ui] removeSettingsPage +-- @param #SettingsPageOptions page must be the exact same table of options as the one passed to registerSettingsPage + --- -- Table with settings page options, passed as an argument to ui.registerSettingsPage -- @type SettingsPageOptions