From c8f970e2b04709280ef144ff135dac15945d21b2 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 29 Oct 2017 19:17:58 +0000 Subject: [PATCH 1/6] Config: Remove recursive layer --- Source/Core/Common/Config/Config.cpp | 8 ---- Source/Core/Common/Config/Config.h | 7 ++- Source/Core/Common/Config/Enums.h | 1 - Source/Core/Common/Config/Layer.cpp | 32 +------------ Source/Core/Common/Config/Layer.h | 10 +--- Source/Core/Common/Config/Section.cpp | 47 ------------------- Source/Core/Common/Config/Section.h | 14 ------ Source/Core/Core/BootManager.cpp | 2 +- .../Core/ConfigLoaders/BaseConfigLoader.cpp | 8 ++-- .../Core/ConfigLoaders/BaseConfigLoader.h | 4 +- .../Core/ConfigLoaders/MovieConfigLoader.cpp | 32 ++++++------- .../Core/ConfigLoaders/MovieConfigLoader.h | 2 +- Source/Core/Core/Movie.cpp | 2 +- 13 files changed, 30 insertions(+), 139 deletions(-) diff --git a/Source/Core/Common/Config/Config.cpp b/Source/Core/Common/Config/Config.cpp index 339155dbe3..eb763c3632 100644 --- a/Source/Core/Common/Config/Config.cpp +++ b/Source/Core/Common/Config/Config.cpp @@ -17,11 +17,6 @@ static std::list s_callbacks; void InvokeConfigChangedCallbacks(); -Section* GetOrCreateSection(System system, const std::string& section_name) -{ - return s_layers[LayerType::Meta]->GetOrCreateSection(system, section_name); -} - Layers* GetLayers() { return &s_layers; @@ -83,8 +78,6 @@ void Init() { // These layers contain temporary values ClearCurrentRunLayer(); - // This layer always has to exist - s_layers[LayerType::Meta] = std::make_unique(); } void Shutdown() @@ -129,7 +122,6 @@ const std::string& GetLayerName(LayerType layer) {LayerType::Movie, "Movie"}, {LayerType::CommandLine, "Command Line"}, {LayerType::CurrentRun, "Current Run"}, - {LayerType::Meta, "Top"}, }; return layer_to_name.at(layer); } diff --git a/Source/Core/Common/Config/Config.h b/Source/Core/Common/Config/Config.h index 905960ed4a..454fa3585e 100644 --- a/Source/Core/Common/Config/Config.h +++ b/Source/Core/Common/Config/Config.h @@ -36,9 +36,6 @@ struct ConfigInfo using Layers = std::map>; using ConfigChangedCallback = std::function; -// Common function used for getting configuration -Section* GetOrCreateSection(System system, const std::string& section_name); - // Layer management Layers* GetLayers(); void AddLayer(std::unique_ptr layer); @@ -66,13 +63,15 @@ LayerType GetActiveLayerForConfig(const ConfigLocation&); template T Get(LayerType layer, const ConfigInfo& info) { + if (layer == LayerType::Meta) + return Get(info); return GetLayer(layer)->Get(info); } template T Get(const ConfigInfo& info) { - return Get(LayerType::Meta, info); + return GetLayer(GetActiveLayerForConfig(info.location))->Get(info); } template diff --git a/Source/Core/Common/Config/Enums.h b/Source/Core/Common/Config/Enums.h index 9ffd9688c2..a5b62f812d 100644 --- a/Source/Core/Common/Config/Enums.h +++ b/Source/Core/Common/Config/Enums.h @@ -34,7 +34,6 @@ enum class System }; constexpr std::array SEARCH_ORDER{{ - // Skip the meta layer LayerType::CurrentRun, LayerType::CommandLine, LayerType::Movie, LayerType::Netplay, LayerType::LocalGame, LayerType::GlobalGame, LayerType::Base, }}; diff --git a/Source/Core/Common/Config/Layer.cpp b/Source/Core/Common/Config/Layer.cpp index b613c4366b..a3912281f5 100644 --- a/Source/Core/Common/Config/Layer.cpp +++ b/Source/Core/Common/Config/Layer.cpp @@ -67,15 +67,7 @@ Section* Layer::GetOrCreateSection(System system, const std::string& section_nam Section* section = GetSection(system, section_name); if (!section) { - if (m_layer == LayerType::Meta) - { - m_sections[system].emplace_back( - std::make_unique(m_layer, system, section_name)); - } - else - { - m_sections[system].emplace_back(std::make_unique
(m_layer, system, section_name)); - } + m_sections[system].emplace_back(std::make_unique
(m_layer, system, section_name)); section = m_sections[system].back().get(); } return section; @@ -124,26 +116,4 @@ void Layer::ClearDirty() [](auto& section) { section->ClearDirty(); }); }); } - -RecursiveLayer::RecursiveLayer() : Layer(LayerType::Meta) -{ -} - -Section* RecursiveLayer::GetSection(System system, const std::string& section_name) -{ - // Always queries backwards recursively, so it doesn't matter if it exists or not on this layer - return GetOrCreateSection(system, section_name); -} - -Section* RecursiveLayer::GetOrCreateSection(System system, const std::string& section_name) -{ - Section* section = Layer::GetSection(system, section_name); - if (!section) - { - m_sections[system].emplace_back( - std::make_unique(m_layer, system, section_name)); - section = m_sections[system].back().get(); - } - return section; -} } diff --git a/Source/Core/Common/Config/Layer.h b/Source/Core/Common/Config/Layer.h index edbb706081..ac5b5c3e78 100644 --- a/Source/Core/Common/Config/Layer.h +++ b/Source/Core/Common/Config/Layer.h @@ -84,12 +84,4 @@ protected: const LayerType m_layer; std::unique_ptr m_loader; }; - -class RecursiveLayer final : public Layer -{ -public: - RecursiveLayer(); - Section* GetSection(System system, const std::string& section_name) override; - Section* GetOrCreateSection(System system, const std::string& section_name) override; -}; -} +} // namespace Config diff --git a/Source/Core/Common/Config/Section.cpp b/Source/Core/Common/Config/Section.cpp index bb9fcef0e3..12adff2b1f 100644 --- a/Source/Core/Common/Config/Section.cpp +++ b/Source/Core/Common/Config/Section.cpp @@ -246,51 +246,4 @@ void Section::ClearDirty() { m_dirty = false; } - -RecursiveSection::RecursiveSection(LayerType layer, System system, const std::string& name) - : Section(layer, system, name) -{ -} - -bool RecursiveSection::Exists(const std::string& key) const -{ - auto layers_it = Config::GetLayers()->find(LayerType::Meta); - do - { - const Section* layer_section = layers_it->second->GetSection(m_system, m_name); - if (layer_section && layer_section->Exists(key)) - { - return true; - } - } while (--layers_it != Config::GetLayers()->end()); - - return false; -} - -bool RecursiveSection::Get(const std::string& key, std::string* value, - const std::string& default_value) const -{ - for (auto layer_id : SEARCH_ORDER) - { - auto layers_it = Config::GetLayers()->find(layer_id); - if (layers_it == Config::GetLayers()->end()) - continue; - - const Section* layer_section = layers_it->second->GetSection(m_system, m_name); - if (layer_section && layer_section->Exists(key)) - { - return layer_section->Get(key, value, default_value); - } - } - - return Section::Get(key, value, default_value); -} - -void RecursiveSection::Set(const std::string& key, const std::string& value) -{ - // The RecursiveSection can't set since it is used to recursively get values from the layer - // map. - // It is only a part of the meta layer, and the meta layer isn't allowed to set any values. - _assert_msg_(COMMON, false, "Don't try to set values here!"); -} } diff --git a/Source/Core/Common/Config/Section.h b/Source/Core/Common/Config/Section.h index 948ebd67d4..592b791722 100644 --- a/Source/Core/Common/Config/Section.h +++ b/Source/Core/Common/Config/Section.h @@ -96,18 +96,4 @@ protected: std::vector m_lines; }; - -// Only to be used with the meta-layer -class RecursiveSection final : public Section -{ -public: - RecursiveSection(LayerType layer, System system, const std::string& name); - - bool Exists(const std::string& key) const override; - - bool Get(const std::string& key, std::string* value, - const std::string& default_value = NULL_STRING) const override; - - void Set(const std::string& key, const std::string& value) override; -}; } diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 79771acdc3..e7d2cc91eb 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -376,7 +376,7 @@ bool BootCore(std::unique_ptr boot) // Ensure any new settings are written to the SYSCONF if (StartUp.bWii) - ConfigLoaders::SaveToSYSCONF(Config::GetLayer(Config::LayerType::Meta)); + ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta); const bool load_ipl = !StartUp.bWii && !StartUp.bHLE_BS2 && std::holds_alternative(boot->parameters); diff --git a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp index 8969748a69..848501ba73 100644 --- a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp @@ -26,7 +26,7 @@ namespace ConfigLoaders { -void SaveToSYSCONF(Config::Layer* layer) +void SaveToSYSCONF(Config::LayerType layer) { if (Core::IsRunning()) return; @@ -40,9 +40,9 @@ void SaveToSYSCONF(Config::Layer* layer) const std::string key = info.location.section + "." + info.location.key; if (setting.type == SysConf::Entry::Type::Long) - sysconf.SetData(key, setting.type, layer->Get(info)); + sysconf.SetData(key, setting.type, Config::Get(layer, info)); else if (setting.type == SysConf::Entry::Type::Byte) - sysconf.SetData(key, setting.type, static_cast(layer->Get(info))); + sysconf.SetData(key, setting.type, static_cast(Config::Get(layer, info))); }, setting.config_info); } @@ -106,7 +106,7 @@ public: { if (system.first == Config::System::SYSCONF) { - SaveToSYSCONF(config_layer); + SaveToSYSCONF(config_layer->GetLayer()); continue; } diff --git a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.h b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.h index 2ae00c6aff..4f34197c7c 100644 --- a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.h +++ b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.h @@ -9,11 +9,11 @@ namespace Config { class ConfigLayerLoader; -class Layer; +enum class LayerType; } namespace ConfigLoaders { -void SaveToSYSCONF(Config::Layer* layer); +void SaveToSYSCONF(Config::LayerType layer); std::unique_ptr GenerateBaseConfigLoader(); } diff --git a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp index 9479045e00..edfea3919e 100644 --- a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp @@ -46,27 +46,27 @@ static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm) config_layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, dtm->bEFBEmulateFormatChanges); } -void SaveToDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm) +void SaveToDTM(Movie::DTMHeader* dtm) { - dtm->bDualCore = config_layer->Get(Config::MAIN_CPU_THREAD); - dtm->bDSPHLE = config_layer->Get(Config::MAIN_DSP_HLE); - dtm->bFastDiscSpeed = config_layer->Get(Config::MAIN_FAST_DISC_SPEED); - dtm->CPUCore = config_layer->Get(Config::MAIN_CPU_CORE); - dtm->bSyncGPU = config_layer->Get(Config::MAIN_SYNC_GPU); - const std::string video_backend = config_layer->Get(Config::MAIN_GFX_BACKEND); + dtm->bDualCore = Config::Get(Config::MAIN_CPU_THREAD); + dtm->bDSPHLE = Config::Get(Config::MAIN_DSP_HLE); + dtm->bFastDiscSpeed = Config::Get(Config::MAIN_FAST_DISC_SPEED); + dtm->CPUCore = Config::Get(Config::MAIN_CPU_CORE); + dtm->bSyncGPU = Config::Get(Config::MAIN_SYNC_GPU); + const std::string video_backend = Config::Get(Config::MAIN_GFX_BACKEND); - dtm->bProgressive = config_layer->Get(Config::SYSCONF_PROGRESSIVE_SCAN); - dtm->bPAL60 = config_layer->Get(Config::SYSCONF_PAL60); + dtm->bProgressive = Config::Get(Config::SYSCONF_PROGRESSIVE_SCAN); + dtm->bPAL60 = Config::Get(Config::SYSCONF_PAL60); if (dtm->bWii) - dtm->language = config_layer->Get(Config::SYSCONF_LANGUAGE); + dtm->language = Config::Get(Config::SYSCONF_LANGUAGE); else - dtm->language = config_layer->Get(Config::MAIN_GC_LANGUAGE); + dtm->language = Config::Get(Config::MAIN_GC_LANGUAGE); - dtm->bUseXFB = config_layer->Get(Config::GFX_USE_XFB); - dtm->bUseRealXFB = config_layer->Get(Config::GFX_USE_REAL_XFB); - dtm->bEFBAccessEnable = config_layer->Get(Config::GFX_HACK_EFB_ACCESS_ENABLE); - dtm->bSkipEFBCopyToRam = config_layer->Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); - dtm->bEFBEmulateFormatChanges = config_layer->Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); + dtm->bUseXFB = Config::Get(Config::GFX_USE_XFB); + dtm->bUseRealXFB = Config::Get(Config::GFX_USE_REAL_XFB); + dtm->bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE); + dtm->bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); + dtm->bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); // This never used the regular config dtm->bSkipIdle = true; diff --git a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.h b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.h index dbb2b7e6f7..22d102a742 100644 --- a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.h +++ b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.h @@ -30,6 +30,6 @@ private: Movie::DTMHeader* m_header; }; -void SaveToDTM(Config::Layer* layer, Movie::DTMHeader* header); +void SaveToDTM(Movie::DTMHeader* header); std::unique_ptr GenerateMovieConfigLoader(Movie::DTMHeader* header); } diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index 16ffdb7584..3bdcc9b13d 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -1306,7 +1306,7 @@ void SaveRecording(const std::string& filename) header.recordingStartTime = s_recordingStartTime; header.bSaveConfig = true; - ConfigLoaders::SaveToDTM(Config::GetLayer(Config::LayerType::Meta), &header); + ConfigLoaders::SaveToDTM(&header); header.memcards = s_memcards; header.bClearSave = s_bClearSave; header.bNetPlay = s_bNetPlay; From ec7b84c5f2f68ce8aae35c2dc12854117414f72b Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 30 Oct 2017 16:22:37 +0000 Subject: [PATCH 2/6] Config: Extract ConfigInfo into own header --- Source/Core/Common/CMakeLists.txt | 3 ++- Source/Core/Common/Config/Config.cpp | 15 ------------ Source/Core/Common/Config/Config.h | 19 +-------------- Source/Core/Common/Config/ConfigInfo.cpp | 25 ++++++++++++++++++++ Source/Core/Common/Config/ConfigInfo.h | 30 ++++++++++++++++++++++++ 5 files changed, 58 insertions(+), 34 deletions(-) create mode 100644 Source/Core/Common/Config/ConfigInfo.cpp create mode 100644 Source/Core/Common/Config/ConfigInfo.h diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 91eca8f2ae..5e5a220df7 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -4,6 +4,7 @@ set(SRCS ColorUtil.cpp CommonFuncs.cpp Config/Config.cpp + Config/ConfigInfo.cpp Config/Layer.cpp Config/Section.cpp Crypto/AES.cpp @@ -29,8 +30,8 @@ set(SRCS PcapFile.cpp PerformanceCounter.cpp Profiler.cpp - SettingsHandler.cpp SDCardUtil.cpp + SettingsHandler.cpp StringUtil.cpp SymbolDB.cpp SysConf.cpp diff --git a/Source/Core/Common/Config/Config.cpp b/Source/Core/Common/Config/Config.cpp index eb763c3632..abb2304749 100644 --- a/Source/Core/Common/Config/Config.cpp +++ b/Source/Core/Common/Config/Config.cpp @@ -126,21 +126,6 @@ const std::string& GetLayerName(LayerType layer) return layer_to_name.at(layer); } -bool ConfigLocation::operator==(const ConfigLocation& other) const -{ - return std::tie(system, section, key) == std::tie(other.system, other.section, other.key); -} - -bool ConfigLocation::operator!=(const ConfigLocation& other) const -{ - return !(*this == other); -} - -bool ConfigLocation::operator<(const ConfigLocation& other) const -{ - return std::tie(system, section, key) < std::tie(other.system, other.section, other.key); -} - LayerType GetActiveLayerForConfig(const ConfigLocation& config) { for (auto layer : SEARCH_ORDER) diff --git a/Source/Core/Common/Config/Config.h b/Source/Core/Common/Config/Config.h index 454fa3585e..69eac72203 100644 --- a/Source/Core/Common/Config/Config.h +++ b/Source/Core/Common/Config/Config.h @@ -9,30 +9,13 @@ #include #include +#include "Common/Config/ConfigInfo.h" #include "Common/Config/Enums.h" #include "Common/Config/Layer.h" #include "Common/Config/Section.h" namespace Config { -struct ConfigLocation -{ - System system; - std::string section; - std::string key; - - bool operator==(const ConfigLocation& other) const; - bool operator!=(const ConfigLocation& other) const; - bool operator<(const ConfigLocation& other) const; -}; - -template -struct ConfigInfo -{ - ConfigLocation location; - T default_value; -}; - using Layers = std::map>; using ConfigChangedCallback = std::function; diff --git a/Source/Core/Common/Config/ConfigInfo.cpp b/Source/Core/Common/Config/ConfigInfo.cpp new file mode 100644 index 0000000000..cc34a2d9f0 --- /dev/null +++ b/Source/Core/Common/Config/ConfigInfo.cpp @@ -0,0 +1,25 @@ +// Copyright 2016 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include + +#include "Common/Config/ConfigInfo.h" + +namespace Config +{ +bool ConfigLocation::operator==(const ConfigLocation& other) const +{ + return std::tie(system, section, key) == std::tie(other.system, other.section, other.key); +} + +bool ConfigLocation::operator!=(const ConfigLocation& other) const +{ + return !(*this == other); +} + +bool ConfigLocation::operator<(const ConfigLocation& other) const +{ + return std::tie(system, section, key) < std::tie(other.system, other.section, other.key); +} +} diff --git a/Source/Core/Common/Config/ConfigInfo.h b/Source/Core/Common/Config/ConfigInfo.h new file mode 100644 index 0000000000..fc36ecee03 --- /dev/null +++ b/Source/Core/Common/Config/ConfigInfo.h @@ -0,0 +1,30 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "Common/Config/Enums.h" + +namespace Config +{ +struct ConfigLocation +{ + System system; + std::string section; + std::string key; + + bool operator==(const ConfigLocation& other) const; + bool operator!=(const ConfigLocation& other) const; + bool operator<(const ConfigLocation& other) const; +}; + +template +struct ConfigInfo +{ + ConfigLocation location; + T default_value; +}; +} From e331a761762b23810df8c399c1f62d694fe48e4d Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 30 Oct 2017 17:09:05 +0000 Subject: [PATCH 3/6] ConfigInfo: Switch to doing case-insensitive comparison --- Source/Core/Common/Common.vcxproj | 4 ++-- Source/Core/Common/Config/ConfigInfo.cpp | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 853cff6d0f..7d8ba3b2b0 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -55,9 +55,9 @@ + - @@ -170,8 +170,8 @@ + - diff --git a/Source/Core/Common/Config/ConfigInfo.cpp b/Source/Core/Common/Config/ConfigInfo.cpp index cc34a2d9f0..47d2e25c84 100644 --- a/Source/Core/Common/Config/ConfigInfo.cpp +++ b/Source/Core/Common/Config/ConfigInfo.cpp @@ -2,15 +2,17 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include +#include +#include "Common/CommonFuncs.h" #include "Common/Config/ConfigInfo.h" namespace Config { bool ConfigLocation::operator==(const ConfigLocation& other) const { - return std::tie(system, section, key) == std::tie(other.system, other.section, other.key); + return system == other.system && strcasecmp(section.c_str(), other.section.c_str()) == 0 && + strcasecmp(key.c_str(), other.key.c_str()) == 0; } bool ConfigLocation::operator!=(const ConfigLocation& other) const @@ -20,6 +22,14 @@ bool ConfigLocation::operator!=(const ConfigLocation& other) const bool ConfigLocation::operator<(const ConfigLocation& other) const { - return std::tie(system, section, key) < std::tie(other.system, other.section, other.key); + if (system != other.system) + return system < other.system; + + const int section_compare = strcasecmp(section.c_str(), other.section.c_str()); + if (section_compare != 0) + return section_compare < 0; + + const int key_compare = strcasecmp(key.c_str(), other.key.c_str()); + return key_compare < 0; } } From f3b52c07d74d528a81c818d86c12981a6028f351 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 30 Oct 2017 17:15:21 +0000 Subject: [PATCH 4/6] CommandLineParser: Use ConfigLocation --- Source/Core/UICommon/CommandLineParse.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/Core/UICommon/CommandLineParse.cpp b/Source/Core/UICommon/CommandLineParse.cpp index d76a2052c4..cf47bd8a5c 100644 --- a/Source/Core/UICommon/CommandLineParse.cpp +++ b/Source/Core/UICommon/CommandLineParse.cpp @@ -10,7 +10,9 @@ #include #include "Common/Config/Config.h" +#include "Common/StringUtil.h" #include "Common/Version.h" +#include "Core/Config/MainSettings.h" #include "UICommon/CommandLineParse.h" namespace CommandLineParse @@ -23,22 +25,23 @@ public: : ConfigLayerLoader(Config::LayerType::CommandLine) { if (video_backend.size()) - m_values.emplace_back(std::make_tuple("Dolphin", "Core", "GFXBackend", video_backend)); + m_values.emplace_back(std::make_tuple(Config::MAIN_GFX_BACKEND.location, video_backend)); if (audio_backend.size()) m_values.emplace_back( - std::make_tuple("Dolphin", "Core", "DSPHLE", audio_backend == "HLE" ? "True" : "False")); + std::make_tuple(Config::MAIN_DSP_HLE.location, StringFromBool(audio_backend == "HLE"))); // Arguments are in the format of .
.=Value for (const auto& arg : args) { std::istringstream buffer(arg); - std::string system, section, key, value; - std::getline(buffer, system, '.'); + std::string system_str, section, key, value; + std::getline(buffer, system_str, '.'); std::getline(buffer, section, '.'); std::getline(buffer, key, '='); std::getline(buffer, value, '='); - m_values.emplace_back(std::make_tuple(system, section, key, value)); + Config::System system = Config::GetSystemFromName(system_str); + m_values.emplace_back(std::make_tuple(Config::ConfigLocation{system, section, key}, value)); } } @@ -46,9 +49,10 @@ public: { for (auto& value : m_values) { - Config::Section* section = config_layer->GetOrCreateSection( - Config::GetSystemFromName(std::get<0>(value)), std::get<1>(value)); - section->Set(std::get<2>(value), std::get<3>(value)); + const Config::ConfigLocation location = std::get<0>(value); + Config::Section* section = + config_layer->GetOrCreateSection(location.system, location.section); + section->Set(location.key, std::get<1>(value)); } } @@ -58,7 +62,7 @@ public: } private: - std::list> m_values; + std::list> m_values; }; std::unique_ptr CreateParser(ParserOptions options) From 4c24629b9551cab8af653a2bbcbe6d1639b3edb2 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sun, 29 Oct 2017 19:11:15 +0000 Subject: [PATCH 5/6] Config: Flatten structures Originally, Layer contained a std::map of Sections, which containted a std::map containing the (key, value) pairs. Here we flattern this structure so that only one std::map is required, reducing the number of indirections required and vastly simplifying the code. --- Source/Core/Common/CMakeLists.txt | 1 - Source/Core/Common/Config/Config.cpp | 2 +- Source/Core/Common/Config/Config.h | 1 - Source/Core/Common/Config/Layer.cpp | 99 +++---- Source/Core/Common/Config/Layer.h | 83 ++++-- Source/Core/Common/Config/Section.cpp | 249 ------------------ Source/Core/Common/Config/Section.h | 99 ------- Source/Core/Core/Config/MainSettings.cpp | 1 + Source/Core/Core/Config/MainSettings.h | 1 + .../Core/ConfigLoaders/BaseConfigLoader.cpp | 80 +++--- .../Core/ConfigLoaders/GameConfigLoader.cpp | 112 +++----- .../ConfigLoaders/NetPlayConfigLoader.cpp | 34 ++- Source/Core/UICommon/CommandLineParse.cpp | 9 +- 13 files changed, 220 insertions(+), 551 deletions(-) delete mode 100644 Source/Core/Common/Config/Section.cpp delete mode 100644 Source/Core/Common/Config/Section.h diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 5e5a220df7..f4e0a4ff84 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -6,7 +6,6 @@ set(SRCS Config/Config.cpp Config/ConfigInfo.cpp Config/Layer.cpp - Config/Section.cpp Crypto/AES.cpp Crypto/bn.cpp Crypto/ec.cpp diff --git a/Source/Core/Common/Config/Config.cpp b/Source/Core/Common/Config/Config.cpp index abb2304749..a3504f80d2 100644 --- a/Source/Core/Common/Config/Config.cpp +++ b/Source/Core/Common/Config/Config.cpp @@ -133,7 +133,7 @@ LayerType GetActiveLayerForConfig(const ConfigLocation& config) if (!LayerExists(layer)) continue; - if (GetLayer(layer)->Exists(config.system, config.section, config.key)) + if (GetLayer(layer)->Exists(config)) return layer; } diff --git a/Source/Core/Common/Config/Config.h b/Source/Core/Common/Config/Config.h index 69eac72203..3536f5677c 100644 --- a/Source/Core/Common/Config/Config.h +++ b/Source/Core/Common/Config/Config.h @@ -12,7 +12,6 @@ #include "Common/Config/ConfigInfo.h" #include "Common/Config/Enums.h" #include "Common/Config/Layer.h" -#include "Common/Config/Section.h" namespace Config { diff --git a/Source/Core/Common/Config/Layer.cpp b/Source/Core/Common/Config/Layer.cpp index a3912281f5..d4f9e7c633 100644 --- a/Source/Core/Common/Config/Layer.cpp +++ b/Source/Core/Common/Config/Layer.cpp @@ -8,10 +8,47 @@ #include "Common/Config/Config.h" #include "Common/Config/Layer.h" -#include "Common/Config/Section.h" namespace Config { +namespace detail +{ +std::string ValueToString(u16 value) +{ + return StringFromFormat("0x%04x", value); +} + +std::string ValueToString(u32 value) +{ + return StringFromFormat("0x%08x", value); +} + +std::string ValueToString(float value) +{ + return StringFromFormat("%#.9g", value); +} + +std::string ValueToString(double value) +{ + return StringFromFormat("%#.17g", value); +} + +std::string ValueToString(int value) +{ + return std::to_string(value); +} + +std::string ValueToString(bool value) +{ + return StringFromBool(value); +} + +std::string ValueToString(const std::string& value) +{ + return value; +} +} + ConfigLayerLoader::ConfigLayerLoader(LayerType layer) : m_layer(layer) { } @@ -38,56 +75,44 @@ Layer::~Layer() Save(); } -bool Layer::Exists(System system, const std::string& section_name, const std::string& key) +bool Layer::Exists(const ConfigLocation& location) const { - Section* section = GetSection(system, section_name); - if (!section) - return false; - return section->Exists(key); + const auto iter = m_map.find(location); + return iter != m_map.end() && iter->second.has_value(); } -bool Layer::DeleteKey(System system, const std::string& section_name, const std::string& key) +bool Layer::DeleteKey(const ConfigLocation& location) { - Section* section = GetSection(system, section_name); - if (!section) - return false; - return section->Delete(key); + m_is_dirty = true; + bool had_value = m_map[location].has_value(); + m_map[location].reset(); + return had_value; } -Section* Layer::GetSection(System system, const std::string& section_name) +void Layer::DeleteAllKeys() { - for (auto& section : m_sections[system]) - if (!strcasecmp(section->m_name.c_str(), section_name.c_str())) - return section.get(); - return nullptr; -} - -Section* Layer::GetOrCreateSection(System system, const std::string& section_name) -{ - Section* section = GetSection(system, section_name); - if (!section) + m_is_dirty = true; + for (auto& pair : m_map) { - m_sections[system].emplace_back(std::make_unique
(m_layer, system, section_name)); - section = m_sections[system].back().get(); + pair.second.reset(); } - return section; } void Layer::Load() { if (m_loader) m_loader->Load(this); - ClearDirty(); + m_is_dirty = false; InvokeConfigChangedCallbacks(); } void Layer::Save() { - if (!m_loader || !IsDirty()) + if (!m_loader || !m_is_dirty) return; m_loader->Save(this); - ClearDirty(); + m_is_dirty = false; InvokeConfigChangedCallbacks(); } @@ -98,22 +123,6 @@ LayerType Layer::GetLayer() const const LayerMap& Layer::GetLayerMap() const { - return m_sections; -} - -bool Layer::IsDirty() const -{ - return std::any_of(m_sections.begin(), m_sections.end(), [](const auto& system) { - return std::any_of(system.second.begin(), system.second.end(), - [](const auto& section) { return section->IsDirty(); }); - }); -} - -void Layer::ClearDirty() -{ - std::for_each(m_sections.begin(), m_sections.end(), [](auto& system) { - std::for_each(system.second.begin(), system.second.end(), - [](auto& section) { section->ClearDirty(); }); - }); + return m_map; } } diff --git a/Source/Core/Common/Config/Layer.h b/Source/Core/Common/Config/Layer.h index ac5b5c3e78..eb2a6bafca 100644 --- a/Source/Core/Common/Config/Layer.h +++ b/Source/Core/Common/Config/Layer.h @@ -6,18 +6,47 @@ #include #include +#include #include #include +#include "Common/Config/ConfigInfo.h" #include "Common/Config/Enums.h" -#include "Common/Config/Section.h" +#include "Common/StringUtil.h" namespace Config { +namespace detail +{ +std::string ValueToString(u16 value); +std::string ValueToString(u32 value); +std::string ValueToString(float value); +std::string ValueToString(double value); +std::string ValueToString(int value); +std::string ValueToString(bool value); +std::string ValueToString(const std::string& value); + +template +std::optional TryParse(const std::string& str_value) +{ + T value; + if (!::TryParse(str_value, &value)) + return std::nullopt; + return value; +} + +template <> +inline std::optional TryParse(const std::string& str_value) +{ + return str_value; +} +} + template struct ConfigInfo; -using LayerMap = std::map>>; +class Layer; +using LayerMap = std::map>; class ConfigLayerLoader { @@ -41,32 +70,40 @@ public: virtual ~Layer(); // Convenience functions - bool Exists(System system, const std::string& section_name, const std::string& key); - bool DeleteKey(System system, const std::string& section_name, const std::string& key); - template - bool GetIfExists(System system, const std::string& section_name, const std::string& key, T* value) - { - if (Exists(system, section_name, key)) - return GetOrCreateSection(system, section_name)->Get(key, value); - - return false; - } - - virtual Section* GetSection(System system, const std::string& section_name); - virtual Section* GetOrCreateSection(System system, const std::string& section_name); + bool Exists(const ConfigLocation& location) const; + bool DeleteKey(const ConfigLocation& location); + void DeleteAllKeys(); template T Get(const ConfigInfo& config_info) { - return GetOrCreateSection(config_info.location.system, config_info.location.section) - ->template Get(config_info.location.key, config_info.default_value); + return Get(config_info.location).value_or(config_info.default_value); + } + + template + std::optional Get(const ConfigLocation& location) + { + const std::optional& str_value = m_map[location]; + if (!str_value) + return std::nullopt; + return detail::TryParse(*str_value); } template void Set(const ConfigInfo& config_info, const T& value) { - GetOrCreateSection(config_info.location.system, config_info.location.section) - ->Set(config_info.location.key, value); + Set(config_info.location, value); + } + + template + void Set(const ConfigLocation& location, const T& value) + { + const std::string new_value = detail::ValueToString(value); + std::optional& current_value = m_map[location]; + if (current_value == new_value) + return; + m_is_dirty = true; + current_value = new_value; } // Explicit load and save of layers @@ -77,11 +114,9 @@ public: const LayerMap& GetLayerMap() const; protected: - bool IsDirty() const; - void ClearDirty(); - - LayerMap m_sections; + bool m_is_dirty = false; + LayerMap m_map; const LayerType m_layer; std::unique_ptr m_loader; }; -} // namespace Config +} diff --git a/Source/Core/Common/Config/Section.cpp b/Source/Core/Common/Config/Section.cpp deleted file mode 100644 index 12adff2b1f..0000000000 --- a/Source/Core/Common/Config/Section.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include -#include -#include - -#include "Common/Assert.h" -#include "Common/Config/Config.h" -#include "Common/Config/Layer.h" -#include "Common/Config/Section.h" -#include "Common/StringUtil.h" - -namespace Config -{ -const std::string& Section::NULL_STRING = ""; - -Section::Section(LayerType layer, System system, const std::string& name) - : m_layer(layer), m_system(system), m_name(name) -{ -} - -bool Section::Exists(const std::string& key) const -{ - return m_values.find(key) != m_values.end(); -} - -bool Section::Delete(const std::string& key) -{ - auto it = m_values.find(key); - if (it == m_values.end()) - return false; - - m_values.erase(it); - - m_deleted_keys.push_back(key); - m_dirty = true; - return true; -} - -void Section::Set(const std::string& key, const std::string& value) -{ - auto it = m_values.find(key); - if (it != m_values.end() && it->second != value) - { - it->second = value; - m_dirty = true; - } - else if (it == m_values.end()) - { - m_values[key] = value; - m_dirty = true; - } -} - -void Section::Set(const std::string& key, u16 newValue) -{ - Section::Set(key, StringFromFormat("0x%04x", newValue)); -} - -void Section::Set(const std::string& key, u32 newValue) -{ - Section::Set(key, StringFromFormat("0x%08x", newValue)); -} - -void Section::Set(const std::string& key, float newValue) -{ - Section::Set(key, StringFromFormat("%#.9g", newValue)); -} - -void Section::Set(const std::string& key, double newValue) -{ - Section::Set(key, StringFromFormat("%#.17g", newValue)); -} - -void Section::Set(const std::string& key, int newValue) -{ - Section::Set(key, std::to_string(newValue)); -} - -void Section::Set(const std::string& key, bool newValue) -{ - Section::Set(key, StringFromBool(newValue)); -} - -void Section::Set(const std::string& key, const std::string& newValue, - const std::string& defaultValue) -{ - if (newValue != defaultValue) - Set(key, newValue); - else - Delete(key); -} - -void Section::SetLines(const std::vector& lines) -{ - m_lines = lines; - m_dirty = true; -} - -bool Section::Get(const std::string& key, std::string* value, - const std::string& default_value) const -{ - const auto& it = m_values.find(key); - if (it != m_values.end()) - { - *value = it->second; - return true; - } - else if (&default_value != &NULL_STRING) - { - *value = default_value; - return true; - } - - return false; -} - -bool Section::Get(const std::string& key, int* value, int defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool Section::Get(const std::string& key, u16* value, u16 defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool Section::Get(const std::string& key, u32* value, u32 defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool Section::Get(const std::string& key, bool* value, bool defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool Section::Get(const std::string& key, float* value, float defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -bool Section::Get(const std::string& key, double* value, double defaultValue) const -{ - std::string temp; - bool retval = Get(key, &temp); - - if (retval && TryParse(temp, value)) - return true; - - *value = defaultValue; - return false; -} - -// Return a list of all lines in a section -bool Section::GetLines(std::vector* lines, const bool remove_comments) const -{ - lines->clear(); - - for (std::string line : m_lines) - { - line = StripSpaces(line); - - if (remove_comments) - { - size_t commentPos = line.find('#'); - if (commentPos == 0) - { - continue; - } - - if (commentPos != std::string::npos) - { - line = StripSpaces(line.substr(0, commentPos)); - } - } - - lines->push_back(line); - } - - return true; -} - -bool Section::HasLines() const -{ - return !m_lines.empty(); -} - -const std::string& Section::GetName() const -{ - return m_name; -} - -const SectionValueMap& Section::GetValues() const -{ - return m_values; -} - -const std::vector& Section::GetDeletedKeys() const -{ - return m_deleted_keys; -} - -bool Section::IsDirty() const -{ - return m_dirty; -} -void Section::ClearDirty() -{ - m_dirty = false; -} -} diff --git a/Source/Core/Common/Config/Section.h b/Source/Core/Common/Config/Section.h deleted file mode 100644 index 592b791722..0000000000 --- a/Source/Core/Common/Config/Section.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2017 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include - -// XXX: Purely for case insensitive compare -#include "Common/CommonTypes.h" -#include "Common/Config/Enums.h" -#include "Common/IniFile.h" - -namespace Config -{ -class Layer; -class ConfigLayerLoader; - -using SectionValueMap = std::map; - -class Section -{ - friend Layer; - friend ConfigLayerLoader; - -public: - Section(LayerType layer, System system, const std::string& name); - virtual ~Section() = default; - - virtual bool Exists(const std::string& key) const; - bool Delete(const std::string& key); - - // Setters - virtual void Set(const std::string& key, const std::string& value); - - void Set(const std::string& key, u16 newValue); - void Set(const std::string& key, u32 newValue); - void Set(const std::string& key, float newValue); - void Set(const std::string& key, double newValue); - void Set(const std::string& key, int newValue); - void Set(const std::string& key, bool newValue); - - // Setters with default values - void Set(const std::string& key, const std::string& newValue, const std::string& defaultValue); - template - void Set(const std::string& key, T newValue, const T defaultValue) - { - if (newValue != defaultValue) - Set(key, newValue); - else - Delete(key); - } - - // Getters - virtual bool Get(const std::string& key, std::string* value, - const std::string& default_value = NULL_STRING) const; - - bool Get(const std::string& key, int* value, int defaultValue = 0) const; - bool Get(const std::string& key, u16* value, u16 defaultValue = 0) const; - bool Get(const std::string& key, u32* value, u32 defaultValue = 0) const; - bool Get(const std::string& key, bool* value, bool defaultValue = false) const; - bool Get(const std::string& key, float* value, float defaultValue = 0.0f) const; - bool Get(const std::string& key, double* value, double defaultValue = 0.0) const; - - template - T Get(const std::string& key, const T& default_value) const - { - T value; - Get(key, &value, default_value); - return value; - } - - // Section chunk - void SetLines(const std::vector& lines); - // XXX: Add to recursive layer - virtual bool GetLines(std::vector* lines, const bool remove_comments = true) const; - virtual bool HasLines() const; - const std::string& GetName() const; - const SectionValueMap& GetValues() const; - const std::vector& GetDeletedKeys() const; - bool IsDirty() const; - void ClearDirty(); - -protected: - bool m_dirty = false; - - LayerType m_layer; - System m_system; - const std::string m_name; - static const std::string& NULL_STRING; - - SectionValueMap m_values; - std::vector m_deleted_keys; - - std::vector m_lines; -}; -} diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 697dc81a32..77687c28df 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -61,6 +61,7 @@ ConfigInfo GetInfoForSimulateKonga(u32 channel) } const ConfigInfo MAIN_WII_SD_CARD{{System::Main, "Core", "WiiSDCard"}, false}; +const ConfigInfo MAIN_WII_SD_CARD_WRITABLE{{System::Main, "Core", "WiiSDCardWritable"}, true}; const ConfigInfo MAIN_WII_KEYBOARD{{System::Main, "Core", "WiiKeyboard"}, false}; const ConfigInfo MAIN_WIIMOTE_CONTINUOUS_SCANNING{ {System::Main, "Core", "WiimoteContinuousScanning"}, false}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index cc21e1ac7c..871e103bb9 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -40,6 +40,7 @@ ConfigInfo GetInfoForSIDevice(u32 channel); ConfigInfo GetInfoForAdapterRumble(u32 channel); ConfigInfo GetInfoForSimulateKonga(u32 channel); extern const ConfigInfo MAIN_WII_SD_CARD; +extern const ConfigInfo MAIN_WII_SD_CARD_WRITABLE; extern const ConfigInfo MAIN_WII_KEYBOARD; extern const ConfigInfo MAIN_WIIMOTE_CONTINUOUS_SCANNING; extern const ConfigInfo MAIN_WIIMOTE_ENABLE_SPEAKER; diff --git a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp index 848501ba73..4dcfb613ae 100644 --- a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp @@ -77,9 +77,9 @@ class BaseConfigLayerLoader final : public Config::ConfigLayerLoader { public: BaseConfigLayerLoader() : ConfigLayerLoader(Config::LayerType::Base) {} - void Load(Config::Layer* config_layer) override + void Load(Config::Layer* layer) override { - LoadFromSYSCONF(config_layer); + LoadFromSYSCONF(layer); for (const auto& system : system_to_ini) { IniFile ini; @@ -89,55 +89,62 @@ public: for (const auto& section : system_sections) { const std::string section_name = section.GetName(); - Config::Section* config_section = - config_layer->GetOrCreateSection(system.first, section_name); const IniFile::Section::SectionMap& section_map = section.GetValues(); for (const auto& value : section_map) - config_section->Set(value.first, value.second); + { + const Config::ConfigLocation location{system.first, section_name, value.first}; + layer->Set(location, value.second); + } } } } - void Save(Config::Layer* config_layer) override + void Save(Config::Layer* layer) override { - const Config::LayerMap& sections = config_layer->GetLayerMap(); - for (const auto& system : sections) - { - if (system.first == Config::System::SYSCONF) - { - SaveToSYSCONF(config_layer->GetLayer()); - continue; - } + SaveToSYSCONF(layer->GetLayer()); - auto mapping = system_to_ini.find(system.first); - if (mapping == system_to_ini.end()) + std::map inis; + + for (const auto& system : system_to_ini) + { + inis[system.first].Load(File::GetUserPath(system.second)); + } + + for (const auto& config : layer->GetLayerMap()) + { + const Config::ConfigLocation& location = config.first; + const std::optional& value = config.second; + + // Done by SaveToSYSCONF + if (location.system == Config::System::SYSCONF) + continue; + + auto ini = inis.find(location.system); + if (ini == inis.end()) { ERROR_LOG(COMMON, "Config can't map system '%s' to an INI file!", - Config::GetSystemName(system.first).c_str()); + Config::GetSystemName(location.system).c_str()); continue; } - IniFile ini; - ini.Load(File::GetUserPath(mapping->second)); + if (!IsSettingSaveable(location)) + continue; - for (const auto& section : system.second) + if (value) { - const std::string section_name = section->GetName(); - const Config::SectionValueMap& section_values = section->GetValues(); - - IniFile::Section* ini_section = ini.GetOrCreateSection(section_name); - - for (const auto& value : section_values) - { - if (!IsSettingSaveable({system.first, section->GetName(), value.first})) - continue; - - ini_section->Set(value.first, value.second); - } + IniFile::Section* ini_section = ini->second.GetOrCreateSection(location.section); + ini_section->Set(location.key, *value); } + else + { + ini->second.DeleteKey(location.section, location.key); + } + } - ini.Save(File::GetUserPath(mapping->second)); + for (const auto& system : system_to_ini) + { + inis[system.first].Save(File::GetUserPath(system.second)); } } @@ -153,13 +160,10 @@ private: std::visit( [&](auto& info) { const std::string key = info.location.section + "." + info.location.key; - auto* section = - layer->GetOrCreateSection(Config::System::SYSCONF, info.location.section); - if (setting.type == SysConf::Entry::Type::Long) - section->Set(info.location.key, sysconf.GetData(key, info.default_value)); + layer->Set(info.location, sysconf.GetData(key, info.default_value)); else if (setting.type == SysConf::Entry::Type::Byte) - section->Set(info.location.key, sysconf.GetData(key, info.default_value)); + layer->Set(info.location, sysconf.GetData(key, info.default_value)); }, setting.config_info); } diff --git a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp index cce5fa61b8..17ffed0b94 100644 --- a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp @@ -199,10 +199,10 @@ public: { } - void Load(Config::Layer* config_layer) override + void Load(Config::Layer* layer) override { IniFile ini; - if (config_layer->GetLayer() == Config::LayerType::GlobalGame) + if (layer->GetLayer() == Config::LayerType::GlobalGame) { for (const std::string& filename : GetGameIniFilenames(m_id, m_revision)) ini.Load(File::GetSysDirectory() + GAMESETTINGS_DIR DIR_SEP + filename, true); @@ -217,16 +217,16 @@ public: for (const auto& section : system_sections) { - LoadFromSystemSection(config_layer, section); + LoadFromSystemSection(layer, section); } - LoadControllerConfig(config_layer); + LoadControllerConfig(layer); } - void Save(Config::Layer* config_layer) override; + void Save(Config::Layer* layer) override; private: - void LoadControllerConfig(Config::Layer* config_layer) const + void LoadControllerConfig(Config::Layer* layer) const { // Game INIs can have controller profiles embedded in to them static const std::array nums = {{'1', '2', '3', '4'}}; @@ -244,82 +244,53 @@ private: std::string type = std::get<0>(use_data); std::string path = "Profiles/" + std::get<1>(use_data) + "/"; - Config::Section* control_section = - config_layer->GetOrCreateSection(std::get<2>(use_data), "Controls"); + const auto control_section = [&](std::string key) { + return Config::ConfigLocation{std::get<2>(use_data), "Controls", key}; + }; for (const char num : nums) { - bool use_profile = false; - std::string profile; - if (control_section->Exists(type + "Profile" + num)) + if (auto profile = layer->Get(control_section(type + "Profile" + num))) { - if (control_section->Get(type + "Profile" + num, &profile)) + std::string ini_path = File::GetUserPath(D_CONFIG_IDX) + path + *profile + ".ini"; + if (!File::Exists(ini_path)) { - if (File::Exists(File::GetUserPath(D_CONFIG_IDX) + path + profile + ".ini")) - { - use_profile = true; - } - else - { - // TODO: PanicAlert shouldn't be used for this. - PanicAlertT("Selected controller profile does not exist"); - } + // TODO: PanicAlert shouldn't be used for this. + PanicAlertT("Selected controller profile does not exist"); + continue; } - } - if (use_profile) - { IniFile profile_ini; - profile_ini.Load(File::GetUserPath(D_CONFIG_IDX) + path + profile + ".ini"); + profile_ini.Load(ini_path); const IniFile::Section* ini_section = profile_ini.GetOrCreateSection("Profile"); const IniFile::Section::SectionMap& section_map = ini_section->GetValues(); for (const auto& value : section_map) { - Config::Section* section = config_layer->GetOrCreateSection( - std::get<2>(use_data), std::get<1>(use_data) + num); - section->Set(value.first, value.second); + Config::ConfigLocation location{std::get<2>(use_data), std::get<1>(use_data) + num, + value.first}; + layer->Set(location, value.second); } } } } } - void LoadFromSystemSection(Config::Layer* config_layer, const IniFile::Section& section) const + void LoadFromSystemSection(Config::Layer* layer, const IniFile::Section& section) const { const std::string section_name = section.GetName(); - if (section.HasLines()) - { - // Trash INI File chunks - std::vector chunk; - section.GetLines(&chunk, true); - - if (chunk.size()) - { - const auto mapped_config = MapINIToRealLocation(section_name, ""); - - if (mapped_config.section.empty() && mapped_config.key.empty()) - return; - - auto* config_section = - config_layer->GetOrCreateSection(mapped_config.system, mapped_config.section); - config_section->SetLines(chunk); - } - } // Regular key,value pairs const IniFile::Section::SectionMap& section_map = section.GetValues(); for (const auto& value : section_map) { - const auto mapped_config = MapINIToRealLocation(section_name, value.first); + const auto location = MapINIToRealLocation(section_name, value.first); - if (mapped_config.section.empty() && mapped_config.key.empty()) + if (location.section.empty() && location.key.empty()) continue; - auto* config_section = - config_layer->GetOrCreateSection(mapped_config.system, mapped_config.section); - config_section->Set(mapped_config.key, value.second); + layer->Set(location, value.second); } } @@ -327,32 +298,35 @@ private: const u16 m_revision; }; -void INIGameConfigLayerLoader::Save(Config::Layer* config_layer) +void INIGameConfigLayerLoader::Save(Config::Layer* layer) { - if (config_layer->GetLayer() != Config::LayerType::LocalGame) + if (layer->GetLayer() != Config::LayerType::LocalGame) return; IniFile ini; for (const std::string& file_name : GetGameIniFilenames(m_id, m_revision)) ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + file_name, true); - for (const auto& system : config_layer->GetLayerMap()) + for (const auto& config : layer->GetLayerMap()) { - for (const auto& section : system.second) + const Config::ConfigLocation& location = config.first; + const std::optional& value = config.second; + + if (!IsSettingSaveable(location)) + continue; + + const auto ini_location = GetINILocationFromConfig(location); + if (ini_location.first.empty() && ini_location.second.empty()) + continue; + + if (value) { - for (const auto& value : section->GetValues()) - { - if (!IsSettingSaveable({system.first, section->GetName(), value.first})) - continue; - - const auto ini_location = - GetINILocationFromConfig({system.first, section->GetName(), value.first}); - if (ini_location.first.empty() && ini_location.second.empty()) - continue; - - IniFile::Section* ini_section = ini.GetOrCreateSection(ini_location.first); - ini_section->Set(ini_location.second, value.second); - } + IniFile::Section* ini_section = ini.GetOrCreateSection(ini_location.first); + ini_section->Set(ini_location.second, *value); + } + else + { + ini.DeleteKey(ini_location.first, ini_location.second); } } diff --git a/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp index b9b2085feb..8abb16cf9b 100644 --- a/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/NetPlayConfigLoader.cpp @@ -7,6 +7,7 @@ #include #include "Common/Config/Config.h" +#include "Core/Config/MainSettings.h" #include "Core/Config/SYSCONFSettings.h" #include "Core/NetPlayProto.h" @@ -20,29 +21,26 @@ public: { } - void Load(Config::Layer* config_layer) override + void Load(Config::Layer* layer) override { - Config::Section* core = config_layer->GetOrCreateSection(Config::System::Main, "Core"); - Config::Section* dsp = config_layer->GetOrCreateSection(Config::System::Main, "DSP"); + layer->Set(Config::MAIN_CPU_THREAD, m_settings.m_CPUthread); + layer->Set(Config::MAIN_CPU_CORE, m_settings.m_CPUcore); + layer->Set(Config::MAIN_GC_LANGUAGE, m_settings.m_SelectedLanguage); + layer->Set(Config::MAIN_OVERRIDE_GC_LANGUAGE, m_settings.m_OverrideGCLanguage); + layer->Set(Config::MAIN_DSP_HLE, m_settings.m_DSPHLE); + layer->Set(Config::MAIN_OVERCLOCK_ENABLE, m_settings.m_OCEnable); + layer->Set(Config::MAIN_OVERCLOCK, m_settings.m_OCFactor); + layer->Set(Config::MAIN_SLOT_A, static_cast(m_settings.m_EXIDevice[0])); + layer->Set(Config::MAIN_SLOT_B, static_cast(m_settings.m_EXIDevice[1])); + layer->Set(Config::MAIN_WII_SD_CARD_WRITABLE, m_settings.m_WriteToMemcard); - core->Set("CPUThread", m_settings.m_CPUthread); - core->Set("CPUCore", m_settings.m_CPUcore); - core->Set("SelectedLanguage", m_settings.m_SelectedLanguage); - core->Set("OverrideGCLang", m_settings.m_OverrideGCLanguage); - core->Set("DSPHLE", m_settings.m_DSPHLE); - core->Set("OverclockEnable", m_settings.m_OCEnable); - core->Set("Overclock", m_settings.m_OCFactor); - core->Set("SlotA", m_settings.m_EXIDevice[0]); - core->Set("SlotB", m_settings.m_EXIDevice[1]); - core->Set("EnableSaving", m_settings.m_WriteToMemcard); + layer->Set(Config::MAIN_DSP_JIT, m_settings.m_DSPEnableJIT); - dsp->Set("EnableJIT", m_settings.m_DSPEnableJIT); - - config_layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, m_settings.m_ProgressiveScan); - config_layer->Set(Config::SYSCONF_PAL60, m_settings.m_PAL60); + layer->Set(Config::SYSCONF_PROGRESSIVE_SCAN, m_settings.m_ProgressiveScan); + layer->Set(Config::SYSCONF_PAL60, m_settings.m_PAL60); } - void Save(Config::Layer* config_layer) override + void Save(Config::Layer* layer) override { // Do Nothing } diff --git a/Source/Core/UICommon/CommandLineParse.cpp b/Source/Core/UICommon/CommandLineParse.cpp index cf47bd8a5c..236cd86ba2 100644 --- a/Source/Core/UICommon/CommandLineParse.cpp +++ b/Source/Core/UICommon/CommandLineParse.cpp @@ -45,18 +45,15 @@ public: } } - void Load(Config::Layer* config_layer) override + void Load(Config::Layer* layer) override { for (auto& value : m_values) { - const Config::ConfigLocation location = std::get<0>(value); - Config::Section* section = - config_layer->GetOrCreateSection(location.system, location.section); - section->Set(location.key, std::get<1>(value)); + layer->Set(std::get<0>(value), std::get<1>(value)); } } - void Save(Config::Layer* config_layer) override + void Save(Config::Layer* layer) override { // Save Nothing } From 37419b9a579fbcb1633caa9295a39da405e93904 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 30 Oct 2017 18:10:05 +0000 Subject: [PATCH 6/6] Config/Layer: Allow all keys of a section to be iterated over --- Source/Core/Common/Config/Layer.cpp | 12 ++++++++++++ Source/Core/Common/Config/Layer.h | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/Source/Core/Common/Config/Layer.cpp b/Source/Core/Common/Config/Layer.cpp index d4f9e7c633..5a5c4b5f59 100644 --- a/Source/Core/Common/Config/Layer.cpp +++ b/Source/Core/Common/Config/Layer.cpp @@ -98,6 +98,18 @@ void Layer::DeleteAllKeys() } } +Section Layer::GetSection(System system, const std::string& section) +{ + return Section{m_map.lower_bound(ConfigLocation{system, section, ""}), + m_map.lower_bound(ConfigLocation{system, section + '\001', ""})}; +} + +ConstSection Layer::GetSection(System system, const std::string& section) const +{ + return ConstSection{m_map.lower_bound(ConfigLocation{system, section, ""}), + m_map.lower_bound(ConfigLocation{system, section + '\001', ""})}; +} + void Layer::Load() { if (m_loader) diff --git a/Source/Core/Common/Config/Layer.h b/Source/Core/Common/Config/Layer.h index eb2a6bafca..8e56ae308a 100644 --- a/Source/Core/Common/Config/Layer.h +++ b/Source/Core/Common/Config/Layer.h @@ -62,6 +62,30 @@ private: const LayerType m_layer; }; +class Section +{ +public: + using iterator = LayerMap::iterator; + Section(iterator begin_, iterator end_) : m_begin(begin_), m_end(end_) {} + iterator begin() const { return m_begin; } + iterator end() const { return m_end; } +private: + iterator m_begin; + iterator m_end; +}; + +class ConstSection +{ +public: + using iterator = LayerMap::const_iterator; + ConstSection(iterator begin_, iterator end_) : m_begin(begin_), m_end(end_) {} + iterator begin() const { return m_begin; } + iterator end() const { return m_end; } +private: + iterator m_begin; + iterator m_end; +}; + class Layer { public: @@ -106,6 +130,9 @@ public: current_value = new_value; } + Section GetSection(System system, const std::string& section); + ConstSection GetSection(System system, const std::string& section) const; + // Explicit load and save of layers void Load(); void Save();