From a453e5c19884e716a66abb10175fd351dc243d36 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sun, 16 Jan 2022 01:59:20 +0100 Subject: [PATCH] Reuse the same code to load settings in apps/openmw, apps/launcher, apps/opencs --- apps/launcher/maindialog.cpp | 62 +++++++------------------------ apps/navmeshtool/main.cpp | 19 +--------- apps/opencs/editor.cpp | 11 +++++- apps/opencs/editor.hpp | 3 ++ apps/opencs/model/prefs/state.cpp | 17 +-------- apps/openmw/engine.cpp | 31 +--------------- components/settings/settings.cpp | 32 ++++++++++++---- components/settings/settings.hpp | 12 +++--- 8 files changed, 61 insertions(+), 126 deletions(-) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index d335d7cded..167f6b9c26 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -414,57 +414,23 @@ bool Launcher::MainDialog::setupGameData() bool Launcher::MainDialog::setupGraphicsSettings() { - // This method is almost a copy of OMW::Engine::loadSettings(). They should definitely - // remain consistent, and possibly be merged into a shared component. At the very least - // the filenames should be in the CfgMgr component. - - // Ensure to clear previous settings in case we had already loaded settings. - mEngineSettings.clear(); - - // Create the settings manager and load default settings file - const std::string localDefault = (mCfgMgr.getLocalPath() / "defaults.bin").string(); - const std::string globalDefault = (mCfgMgr.getGlobalPath() / "defaults.bin").string(); - std::string defaultPath; - - // Prefer the defaults.bin in the current directory. - if (boost::filesystem::exists(localDefault)) - defaultPath = localDefault; - else if (boost::filesystem::exists(globalDefault)) - defaultPath = globalDefault; - // Something's very wrong if we can't find the file at all. - else { - cfgError(tr("Error reading OpenMW configuration file"), - tr("
Could not find defaults.bin

\ - The problem may be due to an incomplete installation of OpenMW.
\ - Reinstalling OpenMW may resolve the problem.")); - return false; - } - - // Load the default settings, report any parsing errors. - try { - mEngineSettings.loadDefault(defaultPath); - } - catch (std::exception& e) { - std::string msg = std::string("
Error reading defaults.bin

") + e.what(); - cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str())); - return false; - } - - // Load user settings if they exist - const std::string userPath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string(); - // User settings are not required to exist, so if they don't we're done. - if (!boost::filesystem::exists(userPath)) return true; - - try { - mEngineSettings.loadUser(userPath); + mEngineSettings.clear(); // Ensure to clear previous settings in case we had already loaded settings. + try + { + boost::program_options::variables_map variables; + boost::program_options::options_description desc; + mCfgMgr.addCommonOptions(desc); + mCfgMgr.readConfiguration(variables, desc, true); + mEngineSettings.load(mCfgMgr); + return true; } - catch (std::exception& e) { - std::string msg = std::string("
Error reading settings.cfg

") + e.what(); - cfgError(tr("Error reading OpenMW configuration file"), tr(msg.c_str())); + catch (std::exception& e) + { + cfgError(tr("Error reading OpenMW configuration files"), + tr("
The problem may be due to an incomplete installation of OpenMW.
\ + Reinstalling OpenMW may resolve the problem.
") + e.what()); return false; } - - return true; } void Launcher::MainDialog::loadSettings() diff --git a/apps/navmeshtool/main.cpp b/apps/navmeshtool/main.cpp index ce3cb10b20..f89e80e542 100644 --- a/apps/navmeshtool/main.cpp +++ b/apps/navmeshtool/main.cpp @@ -89,23 +89,6 @@ namespace NavMeshTool return result; } - void loadSettings(const Files::ConfigurationManager& config, Settings::Manager& settings) - { - const std::string localDefault = (config.getLocalPath() / "defaults.bin").string(); - const std::string globalDefault = (config.getGlobalPath() / "defaults.bin").string(); - - if (boost::filesystem::exists(localDefault)) - settings.loadDefault(localDefault); - else if (boost::filesystem::exists(globalDefault)) - settings.loadDefault(globalDefault); - else - throw std::runtime_error("No default settings file found! Make sure the file \"defaults.bin\" was properly installed."); - - const std::string settingsPath = (config.getUserConfigPath() / "settings.cfg").string(); - if (boost::filesystem::exists(settingsPath)) - settings.loadUser(settingsPath); - } - int runNavMeshTool(int argc, char *argv[]) { bpo::options_description desc = makeOptionsDescription(); @@ -166,7 +149,7 @@ namespace NavMeshTool VFS::registerArchives(&vfs, fileCollections, archives, true); Settings::Manager settings; - loadSettings(config, settings); + settings.load(config); const osg::Vec3f agentHalfExtents = Settings::Manager::getVector3("default actor pathfind half extents", "Game"); diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 3db201874a..1d5934fe5d 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -21,7 +21,7 @@ using namespace Fallback; CS::Editor::Editor (int argc, char **argv) -: mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr), +: mConfigVariables(readConfiguration()), mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr), mPid(""), mLock(), mMerge (mDocumentManager), mIpcServerName ("org.openmw.OpenCS"), mServer(nullptr), mClientSocket(nullptr) { @@ -83,7 +83,7 @@ CS::Editor::~Editor () remove(mPid.string().c_str())); // ignore any error } -std::pair > CS::Editor::readConfig(bool quiet) +boost::program_options::variables_map CS::Editor::readConfiguration() { boost::program_options::variables_map variables; boost::program_options::options_description desc("Syntax: openmw-cs \nAllowed options"); @@ -109,6 +109,13 @@ std::pair > CS::Editor::readConfi mCfgMgr.readConfiguration(variables, desc, false); setupLogging(mCfgMgr.getLogPath().string(), "OpenMW-CS"); + return variables; +} + +std::pair > CS::Editor::readConfig(bool quiet) +{ + boost::program_options::variables_map& variables = mConfigVariables; + Fallback::Map::init(variables["fallback"].as().mMap); mEncodingName = variables["encoding"].as(); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 1c93427613..7b258c8049 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -40,6 +40,7 @@ namespace CS Q_OBJECT Files::ConfigurationManager mCfgMgr; + boost::program_options::variables_map mConfigVariables; CSMPrefs::State mSettingsState; CSMDoc::DocumentManager mDocumentManager; CSVDoc::StartupDialogue mStartup; @@ -58,6 +59,8 @@ namespace CS Files::PathContainer mDataDirs; std::string mEncodingName; + boost::program_options::variables_map readConfiguration(); + ///< Calls mCfgMgr.readConfiguration; should be used before initialization of mSettingsState as it depends on the configuration. std::pair > readConfig(bool quiet=false); ///< \return data paths diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 06dc1f4a2e..ee0cbbed5a 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -16,22 +16,7 @@ CSMPrefs::State *CSMPrefs::State::sThis = nullptr; void CSMPrefs::State::load() { - // default settings file - boost::filesystem::path local = mConfigurationManager.getLocalPath() / mDefaultConfigFile; - boost::filesystem::path global = mConfigurationManager.getGlobalPath() / mDefaultConfigFile; - - if (boost::filesystem::exists (local)) - mSettings.loadDefault (local.string()); - else if (boost::filesystem::exists (global)) - mSettings.loadDefault (global.string()); - else - throw std::runtime_error ("No default settings file found! Make sure the file \"" + mDefaultConfigFile + "\" was properly installed."); - - // user settings file - boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile; - - if (boost::filesystem::exists (user)) - mSettings.loadUser (user.string()); + mSettings.load(mConfigurationManager); } void CSMPrefs::State::declare() diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 50053b8b76..cd32cb3b0d 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -518,34 +518,6 @@ void OMW::Engine::setSkipMenu (bool skipMenu, bool newGame) mNewGame = newGame; } -std::string OMW::Engine::loadSettings (Settings::Manager & settings) -{ - const std::vector& paths = mCfgMgr.getActiveConfigPaths(); - if (paths.empty()) - throw std::runtime_error("No config dirs! ConfigurationManager::readConfiguration must be called first."); - - // Create the settings manager and load default settings file. - const std::string defaultsBin = (paths.front() / "defaults.bin").string(); - if (!boost::filesystem::exists(defaultsBin)) - throw std::runtime_error ("No default settings file found! Make sure the file \"defaults.bin\" was properly installed."); - settings.loadDefault(defaultsBin); - - // Load "settings.cfg" from every config dir except the last one as additional default settings. - for (int i = 0; i < static_cast(paths.size()) - 1; ++i) - { - const std::string additionalDefaults = (paths[i] / "settings.cfg").string(); - if (boost::filesystem::exists(additionalDefaults)) - settings.loadDefault(additionalDefaults, true); - } - - // Load "settings.cfg" from the last config as user settings if they exist. This path will be used to save modified settings. - std::string settingspath = (paths.back() / "settings.cfg").string(); - if (boost::filesystem::exists(settingspath)) - settings.loadUser(settingspath); - - return settingspath; -} - void OMW::Engine::createWindow(Settings::Manager& settings) { int screen = settings.getInt("screen", "Video"); @@ -981,8 +953,7 @@ void OMW::Engine::go() // Load settings Settings::Manager settings; - std::string settingspath; - settingspath = loadSettings (settings); + std::string settingspath = settings.load(mCfgMgr); MWClass::registerClasses(); diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp index 09e74b348b..b8ff700492 100644 --- a/components/settings/settings.cpp +++ b/components/settings/settings.cpp @@ -3,6 +3,7 @@ #include +#include #include namespace Settings @@ -19,16 +20,33 @@ void Manager::clear() mChangedSettings.clear(); } -void Manager::loadDefault(const std::string &file, bool overrideExisting) +std::string Manager::load(const Files::ConfigurationManager& cfgMgr) { SettingsFileParser parser; - parser.loadSettingsFile(file, mDefaultSettings, true, overrideExisting); -} + const std::vector& paths = cfgMgr.getActiveConfigPaths(); + if (paths.empty()) + throw std::runtime_error("No config dirs! ConfigurationManager::readConfiguration must be called first."); + + // Create the settings manager and load default settings file. + const std::string defaultsBin = (paths.front() / "defaults.bin").string(); + if (!boost::filesystem::exists(defaultsBin)) + throw std::runtime_error ("No default settings file found! Make sure the file \"defaults.bin\" was properly installed."); + parser.loadSettingsFile(defaultsBin, mDefaultSettings, true, false); + + // Load "settings.cfg" from every config dir except the last one as additional default settings. + for (int i = 0; i < static_cast(paths.size()) - 1; ++i) + { + const std::string additionalDefaults = (paths[i] / "settings.cfg").string(); + if (boost::filesystem::exists(additionalDefaults)) + parser.loadSettingsFile(additionalDefaults, mDefaultSettings, false, true); + } -void Manager::loadUser(const std::string &file) -{ - SettingsFileParser parser; - parser.loadSettingsFile(file, mUserSettings); + // Load "settings.cfg" from the last config as user settings if they exist. This path will be used to save modified settings. + std::string settingspath = (paths.back() / "settings.cfg").string(); + if (boost::filesystem::exists(settingspath)) + parser.loadSettingsFile(settingspath, mUserSettings, false, false); + + return settingspath; } void Manager::saveUser(const std::string &file) diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index 84e7066fbd..04831ef171 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -9,6 +9,11 @@ #include #include +namespace Files +{ + struct ConfigurationManager; +} + namespace Settings { /// @@ -26,11 +31,8 @@ namespace Settings void clear(); ///< clears all settings and default settings - void loadDefault (const std::string& file, bool overrideExisting = false); - ///< load file as the default settings (can be overridden by user settings) - - void loadUser (const std::string& file); - ///< load file as user settings + std::string load(const Files::ConfigurationManager& cfgMgr); + ///< load settings from all active config dirs. Returns the path of the last loaded file. void saveUser (const std::string& file); ///< save user settings to file