Host: Get rid of base settings interface indirection

This commit is contained in:
Stenzek 2025-06-05 20:36:31 +10:00
parent 9cd371d5ff
commit d0b7d9d027
No known key found for this signature in database
5 changed files with 83 additions and 70 deletions

View File

@ -97,7 +97,7 @@ static void SavePlatformWindowGeometry(s32 x, s32 y, s32 width, s32 height);
struct SDLHostState struct SDLHostState
{ {
// UI thread state // UI thread state
ALIGN_TO_CACHE_LINE std::unique_ptr<INISettingsInterface> base_settings_interface; ALIGN_TO_CACHE_LINE INISettingsInterface base_settings_interface;
bool batch_mode = false; bool batch_mode = false;
bool start_fullscreen_ui_fullscreen = false; bool start_fullscreen_ui_fullscreen = false;
bool was_paused_by_focus_loss = false; bool was_paused_by_focus_loss = false;
@ -265,44 +265,44 @@ bool MiniHost::InitializeConfig()
std::string settings_path = Path::Combine(EmuFolders::DataRoot, "settings.ini"); std::string settings_path = Path::Combine(EmuFolders::DataRoot, "settings.ini");
const bool settings_exists = FileSystem::FileExists(settings_path.c_str()); const bool settings_exists = FileSystem::FileExists(settings_path.c_str());
INFO_LOG("Loading config from {}.", settings_path); INFO_LOG("Loading config from {}.", settings_path);
s_state.base_settings_interface = std::make_unique<INISettingsInterface>(std::move(settings_path)); s_state.base_settings_interface.SetPath(std::move(settings_path));
Host::Internal::SetBaseSettingsLayer(s_state.base_settings_interface.get()); Host::Internal::SetBaseSettingsLayer(&s_state.base_settings_interface);
u32 settings_version; u32 settings_version;
if (!settings_exists || !s_state.base_settings_interface->Load() || if (!settings_exists || !s_state.base_settings_interface.Load() ||
!s_state.base_settings_interface->GetUIntValue("Main", "SettingsVersion", &settings_version) || !s_state.base_settings_interface.GetUIntValue("Main", "SettingsVersion", &settings_version) ||
settings_version != SETTINGS_VERSION) settings_version != SETTINGS_VERSION)
{ {
if (s_state.base_settings_interface->ContainsValue("Main", "SettingsVersion")) if (s_state.base_settings_interface.ContainsValue("Main", "SettingsVersion"))
{ {
// NOTE: No point translating this, because there's no config loaded, so no language loaded. // NOTE: No point translating this, because there's no config loaded, so no language loaded.
Host::ReportErrorAsync("Error", fmt::format("Settings version {} does not match expected version {}, resetting.", Host::ReportErrorAsync("Error", fmt::format("Settings version {} does not match expected version {}, resetting.",
settings_version, SETTINGS_VERSION)); settings_version, SETTINGS_VERSION));
} }
s_state.base_settings_interface->SetUIntValue("Main", "SettingsVersion", SETTINGS_VERSION); s_state.base_settings_interface.SetUIntValue("Main", "SettingsVersion", SETTINGS_VERSION);
SetDefaultSettings(*s_state.base_settings_interface, true, true); SetDefaultSettings(s_state.base_settings_interface, true, true);
// Make sure we can actually save the config, and the user doesn't have some permission issue. // Make sure we can actually save the config, and the user doesn't have some permission issue.
Error error; Error error;
if (!s_state.base_settings_interface->Save(&error)) if (!s_state.base_settings_interface.Save(&error))
{ {
Host::ReportFatalError( Host::ReportFatalError(
"Error", "Error",
fmt::format( fmt::format(
"Failed to save configuration to\n\n{}\n\nThe error was: {}\n\nPlease ensure this directory is writable. You " "Failed to save configuration to\n\n{}\n\nThe error was: {}\n\nPlease ensure this directory is writable. You "
"can also try portable mode by creating portable.txt in the same directory you installed DuckStation into.", "can also try portable mode by creating portable.txt in the same directory you installed DuckStation into.",
s_state.base_settings_interface->GetPath(), error.GetDescription())); s_state.base_settings_interface.GetPath(), error.GetDescription()));
return false; return false;
} }
} }
EmuFolders::LoadConfig(*s_state.base_settings_interface.get()); EmuFolders::LoadConfig(s_state.base_settings_interface);
EmuFolders::EnsureFoldersExist(); EmuFolders::EnsureFoldersExist();
// We need to create the console window early, otherwise it appears in front of the main window. // We need to create the console window early, otherwise it appears in front of the main window.
if (!Log::IsConsoleOutputEnabled() && s_state.base_settings_interface->GetBoolValue("Logging", "LogToConsole", false)) if (!Log::IsConsoleOutputEnabled() && s_state.base_settings_interface.GetBoolValue("Logging", "LogToConsole", false))
Log::SetConsoleOutputParams(true, s_state.base_settings_interface->GetBoolValue("Logging", "LogTimestamps", true)); Log::SetConsoleOutputParams(true, s_state.base_settings_interface.GetBoolValue("Logging", "LogTimestamps", true));
// imgui setup, make sure it doesn't bug out // imgui setup, make sure it doesn't bug out
ImGuiManager::SetFontPathAndRange(std::string(), {0x0020, 0x00FF, 0x2022, 0x2022, 0, 0}); ImGuiManager::SetFontPathAndRange(std::string(), {0x0020, 0x00FF, 0x2022, 0x2022, 0, 0});
@ -444,7 +444,7 @@ void Host::CommitBaseSettingChanges()
{ {
auto lock = Host::GetSettingsLock(); auto lock = Host::GetSettingsLock();
Error error; Error error;
if (!MiniHost::s_state.base_settings_interface->Save(&error)) if (!MiniHost::s_state.base_settings_interface.Save(&error))
ERROR_LOG("Failed to save settings: {}", error.GetDescription()); ERROR_LOG("Failed to save settings: {}", error.GetDescription());
} }
@ -730,12 +730,12 @@ void Host::DestroyAuxiliaryRenderWindow(AuxiliaryRenderWindowHandle handle, s32*
bool MiniHost::GetSavedPlatformWindowGeometry(s32* x, s32* y, s32* width, s32* height) bool MiniHost::GetSavedPlatformWindowGeometry(s32* x, s32* y, s32* width, s32* height)
{ {
auto lock = Host::GetSettingsLock(); const auto lock = Host::GetSettingsLock();
bool result = s_state.base_settings_interface->GetIntValue("SimpleHost", "WindowX", x); bool result = s_state.base_settings_interface.GetIntValue("SimpleHost", "WindowX", x);
result = result && s_state.base_settings_interface->GetIntValue("SimpleHost", "WindowY", y); result = result && s_state.base_settings_interface.GetIntValue("SimpleHost", "WindowY", y);
result = result && s_state.base_settings_interface->GetIntValue("SimpleHost", "WindowWidth", width); result = result && s_state.base_settings_interface.GetIntValue("SimpleHost", "WindowWidth", width);
result = result && s_state.base_settings_interface->GetIntValue("SimpleHost", "WindowHeight", height); result = result && s_state.base_settings_interface.GetIntValue("SimpleHost", "WindowHeight", height);
return result; return result;
} }
@ -744,12 +744,11 @@ void MiniHost::SavePlatformWindowGeometry(s32 x, s32 y, s32 width, s32 height)
if (Host::IsFullscreen()) if (Host::IsFullscreen())
return; return;
auto lock = Host::GetSettingsLock(); const auto lock = Host::GetSettingsLock();
s_state.base_settings_interface->SetIntValue("SimpleHost", "WindowX", x); s_state.base_settings_interface.SetIntValue("SimpleHost", "WindowX", x);
s_state.base_settings_interface->SetIntValue("SimpleHost", "WindowY", y); s_state.base_settings_interface.SetIntValue("SimpleHost", "WindowY", y);
s_state.base_settings_interface->SetIntValue("SimpleHost", "WindowWidth", width); s_state.base_settings_interface.SetIntValue("SimpleHost", "WindowWidth", width);
s_state.base_settings_interface->SetIntValue("SimpleHost", "WindowHeight", height); s_state.base_settings_interface.SetIntValue("SimpleHost", "WindowHeight", height);
s_state.base_settings_interface->Save();
} }
void MiniHost::UIThreadMainLoop() void MiniHost::UIThreadMainLoop()
@ -1275,7 +1274,7 @@ void Host::RequestResetSettings(bool system, bool controller)
auto lock = Host::GetSettingsLock(); auto lock = Host::GetSettingsLock();
{ {
SettingsInterface& si = *s_state.base_settings_interface.get(); SettingsInterface& si = s_state.base_settings_interface;
if (system) if (system)
{ {
@ -1846,7 +1845,8 @@ int main(int argc, char* argv[])
// Ensure log is flushed. // Ensure log is flushed.
Log::SetFileOutputParams(false, nullptr); Log::SetFileOutputParams(false, nullptr);
s_state.base_settings_interface.reset(); if (s_state.base_settings_interface.IsDirty())
s_state.base_settings_interface.Save();
SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_EVENTS); SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_EVENTS);

View File

@ -115,7 +115,7 @@ static bool ParseCommandLineParametersAndInitializeConfig(QApplication& app,
std::shared_ptr<SystemBootParameters>& boot_params); std::shared_ptr<SystemBootParameters>& boot_params);
} // namespace QtHost } // namespace QtHost
static std::unique_ptr<INISettingsInterface> s_base_settings_interface; static INISettingsInterface s_base_settings_interface;
static std::unique_ptr<QTimer> s_settings_save_timer; static std::unique_ptr<QTimer> s_settings_save_timer;
static bool s_batch_mode = false; static bool s_batch_mode = false;
static bool s_nogui_mode = false; static bool s_nogui_mode = false;
@ -255,7 +255,7 @@ QString QtHost::GetResourcesBasePath()
INISettingsInterface* QtHost::GetBaseSettingsInterface() INISettingsInterface* QtHost::GetBaseSettingsInterface()
{ {
return s_base_settings_interface.get(); return &s_base_settings_interface;
} }
bool QtHost::SaveGameSettings(SettingsInterface* sif, bool delete_if_empty) bool QtHost::SaveGameSettings(SettingsInterface* sif, bool delete_if_empty)
@ -482,37 +482,37 @@ bool QtHost::InitializeConfig()
std::string settings_path = Path::Combine(EmuFolders::DataRoot, "settings.ini"); std::string settings_path = Path::Combine(EmuFolders::DataRoot, "settings.ini");
const bool settings_exists = FileSystem::FileExists(settings_path.c_str()); const bool settings_exists = FileSystem::FileExists(settings_path.c_str());
INFO_LOG("Loading config from {}.", settings_path); INFO_LOG("Loading config from {}.", settings_path);
s_base_settings_interface = std::make_unique<INISettingsInterface>(std::move(settings_path)); s_base_settings_interface.SetPath(std::move(settings_path));
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get()); Host::Internal::SetBaseSettingsLayer(&s_base_settings_interface);
uint settings_version; uint settings_version;
if (!settings_exists || !s_base_settings_interface->Load() || if (!settings_exists || !s_base_settings_interface.Load() ||
!s_base_settings_interface->GetUIntValue("Main", "SettingsVersion", &settings_version) || !s_base_settings_interface.GetUIntValue("Main", "SettingsVersion", &settings_version) ||
settings_version != SETTINGS_VERSION) settings_version != SETTINGS_VERSION)
{ {
if (s_base_settings_interface->ContainsValue("Main", "SettingsVersion")) if (s_base_settings_interface.ContainsValue("Main", "SettingsVersion"))
{ {
// NOTE: No point translating this, because there's no config loaded, so no language loaded. // NOTE: No point translating this, because there's no config loaded, so no language loaded.
Host::ReportErrorAsync("Error", fmt::format("Settings version {} does not match expected version {}, resetting.", Host::ReportErrorAsync("Error", fmt::format("Settings version {} does not match expected version {}, resetting.",
settings_version, SETTINGS_VERSION)); settings_version, SETTINGS_VERSION));
} }
s_base_settings_interface->SetUIntValue("Main", "SettingsVersion", SETTINGS_VERSION); s_base_settings_interface.SetUIntValue("Main", "SettingsVersion", SETTINGS_VERSION);
SetDefaultSettings(*s_base_settings_interface, true, true); SetDefaultSettings(s_base_settings_interface, true, true);
// Flag for running the setup wizard if this is our first run. We want to run it next time if they don't finish it. // Flag for running the setup wizard if this is our first run. We want to run it next time if they don't finish it.
s_base_settings_interface->SetBoolValue("Main", "SetupWizardIncomplete", true); s_base_settings_interface.SetBoolValue("Main", "SetupWizardIncomplete", true);
// Make sure we can actually save the config, and the user doesn't have some permission issue. // Make sure we can actually save the config, and the user doesn't have some permission issue.
Error error; Error error;
if (!s_base_settings_interface->Save(&error)) if (!s_base_settings_interface.Save(&error))
{ {
QMessageBox::critical( QMessageBox::critical(
nullptr, QStringLiteral("DuckStation"), nullptr, QStringLiteral("DuckStation"),
QStringLiteral( QStringLiteral(
"Failed to save configuration to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You " "Failed to save configuration to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You "
"can also try portable mode by creating portable.txt in the same directory you installed DuckStation into.") "can also try portable mode by creating portable.txt in the same directory you installed DuckStation into.")
.arg(QString::fromStdString(s_base_settings_interface->GetPath())) .arg(QString::fromStdString(s_base_settings_interface.GetPath()))
.arg(QString::fromStdString(error.GetDescription()))); .arg(QString::fromStdString(error.GetDescription())));
return false; return false;
} }
@ -520,15 +520,15 @@ bool QtHost::InitializeConfig()
// Setup wizard was incomplete last time? // Setup wizard was incomplete last time?
s_run_setup_wizard = s_run_setup_wizard =
s_run_setup_wizard || s_base_settings_interface->GetBoolValue("Main", "SetupWizardIncomplete", false); s_run_setup_wizard || s_base_settings_interface.GetBoolValue("Main", "SetupWizardIncomplete", false);
EmuFolders::LoadConfig(*s_base_settings_interface.get()); EmuFolders::LoadConfig(s_base_settings_interface);
EmuFolders::EnsureFoldersExist(); EmuFolders::EnsureFoldersExist();
MigrateSettings(); MigrateSettings();
// We need to create the console window early, otherwise it appears in front of the main window. // We need to create the console window early, otherwise it appears in front of the main window.
if (!Log::IsConsoleOutputEnabled() && s_base_settings_interface->GetBoolValue("Logging", "LogToConsole", false)) if (!Log::IsConsoleOutputEnabled() && s_base_settings_interface.GetBoolValue("Logging", "LogToConsole", false))
Log::SetConsoleOutputParams(true, s_base_settings_interface->GetBoolValue("Logging", "LogTimestamps", true)); Log::SetConsoleOutputParams(true, s_base_settings_interface.GetBoolValue("Logging", "LogTimestamps", true));
UpdateApplicationLanguage(nullptr); UpdateApplicationLanguage(nullptr);
return true; return true;
@ -645,7 +645,7 @@ void EmuThread::setDefaultSettings(bool system /* = true */, bool controller /*
{ {
auto lock = Host::GetSettingsLock(); auto lock = Host::GetSettingsLock();
QtHost::SetDefaultSettings(*s_base_settings_interface, system, controller); QtHost::SetDefaultSettings(s_base_settings_interface, system, controller);
QtHost::QueueSettingsSave(); QtHost::QueueSettingsSave();
} }
@ -675,15 +675,15 @@ void QtHost::SetDefaultSettings(SettingsInterface& si, bool system, bool control
void QtHost::MigrateSettings() void QtHost::MigrateSettings()
{ {
SmallString value; SmallString value;
if (s_base_settings_interface->GetStringValue("Display", "SyncMode", &value)) if (s_base_settings_interface.GetStringValue("Display", "SyncMode", &value))
{ {
s_base_settings_interface->SetBoolValue("Display", "VSync", (value == "VSync" || value == "VSyncRelaxed")); s_base_settings_interface.SetBoolValue("Display", "VSync", (value == "VSync" || value == "VSyncRelaxed"));
s_base_settings_interface->SetBoolValue( s_base_settings_interface.SetBoolValue(
"Display", "OptimalFramePacing", "Display", "OptimalFramePacing",
(value == "VRR" || s_base_settings_interface->GetBoolValue("Display", "DisplayAllFrames", false))); (value == "VRR" || s_base_settings_interface.GetBoolValue("Display", "DisplayAllFrames", false)));
s_base_settings_interface->DeleteValue("Display", "SyncMode"); s_base_settings_interface.DeleteValue("Display", "SyncMode");
s_base_settings_interface->DeleteValue("Display", "DisplayAllFrames"); s_base_settings_interface.DeleteValue("Display", "DisplayAllFrames");
s_base_settings_interface->Save(); s_base_settings_interface.Save();
} }
} }
@ -2553,7 +2553,7 @@ void QtHost::SaveSettings()
{ {
Error error; Error error;
auto lock = Host::GetSettingsLock(); auto lock = Host::GetSettingsLock();
if (!s_base_settings_interface->Save(&error)) if (!s_base_settings_interface.Save(&error))
ERROR_LOG("Failed to save settings: {}", error.GetDescription()); ERROR_LOG("Failed to save settings: {}", error.GetDescription());
} }

View File

@ -70,7 +70,7 @@ static RegTestHostState s_state;
} // namespace RegTestHost } // namespace RegTestHost
static std::unique_ptr<MemorySettingsInterface> s_base_settings_interface; static MemorySettingsInterface s_base_settings_interface;
static Threading::Thread s_gpu_thread; static Threading::Thread s_gpu_thread;
static u32 s_frames_to_run = 60 * 60; static u32 s_frames_to_run = 60 * 60;
@ -114,11 +114,10 @@ bool RegTestHost::InitializeConfig()
{ {
SetFolders(); SetFolders();
s_base_settings_interface = std::make_unique<MemorySettingsInterface>(); Host::Internal::SetBaseSettingsLayer(&s_base_settings_interface);
Host::Internal::SetBaseSettingsLayer(s_base_settings_interface.get());
// default settings for runner // default settings for runner
SettingsInterface& si = *s_base_settings_interface.get(); SettingsInterface& si = s_base_settings_interface;
g_settings.Load(si, si); g_settings.Load(si, si);
g_settings.Save(si, false); g_settings.Save(si, false);
si.SetStringValue("GPU", "Renderer", Settings::GetRendererName(GPURenderer::Software)); si.SetStringValue("GPU", "Renderer", Settings::GetRendererName(GPURenderer::Software));
@ -140,7 +139,7 @@ bool RegTestHost::InitializeConfig()
for (u32 i = 0; i < static_cast<u32>(InputSourceType::Count); i++) for (u32 i = 0; i < static_cast<u32>(InputSourceType::Count); i++)
si.SetBoolValue("InputSources", InputManager::InputSourceToString(static_cast<InputSourceType>(i)), false); si.SetBoolValue("InputSources", InputManager::InputSourceToString(static_cast<InputSourceType>(i)), false);
EmuFolders::LoadConfig(*s_base_settings_interface.get()); EmuFolders::LoadConfig(s_base_settings_interface);
EmuFolders::EnsureFoldersExist(); EmuFolders::EnsureFoldersExist();
return true; return true;
@ -846,13 +845,13 @@ bool RegTestHost::ParseCommandLineParameters(int argc, char* argv[], std::option
} }
Log::SetLogLevel(level.value()); Log::SetLogLevel(level.value());
s_base_settings_interface->SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(level.value())); s_base_settings_interface.SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(level.value()));
continue; continue;
} }
else if (CHECK_ARG("-console")) else if (CHECK_ARG("-console"))
{ {
Log::SetConsoleOutputParams(true); Log::SetConsoleOutputParams(true);
s_base_settings_interface->SetBoolValue("Logging", "LogToConsole", true); s_base_settings_interface.SetBoolValue("Logging", "LogToConsole", true);
continue; continue;
} }
else if (CHECK_ARG_PARAM("-renderer")) else if (CHECK_ARG_PARAM("-renderer"))
@ -864,7 +863,7 @@ bool RegTestHost::ParseCommandLineParameters(int argc, char* argv[], std::option
return false; return false;
} }
s_base_settings_interface->SetStringValue("GPU", "Renderer", Settings::GetRendererName(renderer.value())); s_base_settings_interface.SetStringValue("GPU", "Renderer", Settings::GetRendererName(renderer.value()));
continue; continue;
} }
else if (CHECK_ARG_PARAM("-upscale")) else if (CHECK_ARG_PARAM("-upscale"))
@ -877,7 +876,7 @@ bool RegTestHost::ParseCommandLineParameters(int argc, char* argv[], std::option
} }
INFO_LOG("Setting upscale to {}.", upscale); INFO_LOG("Setting upscale to {}.", upscale);
s_base_settings_interface->SetIntValue("GPU", "ResolutionScale", static_cast<s32>(upscale)); s_base_settings_interface.SetIntValue("GPU", "ResolutionScale", static_cast<s32>(upscale));
continue; continue;
} }
else if (CHECK_ARG_PARAM("-cpu")) else if (CHECK_ARG_PARAM("-cpu"))
@ -890,21 +889,21 @@ bool RegTestHost::ParseCommandLineParameters(int argc, char* argv[], std::option
} }
INFO_LOG("Setting CPU execution mode to {}.", Settings::GetCPUExecutionModeName(cpu.value())); INFO_LOG("Setting CPU execution mode to {}.", Settings::GetCPUExecutionModeName(cpu.value()));
s_base_settings_interface->SetStringValue("CPU", "ExecutionMode", s_base_settings_interface.SetStringValue("CPU", "ExecutionMode",
Settings::GetCPUExecutionModeName(cpu.value())); Settings::GetCPUExecutionModeName(cpu.value()));
continue; continue;
} }
else if (CHECK_ARG("-pgxp")) else if (CHECK_ARG("-pgxp"))
{ {
INFO_LOG("Enabling PGXP."); INFO_LOG("Enabling PGXP.");
s_base_settings_interface->SetBoolValue("GPU", "PGXPEnable", true); s_base_settings_interface.SetBoolValue("GPU", "PGXPEnable", true);
continue; continue;
} }
else if (CHECK_ARG("-pgxp-cpu")) else if (CHECK_ARG("-pgxp-cpu"))
{ {
INFO_LOG("Enabling PGXP CPU mode."); INFO_LOG("Enabling PGXP CPU mode.");
s_base_settings_interface->SetBoolValue("GPU", "PGXPEnable", true); s_base_settings_interface.SetBoolValue("GPU", "PGXPEnable", true);
s_base_settings_interface->SetBoolValue("GPU", "PGXPCPU", true); s_base_settings_interface.SetBoolValue("GPU", "PGXPCPU", true);
continue; continue;
} }
else if (CHECK_ARG("--")) else if (CHECK_ARG("--"))
@ -948,9 +947,9 @@ bool RegTestHost::SetNewDataRoot(const std::string& filename)
// Switch to file logging. // Switch to file logging.
INFO_LOG("Dumping frames to '{}'...", dump_directory); INFO_LOG("Dumping frames to '{}'...", dump_directory);
EmuFolders::DataRoot = std::move(dump_directory); EmuFolders::DataRoot = std::move(dump_directory);
s_base_settings_interface->SetBoolValue("Logging", "LogToFile", true); s_base_settings_interface.SetBoolValue("Logging", "LogToFile", true);
s_base_settings_interface->SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Log::Level::Dev)); s_base_settings_interface.SetStringValue("Logging", "LogLevel", Settings::GetLogLevelName(Log::Level::Dev));
Settings::UpdateLogConfig(*s_base_settings_interface); Settings::UpdateLogConfig(s_base_settings_interface);
} }
return true; return true;

View File

@ -19,7 +19,11 @@ LOG_CHANNEL(Settings);
// we only allow one ini to be parsed at any point in time. // we only allow one ini to be parsed at any point in time.
static std::mutex s_ini_load_save_mutex; static std::mutex s_ini_load_save_mutex;
INISettingsInterface::INISettingsInterface(std::string filename) : m_path(std::move(filename)), m_ini(true, true) INISettingsInterface::INISettingsInterface() : m_ini(true, true)
{
}
INISettingsInterface::INISettingsInterface(std::string path) : m_path(std::move(path)), m_ini(true, true)
{ {
} }
@ -29,6 +33,12 @@ INISettingsInterface::~INISettingsInterface()
Save(); Save();
} }
void INISettingsInterface::SetPath(std::string path)
{
m_dirty |= (path != m_path);
m_path = std::move(path);
}
bool INISettingsInterface::Load(Error* error /* = nullptr */) bool INISettingsInterface::Load(Error* error /* = nullptr */)
{ {
if (m_path.empty()) if (m_path.empty())
@ -47,6 +57,7 @@ bool INISettingsInterface::Load(Error* error /* = nullptr */)
Error::SetStringFmt(error, "INI LoadFile() failed: {}", static_cast<int>(err)); Error::SetStringFmt(error, "INI LoadFile() failed: {}", static_cast<int>(err));
} }
m_dirty = false;
return (err == SI_OK); return (err == SI_OK);
} }

View File

@ -13,10 +13,13 @@
class INISettingsInterface final : public SettingsInterface class INISettingsInterface final : public SettingsInterface
{ {
public: public:
INISettingsInterface();
INISettingsInterface(std::string path); INISettingsInterface(std::string path);
~INISettingsInterface() override; ~INISettingsInterface() override;
const std::string& GetPath() const { return m_path; } ALWAYS_INLINE bool IsDirty() const { return m_dirty; }
ALWAYS_INLINE const std::string& GetPath() const { return m_path; }
void SetPath(std::string path);
bool Load(Error* error = nullptr); bool Load(Error* error = nullptr);
bool Load(std::string new_path, Error* error = nullptr); bool Load(std::string new_path, Error* error = nullptr);