Changeset 5836 for code/branches/core5/src/libraries
- Timestamp:
- Sep 30, 2009, 12:00:16 AM (15 years ago)
- Location:
- code/branches/core5/src/libraries
- Files:
-
- 12 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
code/branches/core5/src/libraries/core/CMakeLists.txt
r5778 r5836 36 36 ObjectListBase.cc 37 37 OrxonoxClass.cc 38 PathConfig.cc 38 39 Resource.cc 39 40 WindowEventListener.cc -
code/branches/core5/src/libraries/core/CommandLine.cc
r5738 r5836 38 38 #include "util/StringUtils.h" 39 39 #include "util/SubString.h" 40 #include " Core.h"40 #include "PathConfig.h" 41 41 42 42 namespace orxonox … … 348 348 { 349 349 std::string filename = CommandLine::getValue("optionsFile").getString(); 350 boost::filesystem::path filepath( Core::getConfigPath() / filename);350 boost::filesystem::path filepath(PathConfig::getConfigPath() / filename); 351 351 352 352 // look for additional arguments in given file or start.ini as default -
code/branches/core5/src/libraries/core/ConfigFileManager.cc
r5778 r5836 36 36 #include "ConsoleCommand.h" 37 37 #include "ConfigValueContainer.h" 38 #include " Core.h"38 #include "PathConfig.h" 39 39 40 40 namespace orxonox … … 222 222 223 223 // Get default file if necessary and available 224 boost::filesystem::path filepath( Core::getConfigPath() / this->filename_);224 boost::filesystem::path filepath(PathConfig::getConfigPath() / this->filename_); 225 225 if (!boost::filesystem::exists(filepath)) 226 226 { 227 227 // Try to get default one from the data folder 228 boost::filesystem::path defaultFilepath( Core::getDataPath() / "defaultConfig" / this->filename_);228 boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / "defaultConfig" / this->filename_); 229 229 if (boost::filesystem::exists(defaultFilepath)) 230 230 { … … 336 336 { 337 337 std::ofstream file; 338 file.open(( Core::getConfigPathString() + filename_).c_str(), std::fstream::out);338 file.open((PathConfig::getConfigPathString() + filename_).c_str(), std::fstream::out); 339 339 file.setf(std::ios::fixed, std::ios::floatfield); 340 340 file.precision(6); -
code/branches/core5/src/libraries/core/Core.cc
r5778 r5836 37 37 38 38 #include <cassert> 39 #include <fstream> 40 #include <cstdlib> 41 #include <cstdio> 42 #include <boost/version.hpp> 43 #include <boost/filesystem.hpp> 39 #include <vector> 44 40 45 41 #ifdef ORXONOX_PLATFORM_WINDOWS … … 50 46 # undef min 51 47 # undef max 52 #elif defined(ORXONOX_PLATFORM_APPLE)53 # include <sys/param.h>54 # include <mach-o/dyld.h>55 #else /* Linux */56 # include <sys/types.h>57 # include <unistd.h>58 48 #endif 59 49 60 #include "SpecialConfig.h"61 50 #include "util/Debug.h" 62 51 #include "util/Exception.h" 63 52 #include "util/SignalHandler.h" 53 #include "PathConfig.h" 64 54 #include "Clock.h" 65 55 #include "CommandExecutor.h" … … 80 70 #include "input/InputManager.h" 81 71 82 // Boost 1.36 has some issues with deprecated functions that have been omitted83 #if (BOOST_VERSION == 103600)84 # define BOOST_LEAF_FUNCTION filename85 #else86 # define BOOST_LEAF_FUNCTION leaf87 #endif88 89 72 namespace orxonox 90 73 { … … 92 75 Core* Core::singletonPtr_s = 0; 93 76 94 SetCommandLineArgument(externalDataPath, "").information("Path to the external data files");95 SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files");96 77 SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file"); 97 78 #ifdef ORXONOX_PLATFORM_WINDOWS … … 116 97 RegisterRootObject(CoreConfiguration); 117 98 this->setConfigValues(); 118 119 // External data directory only exists for dev runs120 if (Core::isDevelopmentRun())121 {122 // Possible data path override by the command line123 if (!CommandLine::getArgument("externalDataPath")->hasDefaultValue())124 tsetExternalDataPath(CommandLine::getValue("externalDataPath"));125 }126 99 } 127 100 … … 193 166 } 194 167 195 /**196 @brief197 Temporary sets the external data path198 @param path199 The new data path200 */201 void tsetExternalDataPath(const std::string& path)202 {203 externalDataPath_ = boost::filesystem::path(path);204 }205 206 168 void initializeRandomNumberGenerator() 207 169 { … … 221 183 std::string language_; //!< The language 222 184 bool bInitializeRandomNumberGenerator_; //!< If true, srand(time(0)) is called 223 224 //! Path to the parent directory of the ones above if program was installed with relativ pahts225 boost::filesystem::path rootPath_;226 boost::filesystem::path executablePath_; //!< Path to the executable227 boost::filesystem::path modulePath_; //!< Path to the modules228 boost::filesystem::path dataPath_; //!< Path to the data file folder229 boost::filesystem::path externalDataPath_; //!< Path to the external data file folder230 boost::filesystem::path configPath_; //!< Path to the config file folder231 boost::filesystem::path logPath_; //!< Path to the log file folder232 185 }; 233 186 … … 239 192 , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands) 240 193 , configuration_(new CoreConfiguration()) // Don't yet create config values! 241 , bDevRun_(false)242 194 , bGraphicsLoaded_(false) 243 195 { 244 196 // Set the hard coded fixed paths 245 this-> setFixedPaths();197 this->pathConfig_.reset(new PathConfig()); 246 198 247 199 // Create a new dynamic library manager … … 249 201 250 202 // Load modules 251 try 252 { 253 // We search for helper files with the following extension 254 std::string moduleextension = specialConfig::moduleExtension; 255 size_t moduleextensionlength = moduleextension.size(); 256 257 // Search in the directory of our executable 258 boost::filesystem::path searchpath = this->configuration_->modulePath_; 259 260 // Add that path to the PATH variable in case a module depends on another one 261 std::string pathVariable = getenv("PATH"); 262 putenv(const_cast<char*>(("PATH=" + pathVariable + ";" + configuration_->modulePath_.string()).c_str())); 263 264 boost::filesystem::directory_iterator file(searchpath); 265 boost::filesystem::directory_iterator end; 266 267 // Iterate through all files 268 while (file != end) 203 std::vector<std::string>& modulePaths = this->pathConfig_->getModulePaths(); 204 for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it) 205 { 206 try 269 207 { 270 std::string filename = file->BOOST_LEAF_FUNCTION(); 271 272 // Check if the file ends with the exension in question 273 if (filename.size() > moduleextensionlength) 274 { 275 if (filename.substr(filename.size() - moduleextensionlength) == moduleextension) 276 { 277 // We've found a helper file - now load the library with the same name 278 std::string library = filename.substr(0, filename.size() - moduleextensionlength); 279 boost::filesystem::path librarypath = searchpath / library; 280 281 try 282 { 283 DynLibManager::getInstance().load(librarypath.string()); 284 } 285 catch (...) 286 { 287 COUT(1) << "Couldn't load module \"" << librarypath.string() << "\": " << Exception::handleMessage() << std::endl; 288 } 289 } 290 } 291 292 ++file; 208 this->dynLibManager_->load(*it); 293 209 } 294 }295 catch (...)296 {297 COUT(1) << "An error occurred while loading modules: " << Exception::handleMessage() << std::endl;210 catch (...) 211 { 212 COUT(1) << "Couldn't load module \"" << *it << "\": " << Exception::handleMessage() << std::endl; 213 } 298 214 } 299 215 … … 302 218 303 219 // Set configurable paths like log, config and media 304 this-> setConfigurablePaths();220 this->pathConfig_->setConfigurablePaths(); 305 221 306 222 // create a signal handler (only active for linux) 307 223 // This call is placed as soon as possible, but after the directories are set 308 224 this->signalHandler_.reset(new SignalHandler()); 309 this->signalHandler_->doCatch( configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");225 this->signalHandler_->doCatch(PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log"); 310 226 311 227 // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used 312 OutputHandler::getOutStream().setLogPath( Core::getLogPathString());228 OutputHandler::getOutStream().setLogPath(PathConfig::getLogPathString()); 313 229 314 230 // Parse additional options file now that we know its path … … 343 259 344 260 // initialise Tcl 345 this->tclBind_.reset(new TclBind( Core::getDataPathString()));261 this->tclBind_.reset(new TclBind(PathConfig::getDataPathString())); 346 262 this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter())); 347 263 … … 456 372 } 457 373 458 /*static*/ void Core::tsetExternalDataPath(const std::string& path)459 {460 getInstance().configuration_->tsetExternalDataPath(path);461 }462 463 /*static*/ const boost::filesystem::path& Core::getDataPath()464 {465 return getInstance().configuration_->dataPath_;466 }467 /*static*/ std::string Core::getDataPathString()468 {469 return getInstance().configuration_->dataPath_.string() + '/';470 }471 472 /*static*/ const boost::filesystem::path& Core::getExternalDataPath()473 {474 return getInstance().configuration_->externalDataPath_;475 }476 /*static*/ std::string Core::getExternalDataPathString()477 {478 return getInstance().configuration_->externalDataPath_.string() + '/';479 }480 481 /*static*/ const boost::filesystem::path& Core::getConfigPath()482 {483 return getInstance().configuration_->configPath_;484 }485 /*static*/ std::string Core::getConfigPathString()486 {487 return getInstance().configuration_->configPath_.string() + '/';488 }489 490 /*static*/ const boost::filesystem::path& Core::getLogPath()491 {492 return getInstance().configuration_->logPath_;493 }494 /*static*/ std::string Core::getLogPathString()495 {496 return getInstance().configuration_->logPath_.string() + '/';497 }498 499 /*static*/ const boost::filesystem::path& Core::getRootPath()500 {501 return getInstance().configuration_->rootPath_;502 }503 /*static*/ std::string Core::getRootPathString()504 {505 return getInstance().configuration_->rootPath_.string() + '/';506 }507 508 374 /** 509 375 @note … … 552 418 } 553 419 554 /**555 @brief556 Retrievs the executable path and sets all hard coded fixed path (currently only the module path)557 Also checks for "orxonox_dev_build.keep_me" in the executable diretory.558 If found it means that this is not an installed run, hence we559 don't write the logs and config files to ~/.orxonox560 @throw561 GeneralException562 */563 void Core::setFixedPaths()564 {565 //////////////////////////566 // FIND EXECUTABLE PATH //567 //////////////////////////568 569 #ifdef ORXONOX_PLATFORM_WINDOWS570 // get executable module571 TCHAR buffer[1024];572 if (GetModuleFileName(NULL, buffer, 1024) == 0)573 ThrowException(General, "Could not retrieve executable path.");574 575 #elif defined(ORXONOX_PLATFORM_APPLE)576 char buffer[1024];577 unsigned long path_len = 1023;578 if (_NSGetExecutablePath(buffer, &path_len))579 ThrowException(General, "Could not retrieve executable path.");580 581 #else /* Linux */582 /* written by Nicolai Haehnle <prefect_@gmx.net> */583 584 /* Get our PID and build the name of the link in /proc */585 char linkname[64]; /* /proc/<pid>/exe */586 if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", getpid()) < 0)587 {588 /* This should only happen on large word systems. I'm not sure589 what the proper response is here.590 Since it really is an assert-like condition, aborting the591 program seems to be in order. */592 assert(false);593 }594 595 /* Now read the symbolic link */596 char buffer[1024];597 int ret;598 ret = readlink(linkname, buffer, 1024);599 /* In case of an error, leave the handling up to the caller */600 if (ret == -1)601 ThrowException(General, "Could not retrieve executable path.");602 603 /* Ensure proper NUL termination */604 buffer[ret] = 0;605 #endif606 607 configuration_->executablePath_ = boost::filesystem::path(buffer);608 #ifndef ORXONOX_PLATFORM_APPLE609 configuration_->executablePath_ = configuration_->executablePath_.branch_path(); // remove executable name610 #endif611 612 /////////////////////613 // SET MODULE PATH //614 /////////////////////615 616 if (boost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me"))617 {618 COUT(1) << "Running from the build tree." << std::endl;619 Core::bDevRun_ = true;620 configuration_->modulePath_ = specialConfig::moduleDevDirectory;621 }622 else623 {624 625 #ifdef INSTALL_COPYABLE // --> relative paths626 627 // Also set the root path628 boost::filesystem::path relativeExecutablePath(specialConfig::defaultRuntimePath);629 configuration_->rootPath_ = configuration_->executablePath_;630 while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_)631 && !configuration_->rootPath_.empty())632 configuration_->rootPath_ = configuration_->rootPath_.branch_path();633 if (configuration_->rootPath_.empty())634 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");635 636 // Module path is fixed as well637 configuration_->modulePath_ = configuration_->rootPath_ / specialConfig::defaultModulePath;638 639 #else640 641 // There is no root path, so don't set it at all642 // Module path is fixed as well643 configuration_->modulePath_ = specialConfig::moduleInstallDirectory;644 645 #endif646 }647 }648 649 /**650 @brief651 Sets config, log and media path and creates folders if necessary.652 @throws653 GeneralException654 */655 void Core::setConfigurablePaths()656 {657 if (Core::isDevelopmentRun())658 {659 configuration_->dataPath_ = specialConfig::dataDevDirectory;660 configuration_->externalDataPath_ = specialConfig::externalDataDevDirectory;661 configuration_->configPath_ = specialConfig::configDevDirectory;662 configuration_->logPath_ = specialConfig::logDevDirectory;663 }664 else665 {666 667 #ifdef INSTALL_COPYABLE // --> relative paths668 669 // Using paths relative to the install prefix, complete them670 configuration_->dataPath_ = configuration_->rootPath_ / specialConfig::defaultDataPath;671 configuration_->configPath_ = configuration_->rootPath_ / specialConfig::defaultConfigPath;672 configuration_->logPath_ = configuration_->rootPath_ / specialConfig::defaultLogPath;673 674 #else675 676 configuration_->dataPath_ = specialConfig::dataInstallDirectory;677 678 // Get user directory679 # ifdef ORXONOX_PLATFORM_UNIX /* Apple? */680 char* userDataPathPtr(getenv("HOME"));681 # else682 char* userDataPathPtr(getenv("APPDATA"));683 # endif684 if (userDataPathPtr == NULL)685 ThrowException(General, "Could not retrieve user data path.");686 boost::filesystem::path userDataPath(userDataPathPtr);687 userDataPath /= ".orxonox";688 689 configuration_->configPath_ = userDataPath / specialConfig::defaultConfigPath;690 configuration_->logPath_ = userDataPath / specialConfig::defaultLogPath;691 692 #endif693 694 }695 696 // Option to put all the config and log files in a separate folder697 if (!CommandLine::getArgument("writingPathSuffix")->hasDefaultValue())698 {699 std::string directory(CommandLine::getValue("writingPathSuffix").getString());700 configuration_->configPath_ = configuration_->configPath_ / directory;701 configuration_->logPath_ = configuration_->logPath_ / directory;702 }703 704 // Create directories to avoid problems when opening files in non existent folders.705 std::vector<std::pair<boost::filesystem::path, std::string> > directories;706 directories.push_back(std::make_pair(boost::filesystem::path(configuration_->configPath_), "config"));707 directories.push_back(std::make_pair(boost::filesystem::path(configuration_->logPath_), "log"));708 709 for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin();710 it != directories.end(); ++it)711 {712 if (boost::filesystem::exists(it->first) && !boost::filesystem::is_directory(it->first))713 {714 ThrowException(General, std::string("The ") + it->second + " directory has been preoccupied by a file! \715 Please remove " + it->first.string());716 }717 if (boost::filesystem::create_directories(it->first)) // function may not return true at all (bug?)718 {719 COUT(4) << "Created " << it->second << " directory" << std::endl;720 }721 }722 }723 724 420 void Core::preUpdate(const Clock& time) 725 421 { -
code/branches/core5/src/libraries/core/Core.h
r5738 r5836 28 28 */ 29 29 30 /**31 @file32 @brief33 Declaration of the Core class.34 @details35 The Core class is a singleton, only used to configure some variables36 in the core through the config-file.37 */38 39 30 #ifndef _Core_H__ 40 31 #define _Core_H__ … … 55 46 @brief 56 47 The Core class is a singleton used to configure the program basics. 57 @details58 The class provides information about the data, config and log path.59 It determines those by the use of platform specific functions.60 48 @remark 61 49 You should only create this singleton once because it destroys the identifiers! … … 85 73 static void resetLanguage(); 86 74 87 static void tsetExternalDataPath(const std::string& path);88 //! Returns the path to the data files as boost::filesystem::path89 static const boost::filesystem::path& getDataPath();90 //! Returns the path to the external data files as boost::filesystem::path91 static const boost::filesystem::path& getExternalDataPath();92 //! Returns the path to the config files as boost::filesystem::path93 static const boost::filesystem::path& getConfigPath();94 //! Returns the path to the log files as boost::filesystem::path95 static const boost::filesystem::path& getLogPath();96 //! Returns the path to the root folder as boost::filesystem::path97 static const boost::filesystem::path& getRootPath();98 //! Returns the path to the data files as std::string99 static std::string getDataPathString();100 //! Returns the path to the external data files as std::string101 static std::string getExternalDataPathString();102 //! Returns the path to the config files as std::string103 static std::string getConfigPathString();104 //! Returns the path to the log files as std::string105 static std::string getLogPathString();106 //! Returns the path to the root folder as std::string107 static std::string getRootPathString();108 109 static bool isDevelopmentRun() { return getInstance().bDevRun_; }110 111 75 private: 112 76 Core(const Core&); //!< Don't use (undefined symbol) … … 118 82 void unloadGraphics(); 119 83 120 void setFixedPaths();121 void setConfigurablePaths();122 84 void setThreadAffinity(int limitToCPU); 123 85 124 86 // Mind the order for the destruction! 87 scoped_ptr<PathConfig> pathConfig_; 125 88 scoped_ptr<DynLibManager> dynLibManager_; 126 89 scoped_ptr<SignalHandler> signalHandler_; … … 138 101 scoped_ptr<GUIManager> guiManager_; //!< Interface to GUI 139 102 140 bool bDevRun_; //!< True for runs in the build directory (not installed)141 103 bool bGraphicsLoaded_; 142 143 104 static Core* singletonPtr_s; 144 105 }; -
code/branches/core5/src/libraries/core/CorePrereqs.h
r5804 r5836 151 151 class OgreWindowEventListener; 152 152 class OrxonoxClass; 153 class PathConfig; 153 154 struct ResourceInfo; 154 155 class Shell; -
code/branches/core5/src/libraries/core/GUIManager.cc
r5819 r5836 55 55 #include "Clock.h" 56 56 #include "LuaState.h" 57 #include "PathConfig.h" 57 58 #include "Resource.h" 58 59 … … 116 117 // Create our own logger to specify the filepath 117 118 std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger()); 118 ceguiLogger->setLogFilename( Core::getLogPathString() + "cegui.log");119 ceguiLogger->setLogFilename(PathConfig::getLogPathString() + "cegui.log"); 119 120 // set the log level according to ours (translate by subtracting 1) 120 121 ceguiLogger->setLoggingLevel( -
code/branches/core5/src/libraries/core/GraphicsManager.cc
r5829 r5836 55 55 #include "ConfigValueIncludes.h" 56 56 #include "CoreIncludes.h" 57 #include "Core.h"58 57 #include "Game.h" 59 58 #include "GameMode.h" 60 59 #include "Loader.h" 61 60 #include "MemoryArchive.h" 61 #include "PathConfig.h" 62 62 #include "WindowEventListener.h" 63 63 #include "XMLFile.h" … … 102 102 103 103 // At first, add the root paths of the data directories as resource locations 104 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( Core::getDataPathString(), "FileSystem", "dataRoot", false);104 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getDataPathString(), "FileSystem", "dataRoot", false); 105 105 // Load resources 106 106 resources_.reset(new XMLFile("resources.oxr", "dataRoot")); … … 109 109 110 110 // Only for development runs 111 if ( Core::isDevelopmentRun())112 { 113 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( Core::getExternalDataPathString(), "FileSystem", "externalDataRoot", false);111 if (PathConfig::isDevelopmentRun()) 112 { 113 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getExternalDataPathString(), "FileSystem", "externalDataRoot", false); 114 114 extResources_.reset(new XMLFile("resources.oxr", "externalDataRoot")); 115 115 extResources_->setLuaSupport(false); … … 135 135 // Undeclare the resources 136 136 Loader::unload(resources_.get()); 137 if ( Core::isDevelopmentRun())137 if (PathConfig::isDevelopmentRun()) 138 138 Loader::unload(extResources_.get()); 139 139 } … … 246 246 } 247 247 248 boost::filesystem::path ogreConfigFilepath( Core::getConfigPath() / this->ogreConfigFile_);249 boost::filesystem::path ogreLogFilepath( Core::getLogPath() / this->ogreLogFile_);248 boost::filesystem::path ogreConfigFilepath(PathConfig::getConfigPath() / this->ogreConfigFile_); 249 boost::filesystem::path ogreLogFilepath(PathConfig::getLogPath() / this->ogreLogFile_); 250 250 251 251 // create a new logManager … … 422 422 assert(this->renderWindow_); 423 423 424 this->renderWindow_->writeContentsToTimestampedFile( Core::getLogPathString() + "screenShot_", ".jpg");424 this->renderWindow_->writeContentsToTimestampedFile(PathConfig::getLogPathString() + "screenShot_", ".jpg"); 425 425 } 426 426 } -
code/branches/core5/src/libraries/core/Language.cc
r5738 r5836 39 39 #include "util/Debug.h" 40 40 #include "Core.h" 41 #include "PathConfig.h" 41 42 42 43 namespace orxonox … … 200 201 COUT(4) << "Read default language file." << std::endl; 201 202 202 boost::filesystem::path filepath( Core::getConfigPath() / getFilename(this->defaultLanguage_));203 boost::filesystem::path filepath(PathConfig::getConfigPath() / getFilename(this->defaultLanguage_)); 203 204 204 205 // This creates the file if it's not existing … … 249 250 COUT(4) << "Read translated language file (" << Core::getLanguage() << ")." << std::endl; 250 251 251 boost::filesystem::path filepath( Core::getConfigPath() / getFilename(Core::getLanguage()));252 boost::filesystem::path filepath(PathConfig::getConfigPath() / getFilename(Core::getLanguage())); 252 253 253 254 // Open the file … … 303 304 COUT(4) << "Language: Write default language file." << std::endl; 304 305 305 boost::filesystem::path filepath( Core::getConfigPath() / getFilename(this->defaultLanguage_));306 boost::filesystem::path filepath(PathConfig::getConfigPath() / getFilename(this->defaultLanguage_)); 306 307 307 308 // Open the file -
code/branches/core5/src/libraries/core/LuaState.cc
r5759 r5836 37 37 38 38 #include "util/Debug.h" 39 #include "Core.h"40 39 #include "Resource.h" 41 40 #include "ToluaBindCore.h" -
code/branches/core5/src/libraries/core/PathConfig.cc
r5832 r5836 21 21 * 22 22 * Author: 23 * Fabian 'x3n' Landau24 23 * Reto Grieder 25 24 * Co-authors: … … 28 27 */ 29 28 30 /** 31 @file 32 @brief 33 Implementation of the Core singleton with its global variables (avoids boost include) 34 */ 35 36 #include "Core.h" 29 #include "PathConfig.h" 37 30 38 31 #include <cassert> 39 #include <fstream>40 32 #include <cstdlib> 41 33 #include <cstdio> 34 #include <vector> 42 35 #include <boost/version.hpp> 43 36 #include <boost/filesystem.hpp> … … 61 54 #include "util/Debug.h" 62 55 #include "util/Exception.h" 63 #include "util/SignalHandler.h"64 #include "Clock.h"65 #include "CommandExecutor.h"66 56 #include "CommandLine.h" 67 #include "ConfigFileManager.h"68 #include "ConfigValueIncludes.h"69 #include "CoreIncludes.h"70 #include "DynLibManager.h"71 #include "GameMode.h"72 #include "GraphicsManager.h"73 #include "GUIManager.h"74 #include "Identifier.h"75 #include "Language.h"76 #include "LuaState.h"77 #include "Shell.h"78 #include "TclBind.h"79 #include "TclThreadManager.h"80 #include "input/InputManager.h"81 57 82 58 // Boost 1.36 has some issues with deprecated functions that have been omitted … … 89 65 namespace orxonox 90 66 { 67 namespace bf = boost::filesystem; 68 91 69 //! Static pointer to the singleton 92 Core* Core::singletonPtr_s = 0;70 PathConfig* PathConfig::singletonPtr_s = 0; 93 71 94 72 SetCommandLineArgument(externalDataPath, "").information("Path to the external data files"); 95 73 SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files"); 96 SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file"); 97 #ifdef ORXONOX_PLATFORM_WINDOWS 98 SetCommandLineArgument(limitToCPU, 0).information("Limits the program to one cpu/core (1, 2, 3, etc.). 0 turns it off (default)"); 99 #endif 100 101 /** 102 @brief 103 Helper class for the Core singleton: we cannot derive 104 Core from OrxonoxClass because we need to handle the Identifier 105 destruction in the Core destructor. 106 */ 107 class CoreConfiguration : public OrxonoxClass 108 { 109 public: 110 CoreConfiguration() 111 { 112 } 113 114 void initialise() 115 { 116 RegisterRootObject(CoreConfiguration); 117 this->setConfigValues(); 118 119 // External data directory only exists for dev runs 120 if (Core::isDevelopmentRun()) 121 { 122 // Possible data path override by the command line 123 if (!CommandLine::getArgument("externalDataPath")->hasDefaultValue()) 124 tsetExternalDataPath(CommandLine::getValue("externalDataPath")); 125 } 126 } 127 128 /** 129 @brief Function to collect the SetConfigValue-macro calls. 130 */ 131 void setConfigValues() 132 { 133 #ifdef NDEBUG 134 const unsigned int defaultLevelConsole = 1; 135 const unsigned int defaultLevelLogfile = 3; 136 const unsigned int defaultLevelShell = 1; 137 #else 138 const unsigned int defaultLevelConsole = 3; 139 const unsigned int defaultLevelLogfile = 4; 140 const unsigned int defaultLevelShell = 3; 141 #endif 142 SetConfigValue(softDebugLevelConsole_, defaultLevelConsole) 143 .description("The maximal level of debug output shown in the console") 144 .callback(this, &CoreConfiguration::debugLevelChanged); 145 SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile) 146 .description("The maximal level of debug output shown in the logfile") 147 .callback(this, &CoreConfiguration::debugLevelChanged); 148 SetConfigValue(softDebugLevelShell_, defaultLevelShell) 149 .description("The maximal level of debug output shown in the ingame shell") 150 .callback(this, &CoreConfiguration::debugLevelChanged); 151 152 SetConfigValue(language_, Language::getInstance().defaultLanguage_) 153 .description("The language of the ingame text") 154 .callback(this, &CoreConfiguration::languageChanged); 155 SetConfigValue(bInitializeRandomNumberGenerator_, true) 156 .description("If true, all random actions are different each time you start the game") 157 .callback(this, &CoreConfiguration::initializeRandomNumberGenerator); 158 } 159 160 /** 161 @brief Callback function if the debug level has changed. 162 */ 163 void debugLevelChanged() 164 { 165 // softDebugLevel_ is the maximum of the 3 variables 166 this->softDebugLevel_ = this->softDebugLevelConsole_; 167 if (this->softDebugLevelLogfile_ > this->softDebugLevel_) 168 this->softDebugLevel_ = this->softDebugLevelLogfile_; 169 if (this->softDebugLevelShell_ > this->softDebugLevel_) 170 this->softDebugLevel_ = this->softDebugLevelShell_; 171 172 OutputHandler::setSoftDebugLevel(OutputHandler::LD_All, this->softDebugLevel_); 173 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_); 174 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_); 175 OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell, this->softDebugLevelShell_); 176 } 177 178 /** 179 @brief Callback function if the language has changed. 180 */ 181 void languageChanged() 182 { 183 // Read the translation file after the language was configured 184 Language::getInstance().readTranslatedLanguageFile(); 185 } 186 187 /** 188 @brief Sets the language in the config-file back to the default. 189 */ 190 void resetLanguage() 191 { 192 ResetConfigValue(language_); 193 } 194 195 /** 196 @brief 197 Temporary sets the external data path 198 @param path 199 The new data path 200 */ 201 void tsetExternalDataPath(const std::string& path) 202 { 203 externalDataPath_ = boost::filesystem::path(path); 204 } 205 206 void initializeRandomNumberGenerator() 207 { 208 static bool bInitialized = false; 209 if (!bInitialized && this->bInitializeRandomNumberGenerator_) 210 { 211 srand(static_cast<unsigned int>(time(0))); 212 rand(); 213 bInitialized = true; 214 } 215 } 216 217 int softDebugLevel_; //!< The debug level 218 int softDebugLevelConsole_; //!< The debug level for the console 219 int softDebugLevelLogfile_; //!< The debug level for the logfile 220 int softDebugLevelShell_; //!< The debug level for the ingame shell 221 std::string language_; //!< The language 222 bool bInitializeRandomNumberGenerator_; //!< If true, srand(time(0)) is called 223 224 //! Path to the parent directory of the ones above if program was installed with relativ pahts 225 boost::filesystem::path rootPath_; 226 boost::filesystem::path executablePath_; //!< Path to the executable 227 boost::filesystem::path modulePath_; //!< Path to the modules 228 boost::filesystem::path dataPath_; //!< Path to the data file folder 229 boost::filesystem::path externalDataPath_; //!< Path to the external data file folder 230 boost::filesystem::path configPath_; //!< Path to the config file folder 231 boost::filesystem::path logPath_; //!< Path to the log file folder 232 }; 233 234 235 Core::Core(const std::string& cmdLine) 236 // Cleanup guard for identifier destruction (incl. XMLPort, configValues, consoleCommands) 237 : identifierDestroyer_(Identifier::destroyAllIdentifiers) 238 // Cleanup guard for external console commands that don't belong to an Identifier 239 , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands) 240 , configuration_(new CoreConfiguration()) // Don't yet create config values! 74 75 PathConfig::PathConfig() 76 : rootPath_(*(new bf::path())) 77 , executablePath_(*(new bf::path())) 78 , modulePath_(*(new bf::path())) 79 , dataPath_(*(new bf::path())) 80 , externalDataPath_(*(new bf::path())) 81 , configPath_(*(new bf::path())) 82 , logPath_(*(new bf::path())) 241 83 , bDevRun_(false) 242 , bGraphicsLoaded_(false)243 {244 // Set the hard coded fixed paths245 this->setFixedPaths();246 247 // Create a new dynamic library manager248 this->dynLibManager_.reset(new DynLibManager());249 250 // Load modules251 try252 {253 // We search for helper files with the following extension254 std::string moduleextension = specialConfig::moduleExtension;255 size_t moduleextensionlength = moduleextension.size();256 257 // Search in the directory of our executable258 boost::filesystem::path searchpath = this->configuration_->modulePath_;259 260 // Add that path to the PATH variable in case a module depends on another one261 std::string pathVariable = getenv("PATH");262 putenv(const_cast<char*>(("PATH=" + pathVariable + ";" + configuration_->modulePath_.string()).c_str()));263 264 boost::filesystem::directory_iterator file(searchpath);265 boost::filesystem::directory_iterator end;266 267 // Iterate through all files268 while (file != end)269 {270 std::string filename = file->BOOST_LEAF_FUNCTION();271 272 // Check if the file ends with the exension in question273 if (filename.size() > moduleextensionlength)274 {275 if (filename.substr(filename.size() - moduleextensionlength) == moduleextension)276 {277 // We've found a helper file - now load the library with the same name278 std::string library = filename.substr(0, filename.size() - moduleextensionlength);279 boost::filesystem::path librarypath = searchpath / library;280 281 try282 {283 DynLibManager::getInstance().load(librarypath.string());284 }285 catch (...)286 {287 COUT(1) << "Couldn't load module \"" << librarypath.string() << "\": " << Exception::handleMessage() << std::endl;288 }289 }290 }291 292 ++file;293 }294 }295 catch (...)296 {297 COUT(1) << "An error occurred while loading modules: " << Exception::handleMessage() << std::endl;298 }299 300 // Parse command line arguments AFTER the modules have been loaded (static code!)301 CommandLine::parseCommandLine(cmdLine);302 303 // Set configurable paths like log, config and media304 this->setConfigurablePaths();305 306 // create a signal handler (only active for linux)307 // This call is placed as soon as possible, but after the directories are set308 this->signalHandler_.reset(new SignalHandler());309 this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");310 311 // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used312 OutputHandler::getOutStream().setLogPath(Core::getLogPathString());313 314 // Parse additional options file now that we know its path315 CommandLine::parseFile();316 317 #ifdef ORXONOX_PLATFORM_WINDOWS318 // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump319 // do this after ogre has initialised. Somehow Ogre changes the settings again (not through320 // the timer though).321 int limitToCPU = CommandLine::getValue("limitToCPU");322 if (limitToCPU > 0)323 setThreadAffinity(static_cast<unsigned int>(limitToCPU));324 #endif325 326 // Manage ini files and set the default settings file (usually orxonox.ini)327 this->configFileManager_.reset(new ConfigFileManager());328 this->configFileManager_->setFilename(ConfigFileType::Settings,329 CommandLine::getValue("settingsFile").getString());330 331 // Required as well for the config values332 this->languageInstance_.reset(new Language());333 334 // creates the class hierarchy for all classes with factories335 Identifier::createClassHierarchy();336 337 // Do this soon after the ConfigFileManager has been created to open up the338 // possibility to configure everything below here339 this->configuration_->initialise();340 341 // Load OGRE excluding the renderer and the render window342 this->graphicsManager_.reset(new GraphicsManager(false));343 344 // initialise Tcl345 this->tclBind_.reset(new TclBind(Core::getDataPathString()));346 this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));347 348 // create a shell349 this->shell_.reset(new Shell());350 }351 352 /**353 @brief354 All destruction code is handled by scoped_ptrs and ScopeGuards.355 */356 Core::~Core()357 {358 }359 360 void Core::loadGraphics()361 {362 // Any exception should trigger this, even in upgradeToGraphics (see its remarks)363 Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics);364 365 // Upgrade OGRE to receive a render window366 graphicsManager_->upgradeToGraphics();367 368 // Calls the InputManager which sets up the input devices.369 inputManager_.reset(new InputManager());370 371 // load the CEGUI interface372 guiManager_.reset(new GUIManager(graphicsManager_->getRenderWindow(),373 inputManager_->getMousePosition(), graphicsManager_->isFullScreen()));374 375 unloader.Dismiss();376 377 bGraphicsLoaded_ = true;378 }379 380 void Core::unloadGraphics()381 {382 this->guiManager_.reset();;383 this->inputManager_.reset();;384 this->graphicsManager_.reset();385 386 // Load Ogre::Root again, but without the render system387 try388 { this->graphicsManager_.reset(new GraphicsManager(false)); }389 catch (...)390 {391 COUT(0) << "An exception occurred during 'unloadGraphics':" << Exception::handleMessage() << std::endl392 << "Another exception might be being handled which may lead to undefined behaviour!" << std::endl393 << "Terminating the program." << std::endl;394 abort();395 }396 397 bGraphicsLoaded_ = false;398 }399 400 /**401 @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).402 @param device The device403 @return The softDebugLevel404 */405 /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)406 {407 switch (device)408 {409 case OutputHandler::LD_All:410 return Core::getInstance().configuration_->softDebugLevel_;411 case OutputHandler::LD_Console:412 return Core::getInstance().configuration_->softDebugLevelConsole_;413 case OutputHandler::LD_Logfile:414 return Core::getInstance().configuration_->softDebugLevelLogfile_;415 case OutputHandler::LD_Shell:416 return Core::getInstance().configuration_->softDebugLevelShell_;417 default:418 assert(0);419 return 2;420 }421 }422 423 /**424 @brief Sets the softDebugLevel for the given device. Please use this only temporary and restore the value afterwards, as it overrides the configured value.425 @param device The device426 @param level The level427 */428 /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)429 {430 if (device == OutputHandler::LD_All)431 Core::getInstance().configuration_->softDebugLevel_ = level;432 else if (device == OutputHandler::LD_Console)433 Core::getInstance().configuration_->softDebugLevelConsole_ = level;434 else if (device == OutputHandler::LD_Logfile)435 Core::getInstance().configuration_->softDebugLevelLogfile_ = level;436 else if (device == OutputHandler::LD_Shell)437 Core::getInstance().configuration_->softDebugLevelShell_ = level;438 439 OutputHandler::setSoftDebugLevel(device, level);440 }441 442 /**443 @brief Returns the configured language.444 */445 /*static*/ const std::string& Core::getLanguage()446 {447 return Core::getInstance().configuration_->language_;448 }449 450 /**451 @brief Sets the language in the config-file back to the default.452 */453 /*static*/ void Core::resetLanguage()454 {455 Core::getInstance().configuration_->resetLanguage();456 }457 458 /*static*/ void Core::tsetExternalDataPath(const std::string& path)459 {460 getInstance().configuration_->tsetExternalDataPath(path);461 }462 463 /*static*/ const boost::filesystem::path& Core::getDataPath()464 {465 return getInstance().configuration_->dataPath_;466 }467 /*static*/ std::string Core::getDataPathString()468 {469 return getInstance().configuration_->dataPath_.string() + '/';470 }471 472 /*static*/ const boost::filesystem::path& Core::getExternalDataPath()473 {474 return getInstance().configuration_->externalDataPath_;475 }476 /*static*/ std::string Core::getExternalDataPathString()477 {478 return getInstance().configuration_->externalDataPath_.string() + '/';479 }480 481 /*static*/ const boost::filesystem::path& Core::getConfigPath()482 {483 return getInstance().configuration_->configPath_;484 }485 /*static*/ std::string Core::getConfigPathString()486 {487 return getInstance().configuration_->configPath_.string() + '/';488 }489 490 /*static*/ const boost::filesystem::path& Core::getLogPath()491 {492 return getInstance().configuration_->logPath_;493 }494 /*static*/ std::string Core::getLogPathString()495 {496 return getInstance().configuration_->logPath_.string() + '/';497 }498 499 /*static*/ const boost::filesystem::path& Core::getRootPath()500 {501 return getInstance().configuration_->rootPath_;502 }503 /*static*/ std::string Core::getRootPathString()504 {505 return getInstance().configuration_->rootPath_.string() + '/';506 }507 508 /**509 @note510 The code of this function has been copied and adjusted from OGRE, an open source graphics engine.511 (Object-oriented Graphics Rendering Engine)512 For the latest info, see http://www.ogre3d.org/513 514 Copyright (c) 2000-2008 Torus Knot Software Ltd515 516 OGRE is licensed under the LGPL. For more info, see OGRE license.517 */518 void Core::setThreadAffinity(int limitToCPU)519 {520 #ifdef ORXONOX_PLATFORM_WINDOWS521 522 if (limitToCPU <= 0)523 return;524 525 unsigned int coreNr = limitToCPU - 1;526 // Get the current process core mask527 DWORD procMask;528 DWORD sysMask;529 # if _MSC_VER >= 1400 && defined (_M_X64)530 GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);531 # else532 GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask);533 # endif534 535 // If procMask is 0, consider there is only one core available536 // (using 0 as procMask will cause an infinite loop below)537 if (procMask == 0)538 procMask = 1;539 540 // if the core specified with coreNr is not available, take the lowest one541 if (!(procMask & (1 << coreNr)))542 coreNr = 0;543 544 // Find the lowest core that this process uses and coreNr suggests545 DWORD threadMask = 1;546 while ((threadMask & procMask) == 0 || (threadMask < (1u << coreNr)))547 threadMask <<= 1;548 549 // Set affinity to the first core550 SetThreadAffinityMask(GetCurrentThread(), threadMask);551 #endif552 }553 554 /**555 @brief556 Retrievs the executable path and sets all hard coded fixed path (currently only the module path)557 Also checks for "orxonox_dev_build.keep_me" in the executable diretory.558 If found it means that this is not an installed run, hence we559 don't write the logs and config files to ~/.orxonox560 @throw561 GeneralException562 */563 void Core::setFixedPaths()564 84 { 565 85 ////////////////////////// … … 605 125 #endif 606 126 607 configuration_->executablePath_ = boost::filesystem::path(buffer);127 executablePath_ = bf::path(buffer); 608 128 #ifndef ORXONOX_PLATFORM_APPLE 609 configuration_->executablePath_ = configuration_->executablePath_.branch_path(); // remove executable name129 executablePath_ = executablePath_.branch_path(); // remove executable name 610 130 #endif 611 131 … … 614 134 ///////////////////// 615 135 616 if (b oost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me"))136 if (bf::exists(executablePath_ / "orxonox_dev_build.keep_me")) 617 137 { 618 138 COUT(1) << "Running from the build tree." << std::endl; 619 Core::bDevRun_ = true;620 configuration_->modulePath_ = specialConfig::moduleDevDirectory;139 PathConfig::bDevRun_ = true; 140 modulePath_ = specialConfig::moduleDevDirectory; 621 141 } 622 142 else … … 626 146 627 147 // Also set the root path 628 boost::filesystem::path relativeExecutablePath(specialConfig::defaultRuntimePath); 629 configuration_->rootPath_ = configuration_->executablePath_; 630 while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_) 631 && !configuration_->rootPath_.empty()) 632 configuration_->rootPath_ = configuration_->rootPath_.branch_path(); 633 if (configuration_->rootPath_.empty()) 148 bf::path relativeExecutablePath(specialConfig::defaultRuntimePath); 149 rootPath_ = executablePath_; 150 while (!bf::equivalent(rootPath_ / relativeExecutablePath, executablePath_) && !rootPath_.empty()) 151 rootPath_ = rootPath_.branch_path(); 152 if (rootPath_.empty()) 634 153 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?"); 635 154 636 155 // Module path is fixed as well 637 configuration_->modulePath_ = configuration_->rootPath_ / specialConfig::defaultModulePath;156 modulePath_ = rootPath_ / specialConfig::defaultModulePath; 638 157 639 158 #else … … 641 160 // There is no root path, so don't set it at all 642 161 // Module path is fixed as well 643 configuration_->modulePath_ = specialConfig::moduleInstallDirectory; 644 645 #endif 646 } 647 } 648 649 /** 650 @brief 651 Sets config, log and media path and creates folders if necessary. 652 @throws 653 GeneralException 654 */ 655 void Core::setConfigurablePaths() 656 { 657 if (Core::isDevelopmentRun()) 658 { 659 configuration_->dataPath_ = specialConfig::dataDevDirectory; 660 configuration_->externalDataPath_ = specialConfig::externalDataDevDirectory; 661 configuration_->configPath_ = specialConfig::configDevDirectory; 662 configuration_->logPath_ = specialConfig::logDevDirectory; 162 modulePath_ = specialConfig::moduleInstallDirectory; 163 164 #endif 165 } 166 } 167 168 PathConfig::~PathConfig() 169 { 170 delete &rootPath_; 171 delete &executablePath_; 172 delete &modulePath_; 173 delete &dataPath_; 174 delete &externalDataPath_; 175 delete &configPath_; 176 delete &logPath_; 177 } 178 179 void PathConfig::setConfigurablePaths() 180 { 181 if (bDevRun_) 182 { 183 dataPath_ = specialConfig::dataDevDirectory; 184 configPath_ = specialConfig::configDevDirectory; 185 logPath_ = specialConfig::logDevDirectory; 186 187 // Check for data path override by the command line 188 if (!CommandLine::getArgument("externalDataPath")->hasDefaultValue()) 189 externalDataPath_ = CommandLine::getValue("externalDataPath").getString(); 190 else 191 externalDataPath_ = specialConfig::externalDataDevDirectory; 663 192 } 664 193 else … … 668 197 669 198 // Using paths relative to the install prefix, complete them 670 configuration_->dataPath_ = configuration_->rootPath_ / specialConfig::defaultDataPath;671 config uration_->configPath_ = configuration_->rootPath_ / specialConfig::defaultConfigPath;672 configuration_->logPath_ = configuration_->rootPath_ / specialConfig::defaultLogPath;199 dataPath_ = rootPath_ / specialConfig::defaultDataPath; 200 configPath_ = rootPath_ / specialConfig::defaultConfigPath; 201 logPath_ = rootPath_ / specialConfig::defaultLogPath; 673 202 674 203 #else 675 204 676 configuration_->dataPath_ = specialConfig::dataInstallDirectory;205 dataPath_ = specialConfig::dataInstallDirectory; 677 206 678 207 // Get user directory … … 684 213 if (userDataPathPtr == NULL) 685 214 ThrowException(General, "Could not retrieve user data path."); 686 b oost::filesystem::path userDataPath(userDataPathPtr);215 bf::path userDataPath(userDataPathPtr); 687 216 userDataPath /= ".orxonox"; 688 217 689 config uration_->configPath_ = userDataPath / specialConfig::defaultConfigPath;690 configuration_->logPath_ = userDataPath / specialConfig::defaultLogPath;218 configPath_ = userDataPath / specialConfig::defaultConfigPath; 219 logPath_ = userDataPath / specialConfig::defaultLogPath; 691 220 692 221 #endif … … 698 227 { 699 228 std::string directory(CommandLine::getValue("writingPathSuffix").getString()); 700 config uration_->configPath_ = configuration_->configPath_ / directory;701 configuration_->logPath_ = configuration_->logPath_ / directory;229 configPath_ = configPath_ / directory; 230 logPath_ = logPath_ / directory; 702 231 } 703 232 704 233 // Create directories to avoid problems when opening files in non existent folders. 705 std::vector<std::pair<b oost::filesystem::path, std::string> > directories;706 directories.push_back(std::make_pair(b oost::filesystem::path(configuration_->configPath_), "config"));707 directories.push_back(std::make_pair(b oost::filesystem::path(configuration_->logPath_), "log"));708 709 for (std::vector<std::pair<b oost::filesystem::path, std::string> >::iterator it = directories.begin();234 std::vector<std::pair<bf::path, std::string> > directories; 235 directories.push_back(std::make_pair(bf::path(configPath_), "config")); 236 directories.push_back(std::make_pair(bf::path(logPath_), "log")); 237 238 for (std::vector<std::pair<bf::path, std::string> >::iterator it = directories.begin(); 710 239 it != directories.end(); ++it) 711 240 { 712 if (b oost::filesystem::exists(it->first) && !boost::filesystem::is_directory(it->first))241 if (bf::exists(it->first) && !bf::is_directory(it->first)) 713 242 { 714 243 ThrowException(General, std::string("The ") + it->second + " directory has been preoccupied by a file! \ 715 244 Please remove " + it->first.string()); 716 245 } 717 if (b oost::filesystem::create_directories(it->first)) // function may not return true at all (bug?)246 if (bf::create_directories(it->first)) // function may not return true at all (bug?) 718 247 { 719 248 COUT(4) << "Created " << it->second << " directory" << std::endl; … … 722 251 } 723 252 724 void Core::preUpdate(const Clock& time) 725 { 726 if (this->bGraphicsLoaded_) 727 { 728 // process input events 729 this->inputManager_->update(time); 730 // process gui events 731 this->guiManager_->update(time); 732 } 733 // process thread commands 734 this->tclThreadManager_->update(time); 735 } 736 737 void Core::postUpdate(const Clock& time) 738 { 739 if (this->bGraphicsLoaded_) 740 { 741 // Render (doesn't throw) 742 this->graphicsManager_->update(time); 743 } 253 std::vector<std::string> PathConfig::getModulePaths() 254 { 255 std::vector<std::string> modulePaths; 256 257 // We search for helper files with the following extension 258 std::string moduleextension = specialConfig::moduleExtension; 259 size_t moduleextensionlength = moduleextension.size(); 260 261 // Add that path to the PATH variable in case a module depends on another one 262 std::string pathVariable = getenv("PATH"); 263 putenv(const_cast<char*>(("PATH=" + pathVariable + ";" + modulePath_.string()).c_str())); 264 265 boost::filesystem::directory_iterator file(modulePath_); 266 boost::filesystem::directory_iterator end; 267 268 // Iterate through all files 269 while (file != end) 270 { 271 std::string filename = file->BOOST_LEAF_FUNCTION(); 272 273 // Check if the file ends with the exension in question 274 if (filename.size() > moduleextensionlength) 275 { 276 if (filename.substr(filename.size() - moduleextensionlength) == moduleextension) 277 { 278 // We've found a helper file 279 std::string library = filename.substr(0, filename.size() - moduleextensionlength); 280 modulePaths.push_back((modulePath_ / library).string()); 281 } 282 } 283 ++file; 284 } 285 286 return modulePaths; 287 } 288 289 /*static*/ std::string PathConfig::getRootPathString() 290 { 291 return getInstance().rootPath_.string() + '/'; 292 } 293 294 /*static*/ std::string PathConfig::getExecutablePathString() 295 { 296 return getInstance().executablePath_.string() + '/'; 297 } 298 299 /*static*/ std::string PathConfig::getDataPathString() 300 { 301 return getInstance().dataPath_.string() + '/'; 302 } 303 304 /*static*/ std::string PathConfig::getExternalDataPathString() 305 { 306 return getInstance().externalDataPath_.string() + '/'; 307 } 308 309 /*static*/ std::string PathConfig::getConfigPathString() 310 { 311 return getInstance().configPath_.string() + '/'; 312 } 313 314 /*static*/ std::string PathConfig::getLogPathString() 315 { 316 return getInstance().logPath_.string() + '/'; 317 } 318 319 /*static*/ std::string PathConfig::getModulePathString() 320 { 321 return getInstance().modulePath_.string() + '/'; 744 322 } 745 323 } -
code/branches/core5/src/libraries/core/PathConfig.h
r5832 r5836 21 21 * 22 22 * Author: 23 * Fabian 'x3n' Landau24 23 * Reto Grieder 25 24 * Co-authors: … … 28 27 */ 29 28 30 /** 31 @file 32 @brief 33 Declaration of the Core class. 34 @details 35 The Core class is a singleton, only used to configure some variables 36 in the core through the config-file. 37 */ 38 39 #ifndef _Core_H__ 40 #define _Core_H__ 29 #ifndef _PathConfig_H__ 30 #define _PathConfig_H__ 41 31 42 32 #include "CorePrereqs.h" 43 33 44 #include <cassert> 45 #include <boost/scoped_ptr.hpp> 46 #include "util/OutputHandler.h" 47 #include "util/ScopeGuard.h" 34 #include <string> 48 35 #include "util/Singleton.h" 49 36 50 37 namespace orxonox 51 38 { 52 class CoreConfiguration;53 54 39 /** 55 40 @brief 56 The Core class is a singleton used to configure the program basics.41 The PathConfig class is a singleton used to configure different paths. 57 42 @details 58 The class provides information about the data, config and log path. 43 The class provides information about the data, config, log, executable, 44 root and module path. 59 45 It determines those by the use of platform specific functions. 60 @remark 61 You should only create this singleton once because it destroys the identifiers! 46 @remarks 47 Not all paths are always available: 48 - root only when installed copyable 49 - externalData only for development builds in the build tree 62 50 */ 63 class _CoreExport Core : public Singleton<Core>51 class _CoreExport PathConfig : public Singleton<PathConfig> 64 52 { 65 typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard; 66 friend class Singleton<Core>; 67 friend class Game; 53 friend class Singleton<PathConfig>; 54 friend class Core; 68 55 69 56 public: 70 57 /** 71 58 @brief 72 Determines the executable path, checks for build directory runs, creates 73 the output directories and sets up the other core library singletons. 74 @throws 59 Retrievs the executable path and sets all hard coded fixed paths (currently only the module path) 60 Also checks for "orxonox_dev_build.keep_me" in the executable diretory. 61 If found it means that this is not an installed run, hence we 62 don't write the logs and config files to ~/.orxonox 63 @throw 75 64 GeneralException 76 65 */ 77 Core(const std::string& cmdLine);78 ~ Core();66 PathConfig(); 67 ~PathConfig(); 79 68 80 void setConfigValues(); 69 //! Returns the path to the root folder as boost::filesystem::path 70 static const boost::filesystem::path& getRootPath() 71 { return getInstance().rootPath_; } 72 //! Returns the path to the executable folder as boost::filesystem::path 73 static const boost::filesystem::path& getExecutablePath() 74 { return getInstance().executablePath_; } 75 //! Returns the path to the data files as boost::filesystem::path 76 static const boost::filesystem::path& getDataPath() 77 { return getInstance().dataPath_; } 78 //! Returns the path to the external data files as boost::filesystem::path 79 static const boost::filesystem::path& getExternalDataPath() 80 { return getInstance().externalDataPath_; } 81 //! Returns the path to the config files as boost::filesystem::path 82 static const boost::filesystem::path& getConfigPath() 83 { return getInstance().configPath_; } 84 //! Returns the path to the log files as boost::filesystem::path 85 static const boost::filesystem::path& getLogPath() 86 { return getInstance().logPath_; } 87 //! Returns the path to the modules as boost::filesystem::path 88 static const boost::filesystem::path& getModulePath() 89 { return getInstance().modulePath_; } 81 90 82 static int getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All); 83 static void setSoftDebugLevel(OutputHandler::OutputDevice device, int level); 84 static const std::string& getLanguage(); 85 static void resetLanguage(); 86 87 static void tsetExternalDataPath(const std::string& path); 88 //! Returns the path to the data files as boost::filesystem::path 89 static const boost::filesystem::path& getDataPath(); 90 //! Returns the path to the external data files as boost::filesystem::path 91 static const boost::filesystem::path& getExternalDataPath(); 92 //! Returns the path to the config files as boost::filesystem::path 93 static const boost::filesystem::path& getConfigPath(); 94 //! Returns the path to the log files as boost::filesystem::path 95 static const boost::filesystem::path& getLogPath(); 96 //! Returns the path to the root folder as boost::filesystem::path 97 static const boost::filesystem::path& getRootPath(); 91 //! Returns the path to the root folder as std::string 92 static std::string getRootPathString(); 93 //! Returns the path to the executable folder as std::string 94 static std::string getExecutablePathString(); 98 95 //! Returns the path to the data files as std::string 99 96 static std::string getDataPathString(); … … 104 101 //! Returns the path to the log files as std::string 105 102 static std::string getLogPathString(); 106 //! Returns the path to the root folderas std::string107 static std::string get RootPathString();103 //! Returns the path to the modules as std::string 104 static std::string getModulePathString(); 108 105 106 //! Return trrue for runs in the build directory (not installed) 109 107 static bool isDevelopmentRun() { return getInstance().bDevRun_; } 110 108 111 109 private: 112 Core(const Core&); //!< Don't use (undefined symbol)110 PathConfig(const PathConfig&); //!< Don't use (undefined symbol) 113 111 114 void preUpdate(const Clock& time); 115 void postUpdate(const Clock& time); 112 /** 113 @brief 114 Sets config, log and media path and creates the folders if necessary. 115 @throws 116 GeneralException 117 */ 118 void setConfigurablePaths(); 119 //! Returns a list with all modules declared by a *.module file in the module folder. 120 std::vector<std::string> getModulePaths(); 116 121 117 void loadGraphics(); 118 void unloadGraphics(); 122 //! Path to the parent directory of the ones above if program was installed with relativ paths 123 boost::filesystem::path& rootPath_; 124 boost::filesystem::path& executablePath_; //!< Path to the executable 125 boost::filesystem::path& modulePath_; //!< Path to the modules 126 boost::filesystem::path& dataPath_; //!< Path to the data files folder 127 boost::filesystem::path& externalDataPath_; //!< Path to the external data files folder 128 boost::filesystem::path& configPath_; //!< Path to the config files folder 129 boost::filesystem::path& logPath_; //!< Path to the log files folder 119 130 120 void setFixedPaths(); 121 void setConfigurablePaths(); 122 void setThreadAffinity(int limitToCPU); 123 124 // Mind the order for the destruction! 125 scoped_ptr<DynLibManager> dynLibManager_; 126 scoped_ptr<SignalHandler> signalHandler_; 127 SimpleScopeGuard identifierDestroyer_; 128 SimpleScopeGuard consoleCommandDestroyer_; 129 scoped_ptr<ConfigFileManager> configFileManager_; 130 scoped_ptr<Language> languageInstance_; 131 scoped_ptr<CoreConfiguration> configuration_; 132 scoped_ptr<TclBind> tclBind_; 133 scoped_ptr<TclThreadManager> tclThreadManager_; 134 scoped_ptr<Shell> shell_; 135 // graphical 136 scoped_ptr<GraphicsManager> graphicsManager_; //!< Interface to OGRE 137 scoped_ptr<InputManager> inputManager_; //!< Interface to OIS 138 scoped_ptr<GUIManager> guiManager_; //!< Interface to GUI 139 140 bool bDevRun_; //!< True for runs in the build directory (not installed) 141 bool bGraphicsLoaded_; 142 143 static Core* singletonPtr_s; 131 bool bDevRun_; //!< True for runs in the build directory (not installed) 132 static PathConfig* singletonPtr_s; 144 133 }; 145 134 } 146 135 147 #endif /* _ Core_H__ */136 #endif /* _PathConfig_H__ */ -
code/branches/core5/src/libraries/core/TclBind.cc
r5747 r5836 39 39 #include "CommandExecutor.h" 40 40 #include "ConsoleCommand.h" 41 #include " Core.h"41 #include "PathConfig.h" 42 42 #include "TclThreadManager.h" 43 43 … … 123 123 { 124 124 #ifdef DEPENDENCY_PACKAGE_ENABLE 125 if ( Core::isDevelopmentRun())125 if (PathConfig::isDevelopmentRun()) 126 126 return (std::string(specialConfig::dependencyLibraryDirectory) + "/tcl"); 127 127 else 128 return ( Core::getRootPathString() + "lib/tcl");128 return (PathConfig::getRootPathString() + "lib/tcl"); 129 129 #else 130 130 return ""; -
code/branches/core5/src/libraries/tools/ResourceLocation.cc
r5747 r5836 33 33 34 34 #include "util/Exception.h" 35 #include "core/Core.h"36 35 #include "core/CoreIncludes.h" 36 #include "core/PathConfig.h" 37 37 #include "core/XMLFile.h" 38 38 #include "core/XMLPort.h" … … 71 71 72 72 // Find the path 73 boost::filesystem::path path; 74 if (boost::filesystem::exists(Core::getDataPath() / this->getPath())) 75 path = Core::getDataPath() / this->getPath(); 76 else if (Core::isDevelopmentRun() && boost::filesystem::exists(Core::getExternalDataPath() / this->getPath())) 77 path = Core::getExternalDataPath() / this->getPath(); 73 namespace bf = boost::filesystem; 74 bf::path path; 75 if (bf::exists(PathConfig::getDataPath() / this->getPath())) 76 path = PathConfig::getDataPath() / this->getPath(); 77 else if (PathConfig::isDevelopmentRun() && bf::exists(PathConfig::getExternalDataPath() / this->getPath())) 78 path = PathConfig::getExternalDataPath() / this->getPath(); 78 79 else 79 80 {
Note: See TracChangeset
for help on using the changeset viewer.