Changeset 2710 for code/trunk/src/core/Core.cc
- Timestamp:
- Feb 28, 2009, 7:46:37 PM (16 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:ignore deleted
- Property svn:mergeinfo changed
-
code/trunk/src/core/Core.cc
r2662 r2710 33 33 34 34 #include "Core.h" 35 35 36 #include <cassert> 37 #include <fstream> 38 #include <cstdlib> 39 #include <cstdio> 40 #include <boost/filesystem.hpp> 41 42 #ifdef ORXONOX_PLATFORM_WINDOWS 43 # include <windows.h> 44 #elif defined(ORXONOX_PLATFORM_APPLE) 45 # include <sys/param.h> 46 # include <mach-o/dyld.h> 47 #else /* Linux */ 48 # include <sys/types.h> 49 # include <unistd.h> 50 #endif 51 52 #include "SpecialConfig.h" 53 #include "util/Exception.h" 36 54 #include "Language.h" 37 55 #include "CoreIncludes.h" 38 56 #include "ConfigValueIncludes.h" 57 #include "LuaBind.h" 58 #include "CommandLine.h" 39 59 40 60 namespace orxonox 41 61 { 62 //! Path to the parent directory of the ones above if program was installed with relativ pahts 63 static boost::filesystem::path rootPath_g; 64 static boost::filesystem::path executablePath_g; //!< Path to the executable 65 static boost::filesystem::path mediaPath_g; //!< Path to the media file folder 66 static boost::filesystem::path configPath_g; //!< Path to the config file folder 67 static boost::filesystem::path logPath_g; //!< Path to the log file folder 68 42 69 bool Core::bShowsGraphics_s = false; 43 70 bool Core::bHasServer_s = false; … … 46 73 bool Core::bIsMaster_s = false; 47 74 48 Core* Core::singletonRef_s = 0; 75 bool Core::isDevBuild_s = false; 76 Core* Core::singletonRef_s = 0; 77 78 SetCommandLineArgument(mediaPath, "").information("PATH"); 79 SetCommandLineArgument(directory, "").information("DIR"); 49 80 50 81 /** … … 58 89 assert(Core::singletonRef_s == 0); 59 90 Core::singletonRef_s = this; 91 60 92 this->bInitializeRandomNumberGenerator_ = false; 61 62 93 this->setConfigValues(); 94 95 // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used 96 OutputHandler::getOutStream().setLogPath(Core::getLogPathString()); 97 98 // Possible media path override by the command line 99 if (!CommandLine::getArgument("mediaPath")->hasDefaultValue()) 100 { 101 //std::string mediaPath = CommandLine::getValue("mediaPath"); 102 Core::tsetMediaPath(CommandLine::getValue("mediaPath")); 103 } 63 104 } 64 105 … … 77 118 void Core::setConfigValues() 78 119 { 79 SetConfigValue(softDebugLevelConsole_, 3).description("The maximal level of debug output shown in the console").callback(this, &Core::debugLevelChanged); 80 SetConfigValue(softDebugLevelLogfile_, 3).description("The maximal level of debug output shown in the logfile").callback(this, &Core::debugLevelChanged); 81 SetConfigValue(softDebugLevelShell_, 1).description("The maximal level of debug output shown in the ingame shell").callback(this, &Core::debugLevelChanged); 120 #ifdef NDEBUG 121 const unsigned int defaultLevelConsole = 1; 122 const unsigned int defaultLevelLogfile = 3; 123 const unsigned int defaultLevelShell = 1; 124 #else 125 const unsigned int defaultLevelConsole = 3; 126 const unsigned int defaultLevelLogfile = 4; 127 const unsigned int defaultLevelShell = 3; 128 #endif 129 SetConfigValue(softDebugLevelConsole_, defaultLevelConsole) 130 .description("The maximal level of debug output shown in the console").callback(this, &Core::debugLevelChanged); 131 SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile) 132 .description("The maximal level of debug output shown in the logfile").callback(this, &Core::debugLevelChanged); 133 SetConfigValue(softDebugLevelShell_, defaultLevelShell) 134 .description("The maximal level of debug output shown in the ingame shell").callback(this, &Core::debugLevelChanged); 135 82 136 SetConfigValue(language_, Language::getLanguage().defaultLanguage_).description("The language of the ingame text").callback(this, &Core::languageChanged); 83 137 SetConfigValue(bInitializeRandomNumberGenerator_, true).description("If true, all random actions are different each time you start the game").callback(this, &Core::initializeRandomNumberGenerator); 138 139 SetConfigValue(mediaPathString_, Core::getMediaPathPOSIXString()) 140 .description("Relative path to the game data.").callback(this, &Core::mediaPathChanged); 84 141 } 85 142 … … 109 166 // Read the translation file after the language was configured 110 167 Language::getLanguage().readTranslatedLanguageFile(); 168 } 169 170 /** 171 @brief 172 Callback function if the media path has changed. 173 */ 174 void Core::mediaPathChanged() 175 { 176 mediaPath_g = boost::filesystem::path(this->mediaPathString_); 111 177 } 112 178 … … 177 243 } 178 244 245 /** 246 @brief 247 Temporary sets the media path 248 @param path 249 The new media path 250 */ 251 void Core::_tsetMediaPath(const std::string& path) 252 { 253 ModifyConfigValue(mediaPathString_, tset, path); 254 } 255 256 /*static*/ const boost::filesystem::path& Core::getMediaPath() 257 { 258 return mediaPath_g; 259 } 260 /*static*/ std::string Core::getMediaPathString() 261 { 262 return mediaPath_g.directory_string() + CP_SLASH; 263 } 264 /*static*/ std::string Core::getMediaPathPOSIXString() 265 { 266 return mediaPath_g.string() + '/'; 267 268 } 269 270 /*static*/ const boost::filesystem::path& Core::getConfigPath() 271 { 272 return configPath_g; 273 } 274 /*static*/ std::string Core::getConfigPathString() 275 { 276 return configPath_g.directory_string() + CP_SLASH; 277 } 278 /*static*/ std::string Core::getConfigPathPOSIXString() 279 { 280 return configPath_g.string() + '/'; 281 } 282 283 /*static*/ const boost::filesystem::path& Core::getLogPath() 284 { 285 return logPath_g; 286 } 287 /*static*/ std::string Core::getLogPathString() 288 { 289 return logPath_g.directory_string() + CP_SLASH; 290 } 291 /*static*/ std::string Core::getLogPathPOSIXString() 292 { 293 return logPath_g.string() + '/'; 294 } 295 179 296 void Core::initializeRandomNumberGenerator() 180 297 { … … 187 304 } 188 305 } 306 307 /** 308 @brief 309 Performs the rather lower level operations just after 310 int main() has been called. 311 @remarks 312 This gets called AFTER pre-main stuff like AddFactory, 313 SetConsoleCommand, etc. 314 */ 315 /*static*/ void Core::postMainInitialisation() 316 { 317 // set location of the executable 318 Core::setExecutablePath(); 319 320 // Determine whether we have an installed or a binary dir run 321 // The latter occurs when simply running from the build directory 322 Core::checkDevBuild(); 323 324 // Make sure the directories we write in exist or else make them 325 Core::createDirectories(); 326 } 327 328 /** 329 @brief 330 Compares the executable path with the working directory 331 */ 332 /*static*/ void Core::setExecutablePath() 333 { 334 #ifdef ORXONOX_PLATFORM_WINDOWS 335 // get executable module 336 TCHAR buffer[1024]; 337 if (GetModuleFileName(NULL, buffer, 1024) == 0) 338 ThrowException(General, "Could not retrieve executable path."); 339 340 #elif defined(ORXONOX_PLATFORM_APPLE) 341 char buffer[1024]; 342 unsigned long path_len = 1023; 343 if (_NSGetExecutablePath(buffer, &path_len)) 344 ThrowException(General, "Could not retrieve executable path."); 345 346 #else /* Linux */ 347 /* written by Nicolai Haehnle <prefect_@gmx.net> */ 348 349 /* Get our PID and build the name of the link in /proc */ 350 char linkname[64]; /* /proc/<pid>/exe */ 351 if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", getpid()) < 0) 352 { 353 /* This should only happen on large word systems. I'm not sure 354 what the proper response is here. 355 Since it really is an assert-like condition, aborting the 356 program seems to be in order. */ 357 assert(false); 358 } 359 360 /* Now read the symbolic link */ 361 char buffer[1024]; 362 int ret; 363 ret = readlink(linkname, buffer, 1024); 364 /* In case of an error, leave the handling up to the caller */ 365 if (ret == -1) 366 ThrowException(General, "Could not retrieve executable path."); 367 368 /* Ensure proper NUL termination */ 369 buffer[ret] = 0; 370 #endif 371 372 executablePath_g = boost::filesystem::path(buffer); 373 #ifndef ORXONOX_PLATFORM_APPLE 374 executablePath_g = executablePath_g.branch_path(); // remove executable name 375 #endif 376 } 377 378 /** 379 @brief 380 Checks for "orxonox_dev_build.keep_me" in the executable diretory. 381 If found it means that this is not an installed run, hence we 382 don't write the logs and config files to ~/.orxonox 383 */ 384 /*static*/ void Core::checkDevBuild() 385 { 386 if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me")) 387 { 388 COUT(1) << "Running from the build tree." << std::endl; 389 Core::isDevBuild_s = true; 390 mediaPath_g = ORXONOX_MEDIA_DEV_PATH; 391 configPath_g = ORXONOX_CONFIG_DEV_PATH; 392 logPath_g = ORXONOX_LOG_DEV_PATH; 393 } 394 else 395 { 396 #ifdef INSTALL_COPYABLE // --> relative paths 397 // Also set the root path 398 boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH); 399 rootPath_g = executablePath_g; 400 while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) || rootPath_g.empty()) 401 rootPath_g = rootPath_g.branch_path(); 402 if (rootPath_g.empty()) 403 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?"); 404 405 // Using paths relative to the install prefix, complete them 406 mediaPath_g = rootPath_g / ORXONOX_MEDIA_INSTALL_PATH; 407 configPath_g = rootPath_g / ORXONOX_CONFIG_INSTALL_PATH; 408 logPath_g = rootPath_g / ORXONOX_LOG_INSTALL_PATH; 409 #else 410 // There is no root path, so don't set it at all 411 412 mediaPath_g = ORXONOX_MEDIA_INSTALL_PATH; 413 414 // Get user directory 415 # ifdef ORXONOX_PLATFORM_UNIX /* Apple? */ 416 char* userDataPathPtr(getenv("HOME")); 417 # else 418 char* userDataPathPtr(getenv("APPDATA")); 419 # endif 420 if (userDataPathPtr == NULL) 421 ThrowException(General, "Could not retrieve user data path."); 422 boost::filesystem::path userDataPath(userDataPathPtr); 423 userDataPath /= ".orxonox"; 424 425 configPath_g = userDataPath / ORXONOX_CONFIG_INSTALL_PATH; 426 logPath_g = userDataPath / ORXONOX_LOG_INSTALL_PATH; 427 #endif 428 } 429 430 // Option to put all the config and log files in a separate folder 431 if (!CommandLine::getArgument("directory")->hasDefaultValue()) 432 { 433 std::string directory(CommandLine::getValue("directory")); 434 configPath_g = configPath_g / directory; 435 logPath_g = logPath_g / directory; 436 } 437 } 438 439 /* 440 @brief 441 Checks for the log and the config directory and creates them 442 if necessary. Otherwise me might have problems opening those files. 443 */ 444 /*static*/ void Core::createDirectories() 445 { 446 std::vector<std::pair<boost::filesystem::path, std::string> > directories; 447 directories.push_back(std::pair<boost::filesystem::path, std::string> 448 (boost::filesystem::path(configPath_g), "config")); 449 directories.push_back(std::pair<boost::filesystem::path, std::string> 450 (boost::filesystem::path(logPath_g), "log")); 451 452 for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin(); 453 it != directories.end(); ++it) 454 { 455 if (boost::filesystem::exists(it->first) && !boost::filesystem::is_directory(it->first)) 456 { 457 ThrowException(General, std::string("The ") + it->second + " directory has been preoccupied by a file! \ 458 Please remove " + it->first.file_string()); 459 } 460 if (boost::filesystem::create_directories(it->first)) // function may not return true at all (bug?) 461 { 462 COUT(4) << "Created " << it->second << " directory" << std::endl; 463 } 464 } 465 } 189 466 }
Note: See TracChangeset
for help on using the changeset viewer.