From bbc6bf5294f829d62ef61244c315c2886c54c790 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sun, 3 Mar 2019 10:58:37 -0600 Subject: [PATCH] Common/Config: Add a utility class to suppress config change callbacks. --- Source/Core/Common/Config/Config.cpp | 18 ++++++++++++++++++ Source/Core/Common/Config/Config.h | 13 ++++++++++++- Source/Core/Common/Logging/LogManager.cpp | 2 ++ .../Core/DolphinQt/NetPlay/NetPlayDialog.cpp | 2 ++ .../DolphinQt/NetPlay/NetPlaySetupDialog.cpp | 2 ++ .../Core/DolphinQt/Settings/GameCubePane.cpp | 2 ++ Source/Core/DolphinQt/Settings/GeneralPane.cpp | 2 ++ Source/Core/DolphinQt/Settings/WiiPane.cpp | 2 ++ 8 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Source/Core/Common/Config/Config.cpp b/Source/Core/Common/Config/Config.cpp index 30215aec06..122d2d6ff1 100644 --- a/Source/Core/Common/Config/Config.cpp +++ b/Source/Core/Common/Config/Config.cpp @@ -12,6 +12,7 @@ namespace Config { static Layers s_layers; static std::list s_callbacks; +static u32 s_callback_guards = 0; Layers* GetLayers() { @@ -53,6 +54,9 @@ void AddConfigChangedCallback(ConfigChangedCallback func) void InvokeConfigChangedCallbacks() { + if (s_callback_guards) + return; + for (const auto& callback : s_callbacks) callback(); } @@ -137,4 +141,18 @@ LayerType GetActiveLayerForConfig(const ConfigLocation& config) // If config is not present in any layer, base layer is considered active. return LayerType::Base; } + +ConfigChangeCallbackGuard::ConfigChangeCallbackGuard() +{ + ++s_callback_guards; } + +ConfigChangeCallbackGuard::~ConfigChangeCallbackGuard() +{ + if (--s_callback_guards) + return; + + InvokeConfigChangedCallbacks(); +} + +} // namespace Config diff --git a/Source/Core/Common/Config/Config.h b/Source/Core/Common/Config/Config.h index 1418a86606..4120d029ba 100644 --- a/Source/Core/Common/Config/Config.h +++ b/Source/Core/Common/Config/Config.h @@ -96,4 +96,15 @@ void SetBaseOrCurrent(const ConfigInfo& info, const std::common_type_t& va else Set(LayerType::CurrentRun, info, value); } -} + +// Used to defer InvokeConfigChangedCallbacks until after the completion of many config changes. +class ConfigChangeCallbackGuard +{ +public: + ConfigChangeCallbackGuard(); + ~ConfigChangeCallbackGuard(); + + ConfigChangeCallbackGuard(const ConfigChangeCallbackGuard&) = delete; + ConfigChangeCallbackGuard& operator=(const ConfigChangeCallbackGuard&) = delete; +}; +} // namespace Config diff --git a/Source/Core/Common/Logging/LogManager.cpp b/Source/Core/Common/Logging/LogManager.cpp index cd108b0f46..6efb4a39d0 100644 --- a/Source/Core/Common/Logging/LogManager.cpp +++ b/Source/Core/Common/Logging/LogManager.cpp @@ -173,6 +173,8 @@ LogManager::~LogManager() void LogManager::SaveSettings() { + Config::ConfigChangeCallbackGuard config_guard; + Config::SetBaseOrCurrent(LOGGER_WRITE_TO_FILE, IsListenerEnabled(LogListener::FILE_LISTENER)); Config::SetBaseOrCurrent(LOGGER_WRITE_TO_CONSOLE, IsListenerEnabled(LogListener::CONSOLE_LISTENER)); diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp index 9cb27331e7..9353e1a843 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp @@ -1008,6 +1008,8 @@ std::shared_ptr NetPlayDialog::FindGameFile(const std: void NetPlayDialog::SaveSettings() { + Config::ConfigChangeCallbackGuard config_guard; + if (m_host_input_authority) { if (!IsHosting()) diff --git a/Source/Core/DolphinQt/NetPlay/NetPlaySetupDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlaySetupDialog.cpp index 0da0bc6194..e6b34cbe5c 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlaySetupDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlaySetupDialog.cpp @@ -203,6 +203,8 @@ void NetPlaySetupDialog::ConnectWidgets() void NetPlaySetupDialog::SaveSettings() { + Config::ConfigChangeCallbackGuard config_guard; + Config::SetBaseOrCurrent(Config::NETPLAY_NICKNAME, m_nickname_edit->text().toStdString()); Config::SetBaseOrCurrent(m_connection_type->currentIndex() == 0 ? Config::NETPLAY_ADDRESS : Config::NETPLAY_HOST_CODE, diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index 69beebf9db..3c9f1657bb 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -332,6 +332,8 @@ void GameCubePane::LoadSettings() void GameCubePane::SaveSettings() { + Config::ConfigChangeCallbackGuard config_guard; + SConfig& params = SConfig::GetInstance(); // IPL Settings diff --git a/Source/Core/DolphinQt/Settings/GeneralPane.cpp b/Source/Core/DolphinQt/Settings/GeneralPane.cpp index 78ec034fb3..b1ee785cb7 100644 --- a/Source/Core/DolphinQt/Settings/GeneralPane.cpp +++ b/Source/Core/DolphinQt/Settings/GeneralPane.cpp @@ -282,6 +282,8 @@ static QString UpdateTrackFromIndex(int index) void GeneralPane::OnSaveConfig() { + Config::ConfigChangeCallbackGuard config_guard; + auto& settings = SConfig::GetInstance(); if (AutoUpdateChecker::SystemSupportsAutoUpdates()) { diff --git a/Source/Core/DolphinQt/Settings/WiiPane.cpp b/Source/Core/DolphinQt/Settings/WiiPane.cpp index 6d2eced4cb..661b915118 100644 --- a/Source/Core/DolphinQt/Settings/WiiPane.cpp +++ b/Source/Core/DolphinQt/Settings/WiiPane.cpp @@ -221,6 +221,8 @@ void WiiPane::LoadConfig() void WiiPane::OnSaveConfig() { + Config::ConfigChangeCallbackGuard config_guard; + Config::SetBase(Config::SYSCONF_SCREENSAVER, m_screensaver_checkbox->isChecked()); Config::SetBase(Config::SYSCONF_PAL60, m_pal60_mode_checkbox->isChecked()); Settings::Instance().SetUSBKeyboardConnected(m_connect_keyboard_checkbox->isChecked());