Changeset 10624 for code/trunk/src/libraries/core/Core.cc
- Timestamp:
- Oct 4, 2015, 9:12:21 PM (9 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
-
code/trunk/src/libraries/core/Core.cc
r9667 r10624 54 54 #include "util/Output.h" 55 55 #include "util/Exception.h" 56 #include "util/SignalHandler.h" 56 57 #include "util/output/LogWriter.h" 57 58 #include "util/output/OutputManager.h" 58 #include "util/Scope.h" 59 #include "util/ScopedSingletonManager.h" 60 #include "util/SignalHandler.h" 61 #include "PathConfig.h" 62 #include "config/CommandLineParser.h" 59 #include "core/singleton/Scope.h" 60 #include "ApplicationPaths.h" 61 #include "ConfigurablePaths.h" 62 #include "commandline/CommandLineIncludes.h" 63 63 #include "config/ConfigFileManager.h" 64 #include "config/ConfigValueIncludes.h"65 #include "CoreIncludes.h"66 #include "DynLibManager.h"67 64 #include "GameMode.h" 68 65 #include "GraphicsManager.h" 69 66 #include "GUIManager.h" 70 #include "class/Identifier.h"71 67 #include "Language.h" 68 #include "Loader.h" 72 69 #include "LuaState.h" 73 #include "command/ConsoleCommand.h"74 70 #include "command/IOConsole.h" 75 71 #include "command/TclBind.h" … … 77 73 #include "input/InputManager.h" 78 74 #include "object/ObjectList.h" 75 #include "module/DynLibManager.h" 76 #include "module/ModuleInstance.h" 77 #include "module/StaticInitializationManager.h" 78 #include "module/PluginManager.h" 79 #include "CoreStaticInitializationHandler.h" 80 #include "UpdateListener.h" 79 81 80 82 namespace orxonox … … 92 94 #endif 93 95 94 // register Core as an abstract class to avoid problems if the class hierarchy is created within Core-constructor95 RegisterAbstractClass(Core).inheritsFrom(Class(Configurable));96 97 96 Core::Core(const std::string& cmdLine) 98 : pathConfig_(NULL) 97 : applicationPaths_(NULL) 98 , configurablePaths_(NULL) 99 99 , dynLibManager_(NULL) 100 100 , signalHandler_(NULL) 101 101 , configFileManager_(NULL) 102 102 , languageInstance_(NULL) 103 , loaderInstance_(NULL) 103 104 , ioConsole_(NULL) 104 105 , tclBind_(NULL) … … 110 111 , graphicsScope_(NULL) 111 112 , bGraphicsLoaded_(false) 112 , bStartIOConsole_(true)113 , lastLevelTimestamp_(0)114 , ogreConfigTimestamp_(0)115 , bDevMode_(false)113 , staticInitHandler_(NULL) 114 , pluginManager_(NULL) 115 , rootModule_(NULL) 116 , config_(NULL) 116 117 , destructionHelper_(this) 117 118 { … … 119 120 120 121 // Set the hard coded fixed paths 121 this-> pathConfig_ = new PathConfig();122 this->applicationPaths_ = new ApplicationPaths(); 122 123 123 124 // Create a new dynamic library manager 124 125 this->dynLibManager_ = new DynLibManager(); 125 126 126 // Load modules 127 orxout(internal_info) << "Loading modules:" << endl; 128 const std::vector<std::string>& modulePaths = this->pathConfig_->getModulePaths(); 129 for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it) 130 { 131 try 132 { 133 this->dynLibManager_->load(*it); 134 } 135 catch (...) 136 { 137 orxout(user_error) << "Couldn't load module \"" << *it << "\": " << Exception::handleMessage() << endl; 138 } 139 } 127 // create handler for static initialization 128 new StaticInitializationManager(); // create singleton 129 this->staticInitHandler_ = new CoreStaticInitializationHandler(); 130 StaticInitializationManager::getInstance().addHandler(this->staticInitHandler_); 131 132 // load root module (all libraries which are linked to the executable, including core, network, and orxonox) 133 this->rootModule_ = ModuleInstance::getCurrentModuleInstance(); 134 StaticInitializationManager::getInstance().loadModule(this->rootModule_); 140 135 141 136 // Parse command line arguments AFTER the modules have been loaded (static code!) … … 143 138 144 139 // Set configurable paths like log, config and media 145 this->pathConfig_->setConfigurablePaths(); 146 147 orxout(internal_info) << "Root path: " << PathConfig::getRootPathString() << endl; 148 orxout(internal_info) << "Executable path: " << PathConfig::getExecutablePathString() << endl; 149 orxout(internal_info) << "Data path: " << PathConfig::getDataPathString() << endl; 150 orxout(internal_info) << "Ext. data path: " << PathConfig::getExternalDataPathString() << endl; 151 orxout(internal_info) << "Config path: " << PathConfig::getConfigPathString() << endl; 152 orxout(internal_info) << "Log path: " << PathConfig::getLogPathString() << endl; 153 orxout(internal_info) << "Modules path: " << PathConfig::getModulePathString() << endl; 154 155 // create a signal handler (only active for Linux) 140 this->configurablePaths_ = new ConfigurablePaths(); 141 this->configurablePaths_->setConfigurablePaths(ApplicationPaths::getInstance()); 142 143 orxout(internal_info) << "Root path: " << ApplicationPaths::getRootPathString() << endl; 144 orxout(internal_info) << "Executable path: " << ApplicationPaths::getExecutablePathString() << endl; 145 orxout(internal_info) << "Modules path: " << ApplicationPaths::getModulePathString() << endl; 146 orxout(internal_info) << "Plugins path: " << ApplicationPaths::getPluginPathString() << endl; 147 148 orxout(internal_info) << "Data path: " << ConfigurablePaths::getDataPathString() << endl; 149 orxout(internal_info) << "Ext. data path: " << ConfigurablePaths::getExternalDataPathString() << endl; 150 orxout(internal_info) << "Config path: " << ConfigurablePaths::getConfigPathString() << endl; 151 orxout(internal_info) << "Log path: " << ConfigurablePaths::getLogPathString() << endl; 152 153 // create a signal handler 156 154 // This call is placed as soon as possible, but after the directories are set 157 155 this->signalHandler_ = new SignalHandler(); 158 this->signalHandler_->doCatch( PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log");156 this->signalHandler_->doCatch(ApplicationPaths::getExecutablePathString(), ConfigurablePaths::getLogPathString() + "orxonox_crash.log"); 159 157 160 158 #ifdef ORXONOX_PLATFORM_WINDOWS … … 177 175 this->languageInstance_ = new Language(); 178 176 177 // initialize root context 178 Context::setRootContext(new Context(NULL)); 179 179 180 // Do this soon after the ConfigFileManager has been created to open up the 180 181 // possibility to configure everything below here 181 RegisterObject(Core);182 182 orxout(internal_info) << "configuring Core" << endl; 183 this-> setConfigValues();183 this->config_ = new CoreConfig(); 184 184 185 185 // Set the correct log path and rewrite the log file with the correct log levels 186 OutputManager::getInstance().getLogWriter()->setLogDirectory( PathConfig::getLogPathString());186 OutputManager::getInstance().getLogWriter()->setLogDirectory(ConfigurablePaths::getLogPathString()); 187 187 188 188 #if !defined(ORXONOX_PLATFORM_APPLE) && !defined(ORXONOX_USE_WINMAIN) 189 189 // Create persistent IO console 190 if (CommandLineParser::getValue("noIOConsole").get<bool>()) 191 { 192 ModifyConfigValue(bStartIOConsole_, tset, false); 193 } 194 if (this->bStartIOConsole_) 190 if (CommandLineParser::getValue("noIOConsole").get<bool>() == false && this->config_->getStartIOConsole()) 195 191 { 196 192 orxout(internal_info) << "creating IO console" << endl; … … 201 197 // creates the class hierarchy for all classes with factories 202 198 orxout(internal_info) << "creating class hierarchy" << endl; 203 IdentifierManager::getInstance().createClassHierarchy(); 199 this->staticInitHandler_->initInstances(this->rootModule_); 200 this->staticInitHandler_->setInitInstances(true); 201 202 // Create plugin manager and search for plugins 203 this->pluginManager_ = new PluginManager(); 204 this->pluginManager_->findPlugins(); 205 206 // Loader 207 this->loaderInstance_ = new Loader(); 204 208 205 209 // Load OGRE excluding the renderer and the render window … … 208 212 209 213 // initialise Tcl 210 this->tclBind_ = new TclBind( PathConfig::getDataPathString());214 this->tclBind_ = new TclBind(ConfigurablePaths::getDataPathString()); 211 215 this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter()); 212 216 213 217 // Create singletons that always exist (in other libraries) 214 218 orxout(internal_info) << "creating root scope:" << endl; 215 this->rootScope_ = new Scope<ScopeID::R oot>();219 this->rootScope_ = new Scope<ScopeID::ROOT>(); 216 220 217 221 // Generate documentation instead of normal run? … … 237 241 orxout(internal_status) << "destroying Core object..." << endl; 238 242 239 // Remove us from the object lists again to avoid problems when destroying them240 this->unregisterObject();241 242 243 safeObjectDelete(&graphicsScope_); 243 244 safeObjectDelete(&guiManager_); … … 248 249 safeObjectDelete(&tclBind_); 249 250 safeObjectDelete(&ioConsole_); 251 safeObjectDelete(&loaderInstance_); 252 safeObjectDelete(&config_); 250 253 safeObjectDelete(&languageInstance_); 251 254 safeObjectDelete(&configFileManager_); 252 ConsoleCommand::destroyAll();253 Context::setRootContext(NULL);254 IdentifierManager::getInstance().destroyAllIdentifiers();255 255 safeObjectDelete(&signalHandler_); 256 safeObjectDelete(&pluginManager_); 257 Context::getRootContext()->unregisterObject(); // unregister context from object lists - otherwise the root context would be destroyed while unloading the root module 258 if (this->rootModule_) 259 { 260 StaticInitializationManager::getInstance().unloadModule(this->rootModule_); 261 this->rootModule_->deleteAllStaticallyInitializedInstances(); 262 } 263 if (this->staticInitHandler_) 264 StaticInitializationManager::getInstance().removeHandler(this->staticInitHandler_); 265 Context::destroyRootContext(); 266 safeObjectDelete(&rootModule_); 267 safeObjectDelete(&staticInitHandler_); 268 delete &StaticInitializationManager::getInstance(); 256 269 safeObjectDelete(&dynLibManager_); 257 safeObjectDelete(&pathConfig_); 270 safeObjectDelete(&configurablePaths_); 271 safeObjectDelete(&applicationPaths_); 258 272 259 273 orxout(internal_status) << "finished destroying Core object" << endl; 260 274 } 261 275 262 //! Function to collect the SetConfigValue-macro calls. 263 void Core::setConfigValues() 264 { 265 SetConfigValueExternal(OutputManager::getInstance().getLogWriter()->configurableMaxLevel_, 266 OutputManager::getInstance().getLogWriter()->getConfigurableSectionName(), 267 OutputManager::getInstance().getLogWriter()->getConfigurableMaxLevelName(), 268 OutputManager::getInstance().getLogWriter()->configurableMaxLevel_) 269 .description("The maximum level of output shown in the log file") 270 .callback(static_cast<BaseWriter*>(OutputManager::getInstance().getLogWriter()), &BaseWriter::changedConfigurableLevel); 271 SetConfigValueExternal(OutputManager::getInstance().getLogWriter()->configurableAdditionalContextsMaxLevel_, 272 OutputManager::getInstance().getLogWriter()->getConfigurableSectionName(), 273 OutputManager::getInstance().getLogWriter()->getConfigurableAdditionalContextsMaxLevelName(), 274 OutputManager::getInstance().getLogWriter()->configurableAdditionalContextsMaxLevel_) 275 .description("The maximum level of output shown in the log file for additional contexts") 276 .callback(static_cast<BaseWriter*>(OutputManager::getInstance().getLogWriter()), &BaseWriter::changedConfigurableAdditionalContextsLevel); 277 SetConfigValueExternal(OutputManager::getInstance().getLogWriter()->configurableAdditionalContexts_, 278 OutputManager::getInstance().getLogWriter()->getConfigurableSectionName(), 279 OutputManager::getInstance().getLogWriter()->getConfigurableAdditionalContextsName(), 280 OutputManager::getInstance().getLogWriter()->configurableAdditionalContexts_) 281 .description("Additional output contexts shown in the log file") 282 .callback(static_cast<BaseWriter*>(OutputManager::getInstance().getLogWriter()), &BaseWriter::changedConfigurableAdditionalContexts); 283 284 SetConfigValue(bDevMode_, PathConfig::buildDirectoryRun()) 285 .description("Developer mode. If not set, hides some things from the user to not confuse him.") 286 .callback(this, &Core::devModeChanged); 287 SetConfigValue(language_, Language::getInstance().defaultLanguage_) 288 .description("The language of the in game text") 289 .callback(this, &Core::languageChanged); 290 SetConfigValue(bInitRandomNumberGenerator_, true) 291 .description("If true, all random actions are different each time you start the game") 292 .callback(this, &Core::initRandomNumberGenerator); 293 SetConfigValue(bStartIOConsole_, true) 294 .description("Set to false if you don't want to use the IOConsole (for Lua debugging for instance)"); 295 SetConfigValue(lastLevelTimestamp_, 0) 296 .description("Timestamp when the last level was started."); 297 SetConfigValue(ogreConfigTimestamp_, 0) 298 .description("Timestamp when the ogre config file was changed."); 299 } 300 301 /** Callback function for changes in the dev mode that affect debug levels. 302 The function behaves according to these rules: 303 - 'normal' mode is defined based on where the program was launched: if 304 the launch path was the build directory, development mode \c on is 305 normal, otherwise normal means development mode \c off. 306 - Debug levels should not be hard configured (\c config instead of 307 \c tconfig) in non 'normal' mode to avoid strange behaviour. 308 - Changing the development mode from 'normal' to the other state will 309 immediately change the debug levels to predefined values which can be 310 reconfigured with \c tconfig. 311 @note 312 The debug levels for the IOConsole and the InGameConsole can be found 313 in the Shell class. The same rules apply. 314 */ 315 void Core::devModeChanged() 316 { 317 // Inform listeners 318 ObjectList<DevModeListener>::iterator it = ObjectList<DevModeListener>::begin(); 319 for (; it != ObjectList<DevModeListener>::end(); ++it) 320 it->devModeChanged(bDevMode_); 321 } 322 323 //! Callback function if the language has changed. 324 void Core::languageChanged() 325 { 326 // Read the translation file after the language was configured 327 Language::getInstance().readTranslatedLanguageFile(); 328 } 329 330 void Core::initRandomNumberGenerator() 331 { 332 static bool bInitialized = false; 333 if (!bInitialized && this->bInitRandomNumberGenerator_) 334 { 335 srand(static_cast<unsigned int>(time(0))); 336 rand(); 337 bInitialized = true; 338 } 276 void Core::loadModules() 277 { 278 orxout(internal_info) << "Loading modules:" << endl; 279 280 const std::vector<std::string>& modulePaths = ApplicationPaths::getInstance().getModulePaths(); 281 for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it) 282 { 283 ModuleInstance* module = new ModuleInstance(*it); 284 this->loadModule(module); 285 this->modules_.push_back(module); 286 } 287 288 orxout(internal_info) << "finished loading modules" << endl; 289 } 290 291 void Core::loadModule(ModuleInstance* module) 292 { 293 orxout(internal_info) << "Loading module " << module->getLibraryName() << "..." << endl; 294 295 try 296 { 297 ModuleInstance::setCurrentModuleInstance(module); 298 DynLib* dynLib = this->dynLibManager_->load(module->getLibraryName()); 299 module->setDynLib(dynLib); 300 301 StaticInitializationManager::getInstance().loadModule(module); 302 } 303 catch (...) 304 { 305 orxout(user_error) << "Couldn't load module \"" << module->getLibraryName() << "\": " << Exception::handleMessage() << endl; 306 } 307 } 308 309 void Core::unloadModules() 310 { 311 for (std::list<ModuleInstance*>::iterator it = this->modules_.begin(); it != this->modules_.end(); ++it) 312 { 313 ModuleInstance* module = (*it); 314 this->unloadModule(module); 315 delete module; 316 } 317 this->modules_.clear(); 318 } 319 320 void Core::unloadModule(ModuleInstance* module) 321 { 322 orxout(internal_info) << "Unloading module " << module->getLibraryName() << "..." << endl; 323 324 StaticInitializationManager::getInstance().unloadModule(module); 325 326 module->deleteAllStaticallyInitializedInstances(); 327 this->dynLibManager_->unload(module->getDynLib()); 328 module->setDynLib(NULL); 339 329 } 340 330 … … 344 334 345 335 // Any exception should trigger this, even in upgradeToGraphics (see its remarks) 346 Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics );336 Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics, true); 347 337 348 338 // Upgrade OGRE to receive a render window … … 385 375 // Create singletons associated with graphics (in other libraries) 386 376 orxout(internal_info) << "creating graphics scope:" << endl; 387 graphicsScope_ = new Scope<ScopeID::G raphics>();377 graphicsScope_ = new Scope<ScopeID::GRAPHICS>(); 388 378 389 379 unloader.Dismiss(); … … 392 382 } 393 383 394 void Core::unloadGraphics( )384 void Core::unloadGraphics(bool loadGraphicsManagerWithoutRenderer) 395 385 { 396 386 orxout(internal_info) << "unloading graphics in Core" << endl; 387 388 if (this->graphicsManager_) 389 this->graphicsManager_->unloadDebugOverlay(); 397 390 398 391 safeObjectDelete(&graphicsScope_); … … 403 396 // Load Ogre::Root again, but without the render system 404 397 try 405 { this->graphicsManager_ = new GraphicsManager(false); } 398 { 399 if (loadGraphicsManagerWithoutRenderer) 400 this->graphicsManager_ = new GraphicsManager(false); 401 } 406 402 catch (...) 407 403 { … … 414 410 bGraphicsLoaded_ = false; 415 411 GameMode::bShowsGraphics_s = false; 416 }417 418 //! Sets the language in the config-file back to the default.419 void Core::resetLanguage()420 {421 ResetConfigValue(language_);422 412 } 423 413 … … 470 460 void Core::preUpdate(const Clock& time) 471 461 { 472 // Update singletons before general ticking 473 ScopedSingletonManager::preUpdate<ScopeID::Root>(time); 462 // Update UpdateListeners before general ticking 463 for (ObjectList<UpdateListener>::iterator it = ObjectList<UpdateListener>::begin(); it != ObjectList<UpdateListener>::end(); ++it) 464 it->preUpdate(time); 474 465 if (this->bGraphicsLoaded_) 475 466 { … … 478 469 // Update GUI 479 470 this->guiManager_->preUpdate(time); 480 // Update singletons before general ticking481 ScopedSingletonManager::preUpdate<ScopeID::Graphics>(time);482 471 } 483 472 // Process console events and status line … … 490 479 void Core::postUpdate(const Clock& time) 491 480 { 492 // Update singletons just before rendering 493 ScopedSingletonManager::postUpdate<ScopeID::Root>(time); 481 // Update UpdateListeners just before rendering 482 for (ObjectList<UpdateListener>::iterator it = ObjectList<UpdateListener>::begin(); it != ObjectList<UpdateListener>::end(); ++it) 483 it->postUpdate(time); 494 484 if (this->bGraphicsLoaded_) 495 485 { 496 // Update singletons just before rendering497 ScopedSingletonManager::postUpdate<ScopeID::Graphics>(time);498 486 // Render (doesn't throw) 499 487 this->graphicsManager_->postUpdate(time); 500 488 } 501 489 } 502 503 void Core::updateLastLevelTimestamp()504 {505 ModifyConfigValue(lastLevelTimestamp_, set, static_cast<long long>(time(NULL)));506 }507 508 void Core::updateOgreConfigTimestamp()509 {510 ModifyConfigValue(ogreConfigTimestamp_, set, static_cast<long long>(time(NULL)));511 }512 513 514 RegisterAbstractClass(DevModeListener).inheritsFrom(Class(Listable));515 516 DevModeListener::DevModeListener()517 {518 RegisterObject(DevModeListener);519 }520 490 }
Note: See TracChangeset
for help on using the changeset viewer.