From ea7eb7a62df0aaea761eab88f9e2f615bd9290e5 Mon Sep 17 00:00:00 2001 From: Lukasz Gromanowski Date: Fri, 19 Aug 2011 21:06:09 +0200 Subject: [PATCH] fixes #128 Configuration cleanup. Signed-off-by: Lukasz Gromanowski --- .gitignore | 3 + CMakeLists.txt | 31 +++- apps/launcher/CMakeLists.txt | 1 + apps/launcher/datafilespage.cpp | 9 +- apps/launcher/graphicspage.cpp | 16 +- apps/launcher/graphicspage.hpp | 2 + apps/launcher/maindialog.cpp | 9 +- apps/openmw/engine.cpp | 66 ++++--- apps/openmw/engine.hpp | 43 +++-- apps/openmw/main.cpp | 186 +++++++++---------- components/cfg/configurationmanager.cpp | 118 ++++++++++++ components/cfg/configurationmanager.hpp | 54 ++++++ components/files/collections.cpp | 26 +-- components/files/collections.hpp | 20 ++- components/files/fileops.cpp | 12 ++ components/files/fileops.hpp | 13 ++ components/files/linuxpath.cpp | 159 ++++++++++++++++ components/files/linuxpath.hpp | 90 ++++++++++ components/files/macospath.cpp | 118 ++++++++++++ components/files/macospath.hpp | 90 ++++++++++ components/files/path.cpp | 61 ------- components/files/path.hpp | 229 +++++++++++++++++++++++- components/files/windowspath.cpp | 72 ++++++++ components/files/windowspath.hpp | 90 ++++++++++ components/misc/fileops.cpp | 16 -- components/misc/fileops.hpp | 18 -- 26 files changed, 1266 insertions(+), 286 deletions(-) create mode 100644 components/cfg/configurationmanager.cpp create mode 100644 components/cfg/configurationmanager.hpp create mode 100644 components/files/fileops.cpp create mode 100644 components/files/fileops.hpp create mode 100644 components/files/linuxpath.cpp create mode 100644 components/files/linuxpath.hpp create mode 100644 components/files/macospath.cpp create mode 100644 components/files/macospath.hpp delete mode 100644 components/files/path.cpp create mode 100644 components/files/windowspath.cpp create mode 100644 components/files/windowspath.hpp delete mode 100644 components/misc/fileops.cpp delete mode 100644 components/misc/fileops.hpp diff --git a/.gitignore b/.gitignore index b17b5a584..ada874bb2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ Doxygen prebuilt apps/openmw/config.hpp Docs/mainpage.hpp +CMakeFiles +*/CMakeFiles +CMakeCache.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 91d3f7dd3..f4be17e90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,6 +90,14 @@ set(BSA_HEADER ${COMP_DIR}/bsa/bsa_file.hpp) source_group(components\\bsa FILES ${BSA} ${BSA_HEADER}) +set(CFG + ${COMP_DIR}/cfg/configurationmanager.cpp + ) +set(CFG_HEADER + ${COMP_DIR}/cfg/configurationmanager.hpp + ) +source_group(components\\cfg FILES ${CFG} ${CFG_HEADER}) + set(NIF ${COMP_DIR}/nif/nif_file.cpp) set(NIF_HEADER @@ -189,22 +197,29 @@ source_group(components\\esm FILES ${ESM_HEADER} ${ESM}) set(MISC ${COMP_DIR}/misc/stringops.cpp - ${COMP_DIR}/misc/fileops.cpp) + ) set(MISC_HEADER - ${COMP_DIR}/misc/fileops.hpp ${COMP_DIR}/misc/slice_array.hpp - ${COMP_DIR}/misc/stringops.hpp) + ${COMP_DIR}/misc/stringops.hpp + ) source_group(components\\misc FILES ${MISC} ${MISC_HEADER}) set(FILES - ${COMP_DIR}/files/path.cpp + ${COMP_DIR}/files/linuxpath.cpp + ${COMP_DIR}/files/windowspath.cpp + ${COMP_DIR}/files/macospath.cpp ${COMP_DIR}/files/multidircollection.cpp ${COMP_DIR}/files/collections.cpp + ${COMP_DIR}/files/fileops.cpp ) set(FILES_HEADER + ${COMP_DIR}/files/linuxpath.hpp + ${COMP_DIR}/files/windowspath.hpp + ${COMP_DIR}/files/macospath.hpp ${COMP_DIR}/files/path.hpp ${COMP_DIR}/files/multidircollection.hpp ${COMP_DIR}/files/collections.hpp + ${COMP_DIR}/files/fileops.hpp ) source_group(components\\files FILES ${FILES} ${FILES_HEADER}) @@ -217,10 +232,14 @@ file(GLOB INTERPRETER_HEADER ${COMP_DIR}/interpreter/*.hpp) source_group(components\\interpreter FILES ${INTERPRETER} ${INTERPRETER_HEADER}) set(COMPONENTS ${BSA} ${NIF} ${NIFOGRE} ${ESM_STORE} ${MISC} ${TO_UTF8} - ${COMPILER} ${INTERPRETER} ${ESM} ${FILE_FINDER} ${NIFBULLET} ${FILES}) + ${COMPILER} ${INTERPRETER} ${ESM} ${FILE_FINDER} ${NIFBULLET} ${FILES} + ${CFG} + ) set(COMPONENTS_HEADER ${BSA_HEADER} ${NIF_HEADER} ${NIFOGRE_HEADER} ${ESM_STORE_HEADER} ${ESM_HEADER} ${MISC_HEADER} ${COMPILER_HEADER} ${TO_UTF8_HEADER} - ${INTERPRETER_HEADER} ${FILE_FINDER_HEADER} ${NIFBULLET_HEADER} ${FILES_HEADER}) + ${INTERPRETER_HEADER} ${FILE_FINDER_HEADER} ${NIFBULLET_HEADER} ${FILES_HEADER} + ${CFG_HEADER} + ) # source directory: libs diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 5090c167d..38a894866 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable(omwlauncher ${LAUNCHER} ${MISC} ${MISC_HEADER} ${FILES} ${FILES_HEADER} + ${CFG} ${CFG_HEADER} ${TO_UTF8} ${ESM} ${RCC_SRCS} diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 2e8cdfbd2..2abe0aed4 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -1,9 +1,9 @@ #include #include -#include #include #include +#include #include "datafilespage.hpp" #include "lineedit.hpp" @@ -211,12 +211,13 @@ void DataFilesPage::setupDataFiles(const QStringList &paths, bool strict) void DataFilesPage::setupConfig() { - QString config = "./launcher.cfg"; + Cfg::ConfigurationManager cfg; + + QString config = (cfg.getRuntimeConfigPath() / "launcher.cfg").string().c_str(); QFile file(config); if (!file.exists()) { - config = QString::fromStdString(Files::getPath(Files::Path_ConfigUser, - "openmw", "launcher.cfg")); + config = QString::fromStdString((cfg.getLocalConfigPath() / "launcher.cfg").string()); } file.setFileName(config); // Just for displaying information diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index d97a915c9..622b00ef5 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -1,7 +1,5 @@ #include -#include - #include "graphicspage.hpp" GraphicsPage::GraphicsPage(QWidget *parent) : QWidget(parent) @@ -149,13 +147,11 @@ void GraphicsPage::createPages() void GraphicsPage::setupConfig() { - QString ogreCfg = "./ogre.cfg"; - + QString ogreCfg = (mCfg.getRuntimeConfigPath() / "ogre.cfg").string().c_str(); QFile file(ogreCfg); if (!file.exists()) { - ogreCfg = QString::fromStdString(Files::getPath(Files::Path_ConfigUser, - "openmw", "ogre.cfg")); + ogreCfg = QString::fromStdString((mCfg.getLocalConfigPath() / "ogre.cfg").string()); } mOgreConfig = new QSettings(ogreCfg, QSettings::IniFormat); @@ -164,12 +160,11 @@ void GraphicsPage::setupConfig() void GraphicsPage::setupOgre() { - QString pluginCfg = "./plugins.cfg"; + QString pluginCfg = (mCfg.getRuntimeConfigPath() / "plugins.cfg").string().c_str(); QFile file(pluginCfg); if (!file.exists()) { - pluginCfg = QString::fromStdString(Files::getPath(Files::Path_ConfigUser, - "openmw", "plugins.cfg")); + pluginCfg = QString::fromStdString((mCfg.getLocalConfigPath() / "plugins.cfg").string()); } // Reopen the file from user directory @@ -177,8 +172,7 @@ void GraphicsPage::setupOgre() if (!file.exists()) { // There's no plugins.cfg in the user directory, use global directory - pluginCfg = QString::fromStdString(Files::getPath(Files::Path_ConfigGlobal, - "openmw", "plugins.cfg")); + pluginCfg = QString::fromStdString((mCfg.getGlobalConfigPath() / "plugins.cfg").string()); } // Create a log manager so we can surpress debug text to stdout/stderr diff --git a/apps/launcher/graphicspage.hpp b/apps/launcher/graphicspage.hpp index 49ed92ac0..5d50cfc61 100644 --- a/apps/launcher/graphicspage.hpp +++ b/apps/launcher/graphicspage.hpp @@ -7,6 +7,7 @@ #include #include #include +#include class QComboBox; class QCheckBox; @@ -28,6 +29,7 @@ public slots: void rendererChanged(const QString &renderer); private: + Cfg::ConfigurationManager mCfg; Ogre::Root *mOgre; Ogre::RenderSystem *mSelectedRenderSystem; Ogre::RenderSystem *mOpenGLRenderSystem; diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index f51b3b549..b125bf13b 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,7 +1,5 @@ #include -#include - #include "maindialog.hpp" #include "playpage.hpp" #include "graphicspage.hpp" @@ -268,13 +266,14 @@ void MainDialog::play() void MainDialog::setupConfig() { + Cfg::ConfigurationManager cfg; + // First we read the OpenMW config - QString config = "./openmw.cfg"; + QString config = (cfg.getRuntimeConfigPath() / "openmw.cfg").string().c_str(); QFile file(config); if (!file.exists()) { - config = QString::fromStdString(Files::getPath(Files::Path_ConfigUser, - "openmw", "openmw.cfg")); + config = QString::fromStdString((cfg.getLocalConfigPath() / "openmw.cfg").string()); } file.close(); diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index d70631cf8..4854eae91 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -11,7 +11,7 @@ #include "components/esm/records.hpp" #include -#include +#include #include #include #include @@ -209,7 +209,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) return true; } -OMW::Engine::Engine() +OMW::Engine::Engine(Cfg::ConfigurationManager& configurationManager) : mPhysicEngine (0) , mShowFPS (false) , mDebug (false) @@ -221,6 +221,7 @@ OMW::Engine::Engine() , mScriptContext (0) , mGuiManager (0) , mFSStrict (false) + , mCfgMgr(configurationManager) { MWClass::registerClasses(); } @@ -265,9 +266,9 @@ void OMW::Engine::addResourcesDirectory (const boost::filesystem::path& path) Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); } -void OMW::Engine::enableFSStrict() +void OMW::Engine::enableFSStrict(bool fsStrict) { - mFSStrict = true; + mFSStrict = fsStrict; } // Set data dir @@ -311,21 +312,40 @@ void OMW::Engine::addMaster (const std::string& master) } } -void OMW::Engine::enableDebugMode() +void OMW::Engine::setDebugMode(bool debugMode) { - mDebug = true; + mDebug = debugMode; } -void OMW::Engine::enableVerboseScripts() +void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) { - mVerboseScripts = true; + mVerboseScripts = scriptsVerbosity; } -void OMW::Engine::setNewGame() +void OMW::Engine::setNewGame(bool newGame) { - mNewGame = true; + mNewGame = newGame; } +std::string OMW::Engine::getOgreFilesDir(const std::string& ogreFile) +{ + boost::filesystem::path cfgPath(mCfgMgr.getRuntimeConfigPath()); + if (!boost::filesystem::exists(cfgPath / ogreFile)) + { + cfgPath = mCfgMgr.getLocalConfigPath(); + if (!boost::filesystem::exists(cfgPath / ogreFile )) + { + cfgPath = mCfgMgr.getGlobalConfigPath(); + if (!boost::filesystem::exists(cfgPath / ogreFile)) + { + cfgPath.clear(); + } + } + } + + return (!cfgPath.empty()) ? cfgPath.string() + std::string("/") : std::string(); + } + // Initialise and enter main loop. void OMW::Engine::go() @@ -337,19 +357,11 @@ void OMW::Engine::go() test.name = ""; total = 0; - std::string cfgDir = Files::getPath (Files::Path_ConfigGlobal, "openmw", ""); - std::string cfgUserDir = Files::getPath (Files::Path_ConfigUser, "openmw", ""); - std::string plugCfg = "plugins.cfg"; - std::string ogreCfg = "ogre.cfg"; - ogreCfg.insert(0, cfgUserDir); - //A local plugins.cfg will be used if it exist, otherwise look in the default path - if(!Misc::isFile(plugCfg.c_str())) - { - plugCfg.insert(0, cfgDir); - } + std::string cfgDir(getOgreFilesDir("ogre.cfg")); + std::string pluginsFile(getOgreFilesDir("plugins.cfg") + std::string("plugins.cfg")); - mOgre.configure(!Misc::isFile(ogreCfg.c_str()), cfgUserDir, plugCfg, false); + mOgre.configure(cfgDir.empty(), cfgDir, pluginsFile, false); // This has to be added BEFORE MyGUI is initialized, as it needs // to find core.xml here. @@ -516,7 +528,17 @@ void OMW::Engine::setCompileAll (bool all) mCompileAll = all; } +void OMW::Engine::setSoundUsage(bool soundUsage) +{ + mUseSound = soundUsage; +} + +void OMW::Engine::showFPS(bool showFps) +{ + mShowFPS = showFps; +} + void OMW::Engine::setEncoding(const std::string& encoding) { mEncoding = encoding; -} \ No newline at end of file +} diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 9d1466655..9ee3298d7 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -15,7 +15,7 @@ #include "mwworld/environment.hpp" #include "mwworld/ptr.hpp" #include - +#include namespace Compiler { @@ -53,7 +53,6 @@ namespace OEngine namespace OMW { /// \brief Main engine class, that brings together all the components of OpenMW - class Engine : private Ogre::FrameListener { std::string mEncoding; @@ -106,49 +105,44 @@ namespace OMW /// Process pending commands public: - - Engine(); - - ~Engine(); + Engine(Cfg::ConfigurationManager& configurationManager); + virtual ~Engine(); /// Enable strict filesystem mode (do not fold case) /// /// \attention The strict mode must be specified before any path-related settings /// are given to the engine. - void enableFSStrict(); + void enableFSStrict(bool fsStrict); /// Set data dirs - void setDataDirs (const std::vector& dataDirs); + void setDataDirs(const Files::Collections::PathContainer& dataDirs); /// Set resource dir - void setResourceDir (const boost::filesystem::path& parResDir); + void setResourceDir(const boost::filesystem::path& parResDir); /// Set start cell name (only interiors for now) - void setCell (const std::string& cellName); + void setCell(const std::string& cellName); /// Set master file (esm) /// - If the given name does not have an extension, ".esm" is added automatically /// - Currently OpenMW only supports one master at the same time. - void addMaster (const std::string& master); + void addMaster(const std::string& master); /// Enable fps counter - void showFPS() { mShowFPS = true; } + void showFPS(bool showFps); /// Enable debug mode: /// - non-exclusive input - void enableDebugMode(); + void setDebugMode(bool debugMode); - /// Enable the command server so external apps can send commands to the console. - /// Must be set before go(). + /// Enable or disable verbose script output + void setScriptsVerbosity(bool scriptsVerbosity); - /// Enable verbose script output - void enableVerboseScripts(); - - /// Disable all sound - void disableSound() { mUseSound = false; } + /// Disable or enable all sounds + void setSoundUsage(bool soundUsage); /// Start as a new game. - void setNewGame(); + void setNewGame(bool newGame); /// Initialise and enter main loop. void go(); @@ -161,7 +155,12 @@ namespace OMW /// Font encoding void setEncoding(const std::string& encoding); + + private: + std::string getOgreFilesDir(const std::string& ogreFile); + + Cfg::ConfigurationManager& mCfgMgr; }; } -#endif +#endif /* ENGINE_H */ diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index ed85f4beb..3fef2b0bd 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -5,8 +5,10 @@ #include -#include +#include #include +#include +#include #include "engine.hpp" @@ -35,56 +37,64 @@ using namespace std; -/// Parse command line options and openmw.cfg file (if one exists). Results are directly -/// written to \a engine. -/// \return Run OpenMW? - -bool parseOptions (int argc, char**argv, OMW::Engine& engine) +/** + * \brief Parses application command line and calls \ref Cfg::ConfigurationManager + * to parse configuration files. + * + * Results are directly written to \ref Engine class. + * + * \retval true - Everything goes OK + * \retval false - Error + */ +bool parseOptions (int argc, char** argv, OMW::Engine& engine, Cfg::ConfigurationManager& cfgMgr) { // Create a local alias for brevity namespace bpo = boost::program_options; + typedef std::vector StringsVector; - bpo::options_description desc ( - "Syntax: openmw \nAllowed options"); + bpo::options_description desc("Syntax: openmw \nAllowed options"); desc.add_options() - ("help", "print help message and quit") + ("help", "print help message") ("version", "print version information and quit") - ("data", bpo::value >() - ->default_value (std::vector(), "data") - ->multitoken(), - "set data directories (later directories have higher priority)") - ("data-local", bpo::value()->default_value (""), + ("data", bpo::value()->default_value(Files::Collections::PathContainer(), "data") + ->multitoken(), "set data directories (later directories have higher priority)") + + ("data-local", bpo::value()->default_value(""), "set local data directory (highest priority)") - ("resources", bpo::value()->default_value ("resources"), + + ("resources", bpo::value()->default_value("resources"), "set resources directory") - ("start", bpo::value()->default_value ("Beshara"), + + ("start", bpo::value()->default_value("Beshara"), "set initial cell") - ("master", bpo::value >() - ->default_value (std::vector(), "") - ->multitoken(), - "master file(s)") - ("plugin", bpo::value >() - ->default_value (std::vector(), "") - ->multitoken(), - "plugin file(s)") - ( "fps", boost::program_options::value()-> - implicit_value (true)->default_value (false), "show fps counter") - ( "debug", boost::program_options::value()-> - implicit_value (true)->default_value (false), "debug mode" ) - ( "nosound", boost::program_options::value()-> - implicit_value (true)->default_value (false), "disable all sound" ) - ( "script-verbose", boost::program_options::value()-> - implicit_value (true)->default_value (false), "verbose script output" ) - ( "new-game", boost::program_options::value()-> - implicit_value (true)->default_value (false), - "activate char gen/new game mechanics" ) - ( "script-all", boost::program_options::value()-> - implicit_value (true)->default_value (false), - "compile all scripts (excluding dialogue scripts) at startup") - ( "fs-strict", boost::program_options::value()-> - implicit_value (true)->default_value (false), - "strict file system handling (no case folding)") + + ("master", bpo::value()->default_value(StringsVector(), "") + ->multitoken(), "master file(s)") + + ("plugin", bpo::value()->default_value(StringsVector(), "") + ->multitoken(), "plugin file(s)") + + ("fps", boost::program_options::value()->implicit_value(true) + ->default_value(false), "show fps counter") + + ("debug", boost::program_options::value()->implicit_value(true) + ->default_value(false), "debug mode") + + ("nosound", boost::program_options::value()->implicit_value(true) + ->default_value(false), "disable all sounds") + + ("script-verbose", boost::program_options::value()->implicit_value(true) + ->default_value(false), "verbose script output") + + ("new-game", boost::program_options::value()->implicit_value(true) + ->default_value(false), "activate char gen/new game mechanics") + + ("script-all", boost::program_options::value()->implicit_value(true) + ->default_value(false), "compile all scripts (excluding dialogue scripts) at startup") + + ("fs-strict", boost::program_options::value()->implicit_value(true) + ->default_value(false), "strict file system handling (no case folding)") ( "encoding", boost::program_options::value()-> default_value("win1252"), @@ -94,32 +104,17 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) "\n\twin1252 - Western European (Latin) alphabet, used by default") ; - bpo::variables_map variables; - - //If there is an openmw.cfg in the current path use that as global config - //Otherwise try getPath - std::string cfgFile = "openmw.cfg"; - if(!Misc::isFile(cfgFile.c_str())) - { - cfgFile = Files::getPath (Files::Path_ConfigGlobal, "openmw", "openmw.cfg"); - } - std::cout << "Using global config file: " << cfgFile << std::endl; - std::ifstream globalConfigFile(cfgFile.c_str()); + bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv) + .options(desc).allow_unregistered().run(); - cfgFile = Files::getPath (Files::Path_ConfigUser, "openmw", "openmw.cfg"); - std::cout << "Using user config file: " << cfgFile << std::endl; - std::ifstream userConfigFile(cfgFile.c_str()); + bpo::variables_map variables; - bpo::parsed_options valid_opts = bpo::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); + cfgMgr.readConfiguration(variables, desc); + // Runtime options override settings from all configs bpo::store(valid_opts, variables); bpo::notify(variables); - if (userConfigFile.is_open()) - bpo::store ( bpo::parse_config_file (userConfigFile, desc), variables); - if (globalConfigFile.is_open()) - bpo::store ( bpo::parse_config_file (globalConfigFile, desc), variables); - bool run = true; if (variables.count ("help")) @@ -156,63 +151,57 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) } // directory settings - if (variables["fs-strict"].as()==true) - engine.enableFSStrict(); + engine.enableFSStrict(variables["fs-strict"].as()); - std::vector dataDirs = variables["data"].as >(); - std::vector dataDirs2 (dataDirs.begin(), dataDirs.end()); + Files::Collections::PathContainer dataDirs = variables["data"].as(); - std::string local = variables["data-local"].as(); + std::string local(variables["data-local"].as()); if (!local.empty()) - dataDirs.push_back (local); + { + dataDirs.push_back(local); + } - engine.setDataDirs (dataDirs2); + if (dataDirs.empty()) + { + dataDirs.push_back(cfgMgr.getLocalDataPath().string()); + } - engine.setResourceDir (variables["resources"].as()); + engine.setDataDirs(dataDirs); + + engine.setResourceDir(variables["resources"].as()); // master and plugin - std::vector master = variables["master"].as >(); + StringsVector master = variables["master"].as(); if (master.empty()) { std::cout << "No master file given. Assuming Morrowind.esm" << std::endl; - master.push_back ("Morrowind"); + master.push_back("Morrowind"); } - if (master.size()>1) + if (master.size() > 1) { std::cout << "Ignoring all but the first master file (multiple master files not yet supported)." << std::endl; } + engine.addMaster(master[0]); - engine.addMaster (master[0]); - - std::vector plugin = variables["plugin"].as >(); - + StringsVector plugin = variables["plugin"].as(); if (!plugin.empty()) + { std::cout << "Ignoring plugin files (plugins not yet supported)." << std::endl; + } // startup-settings - engine.setCell (variables["start"].as()); - - if (variables["new-game"].as()==true) - engine.setNewGame(); + engine.setCell(variables["start"].as()); + engine.setNewGame(variables["new-game"].as()); // other settings - if (variables["fps"].as()==true) - engine.showFPS(); - - if (variables["debug"].as()==true) - engine.enableDebugMode(); - - if (variables["nosound"].as()==true) - engine.disableSound(); - - if (variables["script-verbose"].as()==true) - engine.enableVerboseScripts(); - - if (variables["script-all"].as()==true) - engine.setCompileAll (true); + engine.showFPS(variables["fps"].as()); + engine.setDebugMode(variables["debug"].as()); + engine.setSoundUsage(!variables["nosound"].as()); + engine.setScriptsVerbosity(variables["script-verbose"].as()); + engine.setCompileAll(variables["script-all"].as()); return true; } @@ -227,16 +216,17 @@ int main(int argc, char**argv) try { - OMW::Engine engine; + Cfg::ConfigurationManager cfgMgr; + OMW::Engine engine(cfgMgr); - if (parseOptions (argc, argv, engine)) + if (parseOptions(argc, argv, engine, cfgMgr)) { engine.go(); } } - catch(exception &e) + catch (std::exception &e) { - cout << "\nERROR: " << e.what() << endl; + std::cout << "\nERROR: " << e.what() << std::endl; return 1; } diff --git a/components/cfg/configurationmanager.cpp b/components/cfg/configurationmanager.cpp new file mode 100644 index 000000000..7c210f72c --- /dev/null +++ b/components/cfg/configurationmanager.cpp @@ -0,0 +1,118 @@ +#include "configurationmanager.hpp" + +#include +#include +#include + +namespace Cfg +{ + +static const char* const openmwCfgFile = "openmw.cfg"; +static const char* const ogreCfgFile = "ogre.cfg"; +static const char* const pluginsCfgFile = "plugins.cfg"; + + +ConfigurationManager::ConfigurationManager() + : mPath("openmw") +{ +} + +ConfigurationManager::~ConfigurationManager() +{ +} + +void ConfigurationManager::readConfiguration(boost::program_options::variables_map& variables, + boost::program_options::options_description& description) +{ + loadConfig(mPath.getGlobalConfigPath(), variables, description); + loadConfig(mPath.getLocalConfigPath(), variables, description); + loadConfig(mPath.getRuntimeConfigPath(), variables, description); + boost::program_options::notify(variables); +} + +void ConfigurationManager::loadConfig(const boost::filesystem::path& path, + boost::program_options::variables_map& variables, + boost::program_options::options_description& description) +{ + boost::filesystem::path cfgFile(path); + cfgFile /= std::string(openmwCfgFile); + if (boost::filesystem::is_regular_file(cfgFile)) + { + std::cout << "Loading config file: " << cfgFile.string() << "... "; + + std::ifstream configFileStream(cfgFile.string().c_str()); + if (configFileStream.is_open()) + { + boost::program_options::store(boost::program_options::parse_config_file( + configFileStream, description), variables); + + std::cout << "done." << std::endl; + } + else + { + std::cout << "failed." << std::endl; + } + } +} + +const boost::filesystem::path& ConfigurationManager::getGlobalConfigPath() const +{ + return mPath.getGlobalConfigPath(); +} + +void ConfigurationManager::setGlobalConfigPath(const boost::filesystem::path& newPath) +{ + mPath.setGlobalConfigPath(newPath); +} + +const boost::filesystem::path& ConfigurationManager::getLocalConfigPath() const +{ + return mPath.getLocalConfigPath(); +} + +void ConfigurationManager::setLocalConfigPath(const boost::filesystem::path& newPath) +{ + mPath.setLocalConfigPath(newPath); +} + +const boost::filesystem::path& ConfigurationManager::getRuntimeConfigPath() const +{ + return mPath.getRuntimeConfigPath(); +} + +void ConfigurationManager::setRuntimeConfigPath(const boost::filesystem::path& newPath) +{ + mPath.setRuntimeConfigPath(newPath); +} + +const boost::filesystem::path& ConfigurationManager::getGlobalDataPath() const +{ + return mPath.getGlobalDataPath(); +} + +void ConfigurationManager::setGlobalDataPath(const boost::filesystem::path& newPath) +{ + mPath.setGlobalDataPath(newPath); +} + +const boost::filesystem::path& ConfigurationManager::getLocalDataPath() const +{ + return mPath.getLocalDataPath(); +} + +void ConfigurationManager::setLocalDataPath(const boost::filesystem::path& newPath) +{ + mPath.setLocalDataPath(newPath); +} + +const boost::filesystem::path& ConfigurationManager::getRuntimeDataPath() const +{ + return mPath.getRuntimeDataPath(); +} + +void ConfigurationManager::setRuntimeDataPath(const boost::filesystem::path& newPath) +{ + mPath.setRuntimeDataPath(newPath); +} + +} /* namespace Cfg */ diff --git a/components/cfg/configurationmanager.hpp b/components/cfg/configurationmanager.hpp new file mode 100644 index 000000000..f0123d48a --- /dev/null +++ b/components/cfg/configurationmanager.hpp @@ -0,0 +1,54 @@ +#ifndef COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP +#define COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP + +#include +#include + +#include + +/** + * \namespace Cfg + */ +namespace Cfg +{ + +/** + * \struct ConfigurationManager + */ +struct ConfigurationManager +{ + ConfigurationManager(); + virtual ~ConfigurationManager(); + + void readConfiguration(boost::program_options::variables_map& variables, + boost::program_options::options_description& description); + + const boost::filesystem::path& getGlobalConfigPath() const; + void setGlobalConfigPath(const boost::filesystem::path& newPath); + + const boost::filesystem::path& getLocalConfigPath() const; + void setLocalConfigPath(const boost::filesystem::path& newPath); + + const boost::filesystem::path& getRuntimeConfigPath() const; + void setRuntimeConfigPath(const boost::filesystem::path& newPath); + + const boost::filesystem::path& getGlobalDataPath() const; + void setGlobalDataPath(const boost::filesystem::path& newPath); + + const boost::filesystem::path& getLocalDataPath() const; + void setLocalDataPath(const boost::filesystem::path& newPath); + + const boost::filesystem::path& getRuntimeDataPath() const; + void setRuntimeDataPath(const boost::filesystem::path& newPath); + + private: + void loadConfig(const boost::filesystem::path& path, + boost::program_options::variables_map& variables, + boost::program_options::options_description& description); + + Files::Path<> mPath; +}; + +} /* namespace Cfg */ + +#endif /* COMPONENTS_CFG_CONFIGURATIONMANAGER_HPP */ diff --git a/components/files/collections.cpp b/components/files/collections.cpp index 8cd4865b3..cb32768b4 100644 --- a/components/files/collections.cpp +++ b/components/files/collections.cpp @@ -3,21 +3,27 @@ namespace Files { - Collections::Collections() : mFoldCase (false) {} - - Collections::Collections (const std::vector& directories, bool foldCase) - : mDirectories (directories), mFoldCase (foldCase) - {} + Collections::Collections() + : mDirectories() + , mFoldCase(false) + , mCollections() + { + } - const MultiDirCollection& Collections::getCollection (const std::string& extension) const + Collections::Collections(const std::vector& directories, bool foldCase) + : mDirectories(directories) + , mFoldCase(foldCase) + , mCollections() { - std::map::iterator iter = mCollections.find (extension); + } + const MultiDirCollection& Collections::getCollection(const std::string& extension) const + { + MultiDirCollectionContainer::iterator iter = mCollections.find(extension); if (iter==mCollections.end()) { - std::pair::iterator, bool> result = - mCollections.insert (std::make_pair (extension, - MultiDirCollection (mDirectories, extension, mFoldCase))); + std::pair result = + mCollections.insert(std::make_pair(extension, MultiDirCollection(mDirectories, extension, mFoldCase))); iter = result.first; } diff --git a/components/files/collections.hpp b/components/files/collections.hpp index 6eaf0303e..102ab3050 100644 --- a/components/files/collections.hpp +++ b/components/files/collections.hpp @@ -1,27 +1,35 @@ #ifndef COMPONENTS_FILES_COLLECTION_HPP #define COMPONENTS_FILES_COLLECTION_HPP +#include +#include +#include +#include + #include "multidircollection.hpp" namespace Files { class Collections { - std::vector mDirectories; - bool mFoldCase; - mutable std::map mCollections; - public: + typedef std::vector PathContainer; Collections(); - Collections (const std::vector& directories, bool foldCase); ///< Directories are listed with increasing priority. + Collections(const PathContainer& directories, bool foldCase); - const MultiDirCollection& getCollection (const std::string& extension) const; ///< Return a file collection for the given extension. Extension must contain the /// leading dot and must be all lower-case. + const MultiDirCollection& getCollection(const std::string& extension) const; + private: + typedef std::map MultiDirCollectionContainer; + PathContainer mDirectories; + + bool mFoldCase; + mutable MultiDirCollectionContainer mCollections; }; } diff --git a/components/files/fileops.cpp b/components/files/fileops.cpp new file mode 100644 index 000000000..329e4eb05 --- /dev/null +++ b/components/files/fileops.cpp @@ -0,0 +1,12 @@ +#include "fileops.hpp" +#include + +namespace Files +{ + +bool isFile(const char *name) +{ + return boost::filesystem::exists(boost::filesystem::path(name)); +} + +} diff --git a/components/files/fileops.hpp b/components/files/fileops.hpp new file mode 100644 index 000000000..a541beffc --- /dev/null +++ b/components/files/fileops.hpp @@ -0,0 +1,13 @@ +#ifndef COMPONENTS_FILES_FILEOPS_HPP +#define COMPONENTS_FILES_FILEOPS_HPP + +namespace Files +{ + +///\brief Check if a given path is an existing file (not a directory) +///\param [in] name - filename +bool isFile(const char *name); + +} + +#endif /* COMPONENTS_FILES_FILEOPS_HPP */ diff --git a/components/files/linuxpath.cpp b/components/files/linuxpath.cpp new file mode 100644 index 000000000..9786e3898 --- /dev/null +++ b/components/files/linuxpath.cpp @@ -0,0 +1,159 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/linuxpath.cpp */ + +#include "linuxpath.hpp" + +#if defined(__linux__) + +#include +#include +#include + +/** + * \namespace Files + */ +namespace Files +{ + +boost::filesystem::path LinuxPath::getLocalConfigPath() const +{ + boost::filesystem::path localConfigPath("."); + boost::filesystem::path suffix("/"); + + const char* theDir = getenv("OPENMW_CONFIG"); + if (theDir == NULL) + { + theDir = getenv("XDG_CONFIG_HOME"); + if (theDir == NULL) + { + theDir = getenv("HOME"); + if (theDir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + theDir = pwd->pw_dir; + } + } + if (theDir != NULL) + { + suffix = boost::filesystem::path("/.config/"); + } + } + } + + if (theDir != NULL) { + localConfigPath = boost::filesystem::path(theDir); + } + + localConfigPath /= suffix; + + return localConfigPath; +} + +boost::filesystem::path LinuxPath::getGlobalConfigPath() const +{ + boost::filesystem::path globalConfigPath("/etc/xdg/"); + + char* theDir = getenv("XDG_CONFIG_DIRS"); + if (theDir != NULL) + { + // We take only first path from list + char* ptr = strtok(theDir, ":"); + if (ptr != NULL) + { + globalConfigPath = boost::filesystem::path(ptr); + globalConfigPath /= boost::filesystem::path("/"); + } + } + + return globalConfigPath; +} + +boost::filesystem::path LinuxPath::getRuntimeConfigPath() const +{ + return boost::filesystem::path("./"); +} + +boost::filesystem::path LinuxPath::getLocalDataPath() const +{ + boost::filesystem::path localDataPath("."); + boost::filesystem::path suffix("/"); + + const char* theDir = getenv("OPENMW_DATA"); + if (theDir == NULL) + { + theDir = getenv("XDG_DATA_HOME"); + if (theDir == NULL) + { + theDir = getenv("HOME"); + if (theDir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + theDir = pwd->pw_dir; + } + } + if (theDir != NULL) + { + suffix = boost::filesystem::path("/.local/share/"); + } + } + } + + if (theDir != NULL) { + localDataPath = boost::filesystem::path(theDir); + } + + localDataPath /= suffix; + return localDataPath; +} + +boost::filesystem::path LinuxPath::getGlobalDataPath() const +{ + boost::filesystem::path globalDataPath("/usr/local/share/"); + + char* theDir = getenv("XDG_DATA_DIRS"); + if (theDir != NULL) + { + // We take only first path from list + char* ptr = strtok(theDir, ":"); + if (ptr != NULL) + { + globalDataPath = boost::filesystem::path(ptr); + globalDataPath /= boost::filesystem::path("/"); + } + } + + return globalDataPath; +} + +boost::filesystem::path LinuxPath::getRuntimeDataPath() const +{ + return boost::filesystem::path("./data/"); +} + + +} /* namespace Files */ + +#endif /* defined(__linux__) */ diff --git a/components/files/linuxpath.hpp b/components/files/linuxpath.hpp new file mode 100644 index 000000000..d6e717fc4 --- /dev/null +++ b/components/files/linuxpath.hpp @@ -0,0 +1,90 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/linuxpath.hpp */ + +#ifndef COMPONENTS_FILES_LINUXPATH_H +#define COMPONENTS_FILES_LINUXPATH_H + +#if defined(__linux__) + +#include + +/** + * \namespace Files + */ +namespace Files +{ + +/** + * \struct LinuxPath + */ +struct LinuxPath +{ + /** + * \brief Return path to the local configuration directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getLocalConfigPath() const; + + /** + * \brief Return path to the global (system) configuration directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getGlobalConfigPath() const; + + /** + * \brief Return path to the runtime configuration directory which is the + * place where an application was started. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getRuntimeConfigPath() const; + + /** + * \brief Return path to the local data directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getLocalDataPath() const; + + /** + * \brief Return path to the global (system) data directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getGlobalDataPath() const; + + /** + * \brief Return runtime data path which is a location where + * an application was started with 'data' suffix. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getRuntimeDataPath() const; +}; + +} /* namespace Files */ + +#endif /* defined(__linux__) */ + +#endif /* COMPONENTS_FILES_LINUXPATH_H */ diff --git a/components/files/macospath.cpp b/components/files/macospath.cpp new file mode 100644 index 000000000..46e775030 --- /dev/null +++ b/components/files/macospath.cpp @@ -0,0 +1,118 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/macospath.cpp */ + +#include "macospath.hpp" + +#if defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) + +#include +#include +#include + +/** + * \namespace Files + */ +namespace Files +{ + +boost::filesystem::path MacOsPath::getLocalConfigPath() const +{ + boost::filesystem::path localConfigPath("."); + boost::filesystem::path suffix("/"); + + const char* theDir = getenv("HOME"); + if (theDir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + theDir = pwd->pw_dir; + } + } + if (theDir != NULL) + { + localConfigPath = boost::filesystem::path(theDir) / "Library/Preferences/"; + } + + localConfigPath /= suffix; + + return localConfigPath; +} + +boost::filesystem::path MacOsPath::getGlobalConfigPath() const +{ + boost::filesystem::path globalConfigPath("/Library/Preferences/"); + return globalConfigPath; +} + +boost::filesystem::path MacOsPath::getRuntimeConfigPath() const +{ + return boost::filesystem::path("./"); +} + +boost::filesystem::path MacOsPath::getLocalDataPath() const +{ + boost::filesystem::path localDataPath("."); + boost::filesystem::path suffix("/"); + + const char* theDir = getenv("OPENMW_DATA"); + if (theDir == NULL) + { + theDir = getenv("HOME"); + if (theDir == NULL) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd != NULL) + { + theDir = pwd->pw_dir; + } + } + if (theDir != NULL) + { + suffix = boost::filesystem::path("/Library/Application Support/"); + } + } + + if (theDir != NULL) + { + localDataPath = boost::filesystem::path(theDir); + } + + localDataPath /= suffix; + return localDataPath; +} + +boost::filesystem::path MacOsPath::getGlobalDataPath() const +{ + boost::filesystem::path globalDataPath("/Library/Application Support/"); + return globalDataPath; +} + +boost::filesystem::path MacOsPath::getRuntimeDataPath() const +{ + return boost::filesystem::path("./data/"); +} + + +} /* namespace Files */ + +#endif /* defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) */ diff --git a/components/files/macospath.hpp b/components/files/macospath.hpp new file mode 100644 index 000000000..26f2c907f --- /dev/null +++ b/components/files/macospath.hpp @@ -0,0 +1,90 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/macospath.hpp */ + +#ifndef COMPONENTS_FILES_MACOSPATH_H +#define COMPONENTS_FILES_MACOSPATH_H + +#if defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) + +#include + +/** + * \namespace Files + */ +namespace Files +{ + +/** + * \struct MacOsPath + */ +struct MacOsPath +{ + /** + * \brief Return path to the local configuration directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getLocalConfigPath() const; + + /** + * \brief Return path to the global (system) configuration directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getGlobalConfigPath() const; + + /** + * \brief Return path to the runtime configuration directory which is the + * place where an application was started. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getRuntimeConfigPath() const; + + /** + * \brief Return path to the local data directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getLocalDataPath() const; + + /** + * \brief Return path to the global (system) data directory. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getGlobalDataPath() const; + + /** + * \brief Return runtime data path which is a location where + * an application was started with 'data' suffix. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getRuntimeDataPath() const; +}; + +} /* namespace Files */ + +#endif /* defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) */ + +#endif /* COMPONENTS_FILES_MACOSPATH_H */ diff --git a/components/files/path.cpp b/components/files/path.cpp deleted file mode 100644 index d540f1c14..000000000 --- a/components/files/path.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "path.hpp" - -#include - -#include -#include - -#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -#include -#endif - -#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE -#include //getenv -#endif - -std::string Files::getPath (PathTypeEnum parType, const std::string parApp, const std::string parFile) -{ - std::string theBasePath; - if (parType==Path_ConfigGlobal) - { -#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE - boost::filesystem::path path(Ogre::macBundlePath()); - path = path.parent_path(); - theBasePath = path.string() + "/"; -#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX - theBasePath = "/etc/"+parApp+"/"; -#else - theBasePath = ""; -#endif - - } - else if (parType==Path_ConfigUser) - { -#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX || OGRE_PLATFORM == OGRE_PLATFORM_APPLE - const char* theDir; - if ((theDir = getenv("OPENMW_HOME")) != NULL) - { - theBasePath = std::string(theDir)+"/"; - } - else - { - if ((theDir = getenv("XDG_CONFIG_HOME"))) - { - theBasePath = std::string(theDir)+"/"+parApp+"/"; - } - else - { - if ((theDir = getenv("HOME")) == NULL) - return parFile; - theBasePath = std::string(theDir)+"/.config/"+parApp+"/"; - } - } - boost::filesystem::create_directories(boost::filesystem::path(theBasePath)); -#else - theBasePath = ""; -#endif - } - - theBasePath.append(parFile); - return theBasePath; -} diff --git a/components/files/path.hpp b/components/files/path.hpp index a42646404..0788cefb1 100644 --- a/components/files/path.hpp +++ b/components/files/path.hpp @@ -1,17 +1,232 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/path.hpp */ + #ifndef COMPONENTS_FILES_PATH_HPP #define COMPONENTS_FILES_PATH_HPP #include +#include + +#if defined(__linux__) + #include + namespace Files { typedef LinuxPath TargetPathType; } +#elif defined(__WIN32) || defined(__WINDOWS__) + #include + namespace Files { typedef WindowsPath TargetPathType; } + +#elif defined(macintosh) || defined(Macintosh) || defined(__APPLE__) || defined(__MACH__) + #include + namespace Files { typedef MacOsPath TargetPathType; } + +#else + #error "Unknown platform!" +#endif + + +/** + * \namespace Files + */ namespace Files { - enum PathTypeEnum + +/** + * \struct Path + * + * \tparam P - Path strategy class type (depends on target system) + * + */ +template +< + class P = TargetPathType +> +struct Path +{ + typedef P PathType; + + /** + * \brief Path constructor. + * + * \param [in] application_name - Name of the application + */ + Path(const std::string& application_name) + : mPath() + , mLocalConfigPath(mPath.getLocalConfigPath()) + , mGlobalConfigPath(mPath.getGlobalConfigPath()) + , mRuntimeConfigPath(mPath.getRuntimeConfigPath()) + , mLocalDataPath(mPath.getLocalDataPath()) + , mGlobalDataPath(mPath.getGlobalDataPath()) + , mRuntimeDataPath(mPath.getRuntimeDataPath()) { - Path_ConfigUser, - Path_ConfigGlobal - }; + if (!application_name.empty()) + { + boost::filesystem::path suffix(application_name + std::string("/")); - std::string getPath (PathTypeEnum parType, const std::string parApp, const std::string parFile); -} + mLocalConfigPath /= suffix; + mGlobalConfigPath /= suffix; -#endif + mLocalDataPath /= suffix; + mGlobalDataPath /= suffix; + } + } + + /** + * \brief Return path pointing to the user local configuration directory. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getLocalConfigPath() const + { + return mLocalConfigPath; + } + + /** + * \brief Sets new local configuration path. + * + * \param [in] path - New path + */ + void setLocalConfigPath(const boost::filesystem::path& path) + { + mLocalConfigPath = path; + } + + /** + * \brief Return path pointing to the global (system) configuration directory. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getGlobalConfigPath() const + { + return mGlobalConfigPath; + } + + /** + * \brief Sets new global configuration path. + * + * \param [in] path - New path + */ + void setGlobalConfigPath(const boost::filesystem::path& path) + { + mGlobalConfigPath = path; + } + + /** + * \brief Return path pointing to the directory where application was started. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getRuntimeConfigPath() const + { + return mRuntimeConfigPath; + } + + /** + * \brief Sets new runtime configuration path. + * + * \param [in] path - New path + */ + void setRuntimeConfigPath(const boost::filesystem::path& path) + { + mRuntimeConfigPath = path; + } + + /** + * \brief Return path pointing to the user local data directory. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getLocalDataPath() const + { + return mLocalDataPath; + } + + /** + * \brief Sets new local data path. + * + * \param [in] path - New path + */ + void setLocalDataPath(const boost::filesystem::path& path) + { + mLocalDataPath = path; + } + + /** + * \brief Return path pointing to the global (system) data directory. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getGlobalDataPath() const + { + return mGlobalDataPath; + } + + /** + * \brief Sets new global (system) data directory. + * + * \param [in] path - New path + */ + void setGlobalDataPath(const boost::filesystem::path& path) + { + mGlobalDataPath = path; + } + + /** + * \brief Return path pointing to the directory where application was started. + * + * \return boost::filesystem::path + */ + const boost::filesystem::path& getRuntimeDataPath() const + { + return mRuntimeDataPath; + } + + /** + * \brief Sets new runtime data directory. + * + * \param [in] path - New path + */ + void setRuntimeDataPath(const boost::filesystem::path& path) + { + mRuntimeDataPath = path; + } + + private: + PathType mPath; + + boost::filesystem::path mLocalConfigPath; /**< User local path to the configuration files */ + boost::filesystem::path mGlobalConfigPath; /**< Global path to the configuration files */ + boost::filesystem::path mRuntimeConfigPath; /**< Runtime path to the configuration files. + By default it is the same directory where + application was run */ + + boost::filesystem::path mLocalDataPath; /**< User local application data path (user plugins / mods / etc.) */ + boost::filesystem::path mGlobalDataPath; /**< Global application data path */ + boost::filesystem::path mRuntimeDataPath; /**< Runtime path to the configuration files. + By default it is a 'data' directory in same + directory where application was run */ + +}; + + +} /* namespace Files */ + +#endif /* COMPONENTS_FILES_PATH_HPP */ diff --git a/components/files/windowspath.cpp b/components/files/windowspath.cpp new file mode 100644 index 000000000..f42f149c1 --- /dev/null +++ b/components/files/windowspath.cpp @@ -0,0 +1,72 @@ +#include "windowspath.hpp" + +#if defined(_WIN32) || defined(__WINDOWS__) + +#include + +#include +#include + +namespace Files +{ + +boost::filesystem::path WindowsPath::getLocalConfigPath() const +{ + boost::filesystem::path localConfigPath("."); + boost::filesystem::path suffix("/"); + + TCHAR path[MAX_PATH]; + memset(path, 0, sizeof(path)); + + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, path))) + { + PathAppend(path, TEXT("My Games")); + localConfigPath = boost::filesystem::path(path); + } + + localConfigPath /= suffix; + + return localConfigPath; +} + +boost::filesystem::path WindowsPath::getGlobalConfigPath() const +{ + boost::filesystem::path globalConfigPath("."); + boost::filesystem::path suffix("/"); + + TCHAR path[MAX_PATH]; + memset(path, 0, sizeof(path)); + + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROGRAM_FILES | CSIDL_FLAG_CREATE, NULL, 0, path))) + { + globalConfigPath = boost::filesystem::path(path); + } + + globalConfigPath /= suffix; + + return globalConfigPath; +} + +boost::filesystem::path WindowsPath::getRuntimeConfigPath() const +{ + return boost::filesystem::path("./"); +} + +boost::filesystem::path WindowsPath::getLocalDataPath() const +{ + return getLocalConfigPath(); +} + +boost::filesystem::path WindowsPath::getGlobalDataPath() const +{ + return getGlobalConfigPath(); +} + +boost::filesystem::path WindowsPath::getRuntimeDataPath() const +{ + return boost::filesystem::path("./data/"); +} + +} /* namespace Files */ + +#endif /* defined(_WIN32) || defined(__WINDOWS__) */ diff --git a/components/files/windowspath.hpp b/components/files/windowspath.hpp new file mode 100644 index 000000000..47dfc08d8 --- /dev/null +++ b/components/files/windowspath.hpp @@ -0,0 +1,90 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/windowspath.hpp */ + +#ifndef COMPONENTS_FILES_WINDOWSPATH_HPP +#define COMPONENTS_FILES_WINDOWSPATH_HPP + +#if defined(_WIN32) || defined(__WINDOWS__) + +#include + +/** + * \namespace Files + */ +namespace Files +{ + +/** + * \struct WindowsPath + */ +struct WindowsPath +{ + /** + * \brief Returns "X:\Documents And Settings\\My Documents\My Games\" + * + * \return boost::filesystem::path + */ + boost::filesystem::path getLocalConfigPath() const; + + /** + * \brief Returns "X:\Program Files\" + * + * \return boost::filesystem::path + */ + boost::filesystem::path getGlobalConfigPath() const; + + /** + * \brief Return runtime configuration path which is a location where + * an application was started + * + * \return boost::filesystem::path + */ + boost::filesystem::path getRuntimeConfigPath() const; + + /** + * \brief Return same path like getLocalConfigPath + * + * \return boost::filesystem::path + */ + boost::filesystem::path getLocalDataPath() const; + + /** + * \brief Return same path like getGlobalConfigPath + * + * \return boost::filesystem::path + */ + boost::filesystem::path getGlobalDataPath() const; + + /** + * \brief Return runtime data path which is a location where + * an application was started with 'data' suffix. + * + * \return boost::filesystem::path + */ + boost::filesystem::path getRuntimeDataPath() const; +}; + +} /* namespace Files */ + +#endif /* defined(_WIN32) || defined(__WINDOWS__) */ + +#endif /* COMPONENTS_FILES_WINDOWSPATH_HPP */ diff --git a/components/misc/fileops.cpp b/components/misc/fileops.cpp deleted file mode 100644 index eb3b58d84..000000000 --- a/components/misc/fileops.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "fileops.hpp" -#include -#include - -#include - -namespace Misc -{ - -bool isFile(const char *name) -{ - boost::filesystem::path cfg_file_path(name); - return boost::filesystem::exists(cfg_file_path); -} - -} diff --git a/components/misc/fileops.hpp b/components/misc/fileops.hpp deleted file mode 100644 index f4e7701bb..000000000 --- a/components/misc/fileops.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef MISC_FILEOPS_H -#define MISC_FILEOPS_H - -#include - -namespace Misc -{ - -/// Check if a given path is an existing file (not a directory) -bool isFile(const char *name); - -#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE -std::string macBundlePath(); -#endif - -} - -#endif