From 7578a1935b9f7167a2ea624bf520c397e82cb96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 29 Oct 2025 15:41:41 +0100 Subject: [PATCH] More config refactor --- Core/Config.cpp | 55 +++++++++++++++++++++++++---------------- Core/Config.h | 7 ++++++ Core/ConfigSettings.cpp | 11 +++------ Core/ConfigSettings.h | 30 ++++++---------------- 4 files changed, 51 insertions(+), 52 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 15eddbae4e..eb0990b77f 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -1055,7 +1055,7 @@ static const ConfigSetting vrSettings[] = { }; // The first column says what structure the parameters are relative to. -static const ConfigSectionSettings sections[] = { +static const ConfigSectionSettings sectionDescs[] = { {(const char *)&g_Config, "General", generalSettings, ARRAY_SIZE(generalSettings)}, {(const char *)&g_Config, "CPU", cpuSettings, ARRAY_SIZE(cpuSettings)}, {(const char *)&g_Config, "Graphics", graphicsSettings, ARRAY_SIZE(graphicsSettings)}, @@ -1070,26 +1070,38 @@ static const ConfigSectionSettings sections[] = { {(const char *)&g_Config, "Achievements", achievementSettings, ARRAY_SIZE(achievementSettings)}, }; -const size_t numSections = ARRAY_SIZE(sections); +const size_t numSections = ARRAY_SIZE(sectionDescs); static void IterateSettings(IniFile &iniFile, std::function func) { for (size_t i = 0; i < numSections; ++i) { - Section *section = iniFile.GetOrCreateSection(sections[i].section); - for (size_t j = 0; j < sections[i].settingsCount; j++) { - func(section, sections[i].settings[j]); + Section *section = iniFile.GetOrCreateSection(sectionDescs[i].section); + for (size_t j = 0; j < sectionDescs[i].settingsCount; j++) { + func(section, sectionDescs[i].settings[j]); } } } static void IterateSettings(std::function func) { for (size_t i = 0; i < numSections; ++i) { - for (size_t j = 0; j < sections[i].settingsCount; j++) { - func(sections[i].settings[j]); + for (size_t j = 0; j < sectionDescs[i].settingsCount; j++) { + func(sectionDescs[i].settings[j]); } } } -Config::Config() {} +std::map &Config::getPtrLUT() { + static std::map lut; + return lut; +} + +Config::Config() { + // Initialize the pointer->setting lookup map. + auto ref = getPtrLUT(); + IterateSettings([this, &ref](const ConfigSetting &setting) { + const void *ptr = setting.GetVoidPtr(); + ref[ptr] = &setting; + }); +} Config::~Config() { if (bUpdatedInstanceCounter) { @@ -1165,8 +1177,9 @@ bool Config::LoadAppendedConfig() { } IterateSettings(iniFile, [&iniFile](Section *section, const ConfigSetting &setting) { - if (iniFile.Exists(section->name().c_str(), setting.iniKey_)) - setting.Get(section); + if (iniFile.Exists(section->name().c_str(), setting.iniKey_)) { + setting.ReadFromIniSection(section); + } }); INFO_LOG(Log::Loader, "Loaded appended config '%s'.", appendedConfigFileName_.c_str()); @@ -1210,8 +1223,8 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { // Continue anyway to initialize the config. } - IterateSettings(iniFile, [](Section *section, const ConfigSetting &setting) { - setting.Get(section); + IterateSettings(iniFile, [](const Section *section, const ConfigSetting &setting) { + setting.ReadFromIniSection(section); }); iRunCount++; @@ -1353,7 +1366,7 @@ bool Config::Save(const char *saveReason) { IterateSettings(iniFile, [&](Section *section, const ConfigSetting &setting) { if (!bGameSpecific || !setting.PerGame()) { - setting.Set(section); + setting.WriteToIniSection(section); } }); @@ -1642,7 +1655,7 @@ bool Config::saveGameConfig(const std::string &pGameId, const std::string &title IterateSettings(iniFile, [](Section *section, const ConfigSetting &setting) { if (setting.PerGame()) { - setting.Set(section); + setting.WriteToIniSection(section); } }); @@ -1699,9 +1712,9 @@ bool Config::loadGameConfig(const std::string &pGameId, const std::string &title vPostShaderNames.push_back(v); } - IterateSettings(iniFile, [](Section *section, const ConfigSetting &setting) { + IterateSettings(iniFile, [](const Section *section, const ConfigSetting &setting) { if (setting.PerGame()) { - setting.Get(section); + setting.ReadFromIniSection(section); } }); @@ -1726,9 +1739,9 @@ void Config::unloadGameConfig() { iniFile.Load(iniFilename_); // Reload game specific settings back to standard. - IterateSettings(iniFile, [](Section *section, const ConfigSetting &setting) { + IterateSettings(iniFile, [](const Section *section, const ConfigSetting &setting) { if (setting.PerGame()) { - setting.Get(section); + setting.ReadFromIniSection(section); } }); @@ -1787,9 +1800,9 @@ void Config::ResetControlLayout() { void Config::GetReportingInfo(UrlEncoder &data) const { for (size_t i = 0; i < numSections; ++i) { - const std::string prefix = std::string("config.") + sections[i].section; - for (size_t j = 0; j < sections[i].settingsCount; j++) { - sections[i].settings[j].ReportSetting(data, prefix); + const std::string prefix = std::string("config.") + sectionDescs[i].section; + for (size_t j = 0; j < sectionDescs[i].settingsCount; j++) { + sectionDescs[i].settings[j].ReportSetting(data, prefix); } } } diff --git a/Core/Config.h b/Core/Config.h index f61e06cb20..e80f73e912 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -59,6 +59,8 @@ private: std::map tracker_; }; +struct ConfigSetting; + struct Config { public: Config(); @@ -668,6 +670,8 @@ protected: void PreSaveCleanup(bool gameSpecific); void PostSaveCleanup(bool gameSpecific); + static std::map &getPtrLUT(); + private: bool reload_ = false; std::string gameId_; @@ -680,6 +684,9 @@ private: Path appendedConfigFileName_; // A set make more sense, but won't have many entry, and I dont want to include the whole std::set header here std::vector appendedConfigUpdatedGames_; + + // TODO: Remove hack. + friend struct ConfigSetting; }; std::string CreateRandMAC(); diff --git a/Core/ConfigSettings.cpp b/Core/ConfigSettings.cpp index d3479c96a3..d379af9925 100644 --- a/Core/ConfigSettings.cpp +++ b/Core/ConfigSettings.cpp @@ -8,16 +8,11 @@ #include "Core/ConfigValues.h" #include "Core/Config.h" -std::unordered_map& ConfigSetting::getPtrLUT() { - static std::unordered_map lut; - return lut; -} - bool ConfigSetting::perGame(void *ptr) { - return g_Config.bGameSpecific && getPtrLUT().count(ptr) > 0 && getPtrLUT()[ptr]->PerGame(); + return g_Config.bGameSpecific && g_Config.getPtrLUT().count(ptr) > 0 && g_Config.getPtrLUT()[ptr]->PerGame(); } -bool ConfigSetting::Get(const Section *section) const { +bool ConfigSetting::ReadFromIniSection(const Section *section) const { switch (type_) { case TYPE_BOOL: return section->Get(iniKey_, ptr_.b, cb_.b ? cb_.b() : default_.b); @@ -86,7 +81,7 @@ bool ConfigSetting::Get(const Section *section) const { } } -void ConfigSetting::Set(Section *section) const { +void ConfigSetting::WriteToIniSection(Section *section) const { if (!SaveSetting()) { return; } diff --git a/Core/ConfigSettings.h b/Core/ConfigSettings.h index 892e30690a..cc8d76387c 100644 --- a/Core/ConfigSettings.h +++ b/Core/ConfigSettings.h @@ -82,7 +82,6 @@ struct ConfigSetting { ptr_.b = v; cb_.b = nullptr; default_.b = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, int *v, int def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -90,7 +89,6 @@ struct ConfigSetting { ptr_.i = v; cb_.i = nullptr; default_.i = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, int *v, int def, std::string (*transTo)(int), int (*transFrom)(const std::string &), CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -98,7 +96,6 @@ struct ConfigSetting { ptr_.i = v; cb_.i = nullptr; default_.i = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, uint32_t *v, uint32_t def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -106,7 +103,6 @@ struct ConfigSetting { ptr_.u = v; cb_.u = nullptr; default_.u = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, uint64_t *v, uint64_t def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -114,7 +110,6 @@ struct ConfigSetting { ptr_.lu = v; cb_.lu = nullptr; default_.lu = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, float *v, float def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -122,7 +117,6 @@ struct ConfigSetting { ptr_.f = v; cb_.f = nullptr; default_.f = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, std::string *v, const char *def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -130,14 +124,12 @@ struct ConfigSetting { ptr_.s = v; cb_.s = nullptr; default_.s = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, std::vector *v, const std::vector *def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_STRING_VECTOR), flags_(flags) { ptr_.v = v; default_.v = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, Path *v, const char *def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -145,7 +137,6 @@ struct ConfigSetting { ptr_.p = v; cb_.p = nullptr; default_.p = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigTouchPos *v, ConfigTouchPos def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -153,7 +144,6 @@ struct ConfigSetting { ptr_.touchPos = v; cb_.touchPos = nullptr; default_.touchPos = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *iniKey, const char *iniImage, const char *iniShape, const char *iniToggle, const char *iniRepeat, ConfigCustomButton *v, ConfigCustomButton def, CfgFlag flags = CfgFlag::DEFAULT) noexcept @@ -161,64 +151,55 @@ struct ConfigSetting { ptr_.customButton = v; cb_.customButton = nullptr; default_.customButton = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, bool *v, BoolDefaultCallback def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_BOOL), flags_(flags) { ptr_.b = v; cb_.b = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, int *v, IntDefaultCallback def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_INT), flags_(flags) { ptr_.i = v; cb_.i = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, int *v, IntDefaultCallback def, std::string(*transTo)(int), int(*transFrom)(const std::string &), CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_INT), flags_(flags), translateTo_(transTo), translateFrom_(transFrom) { ptr_.i = v; cb_.i = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, uint32_t *v, Uint32DefaultCallback def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_UINT32), flags_(flags) { ptr_.u = v; cb_.u = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, float *v, FloatDefaultCallback def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_FLOAT), flags_(flags) { ptr_.f = v; cb_.f = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *ini, std::string *v, StringDefaultCallback def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(ini), type_(TYPE_STRING), flags_(flags) { ptr_.s = v; cb_.s = def; - getPtrLUT()[v] = this; } ConfigSetting(const char *iniX, const char *iniY, const char *iniScale, const char *iniShow, ConfigTouchPos *v, TouchPosDefaultCallback def, CfgFlag flags = CfgFlag::DEFAULT) noexcept : iniKey_(iniX), ini2_(iniY), ini3_(iniScale), ini4_(iniShow), type_(TYPE_TOUCH_POS), flags_(flags) { ptr_.touchPos = v; cb_.touchPos = def; - getPtrLUT()[v] = this; } - // Should actually be called ReadFromIni or something. - bool Get(const Section *section) const; + bool ReadFromIniSection(const Section *section) const; // Yes, this can be const because what's modified is not the ConfigSetting struct, but the value which is stored elsewhere. // Should actually be called WriteToIni or something. - void Set(Section *section) const; + void WriteToIniSection(Section *section) const; // If log is true, logs if the setting changed. bool RestoreToDefault(bool log) const; @@ -241,6 +222,11 @@ struct ConfigSetting { // Returns false if per-game settings are not currently used static bool perGame(void *ptr); + const void *GetVoidPtr() const { + // undefined behavior but in reality will work. + return (const void *)ptr_.i; + } + private: CfgFlag flags_; SettingPtr ptr_{}; @@ -250,8 +236,6 @@ private: // We only support transform for ints. std::string (*translateTo_)(int) = nullptr; int (*translateFrom_)(const std::string &) = nullptr; - - static std::unordered_map& getPtrLUT(); }; struct ConfigSectionSettings {