Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Oct 4, 2015, 9:12:21 PM (9 years ago)
Author:
landauf
Message:

merged branch core7 back to trunk

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/Core.cc

    r9667 r10624  
    5454#include "util/Output.h"
    5555#include "util/Exception.h"
     56#include "util/SignalHandler.h"
    5657#include "util/output/LogWriter.h"
    5758#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"
    6363#include "config/ConfigFileManager.h"
    64 #include "config/ConfigValueIncludes.h"
    65 #include "CoreIncludes.h"
    66 #include "DynLibManager.h"
    6764#include "GameMode.h"
    6865#include "GraphicsManager.h"
    6966#include "GUIManager.h"
    70 #include "class/Identifier.h"
    7167#include "Language.h"
     68#include "Loader.h"
    7269#include "LuaState.h"
    73 #include "command/ConsoleCommand.h"
    7470#include "command/IOConsole.h"
    7571#include "command/TclBind.h"
     
    7773#include "input/InputManager.h"
    7874#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"
    7981
    8082namespace orxonox
     
    9294#endif
    9395
    94     // register Core as an abstract class to avoid problems if the class hierarchy is created within Core-constructor
    95     RegisterAbstractClass(Core).inheritsFrom(Class(Configurable));
    96 
    9796    Core::Core(const std::string& cmdLine)
    98         : pathConfig_(NULL)
     97        : applicationPaths_(NULL)
     98        , configurablePaths_(NULL)
    9999        , dynLibManager_(NULL)
    100100        , signalHandler_(NULL)
    101101        , configFileManager_(NULL)
    102102        , languageInstance_(NULL)
     103        , loaderInstance_(NULL)
    103104        , ioConsole_(NULL)
    104105        , tclBind_(NULL)
     
    110111        , graphicsScope_(NULL)
    111112        , 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)
    116117        , destructionHelper_(this)
    117118    {
     
    119120
    120121        // Set the hard coded fixed paths
    121         this->pathConfig_ = new PathConfig();
     122        this->applicationPaths_ = new ApplicationPaths();
    122123
    123124        // Create a new dynamic library manager
    124125        this->dynLibManager_ = new DynLibManager();
    125126
    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_);
    140135
    141136        // Parse command line arguments AFTER the modules have been loaded (static code!)
     
    143138
    144139        // 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
    156154        // This call is placed as soon as possible, but after the directories are set
    157155        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");
    159157
    160158#ifdef ORXONOX_PLATFORM_WINDOWS
     
    177175        this->languageInstance_ = new Language();
    178176
     177        // initialize root context
     178        Context::setRootContext(new Context(NULL));
     179
    179180        // Do this soon after the ConfigFileManager has been created to open up the
    180181        // possibility to configure everything below here
    181         RegisterObject(Core);
    182182        orxout(internal_info) << "configuring Core" << endl;
    183         this->setConfigValues();
     183        this->config_ = new CoreConfig();
    184184
    185185        // 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());
    187187
    188188#if !defined(ORXONOX_PLATFORM_APPLE) && !defined(ORXONOX_USE_WINMAIN)
    189189        // 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())
    195191        {
    196192            orxout(internal_info) << "creating IO console" << endl;
     
    201197        // creates the class hierarchy for all classes with factories
    202198        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();
    204208
    205209        // Load OGRE excluding the renderer and the render window
     
    208212
    209213        // initialise Tcl
    210         this->tclBind_ = new TclBind(PathConfig::getDataPathString());
     214        this->tclBind_ = new TclBind(ConfigurablePaths::getDataPathString());
    211215        this->tclThreadManager_ = new TclThreadManager(tclBind_->getTclInterpreter());
    212216
    213217        // Create singletons that always exist (in other libraries)
    214218        orxout(internal_info) << "creating root scope:" << endl;
    215         this->rootScope_ = new Scope<ScopeID::Root>();
     219        this->rootScope_ = new Scope<ScopeID::ROOT>();
    216220
    217221        // Generate documentation instead of normal run?
     
    237241        orxout(internal_status) << "destroying Core object..." << endl;
    238242
    239         // Remove us from the object lists again to avoid problems when destroying them
    240         this->unregisterObject();
    241 
    242243        safeObjectDelete(&graphicsScope_);
    243244        safeObjectDelete(&guiManager_);
     
    248249        safeObjectDelete(&tclBind_);
    249250        safeObjectDelete(&ioConsole_);
     251        safeObjectDelete(&loaderInstance_);
     252        safeObjectDelete(&config_);
    250253        safeObjectDelete(&languageInstance_);
    251254        safeObjectDelete(&configFileManager_);
    252         ConsoleCommand::destroyAll();
    253         Context::setRootContext(NULL);
    254         IdentifierManager::getInstance().destroyAllIdentifiers();
    255255        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();
    256269        safeObjectDelete(&dynLibManager_);
    257         safeObjectDelete(&pathConfig_);
     270        safeObjectDelete(&configurablePaths_);
     271        safeObjectDelete(&applicationPaths_);
    258272
    259273        orxout(internal_status) << "finished destroying Core object" << endl;
    260274    }
    261275
    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);
    339329    }
    340330
     
    344334
    345335        // 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);
    347337
    348338        // Upgrade OGRE to receive a render window
     
    385375        // Create singletons associated with graphics (in other libraries)
    386376        orxout(internal_info) << "creating graphics scope:" << endl;
    387         graphicsScope_ = new Scope<ScopeID::Graphics>();
     377        graphicsScope_ = new Scope<ScopeID::GRAPHICS>();
    388378
    389379        unloader.Dismiss();
     
    392382    }
    393383
    394     void Core::unloadGraphics()
     384    void Core::unloadGraphics(bool loadGraphicsManagerWithoutRenderer)
    395385    {
    396386        orxout(internal_info) << "unloading graphics in Core" << endl;
     387
     388        if (this->graphicsManager_)
     389            this->graphicsManager_->unloadDebugOverlay();
    397390
    398391        safeObjectDelete(&graphicsScope_);
     
    403396        // Load Ogre::Root again, but without the render system
    404397        try
    405             { this->graphicsManager_ = new GraphicsManager(false); }
     398        {
     399            if (loadGraphicsManagerWithoutRenderer)
     400                this->graphicsManager_ = new GraphicsManager(false);
     401        }
    406402        catch (...)
    407403        {
     
    414410        bGraphicsLoaded_ = false;
    415411        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_);
    422412    }
    423413
     
    470460    void Core::preUpdate(const Clock& time)
    471461    {
    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);
    474465        if (this->bGraphicsLoaded_)
    475466        {
     
    478469            // Update GUI
    479470            this->guiManager_->preUpdate(time);
    480             // Update singletons before general ticking
    481             ScopedSingletonManager::preUpdate<ScopeID::Graphics>(time);
    482471        }
    483472        // Process console events and status line
     
    490479    void Core::postUpdate(const Clock& time)
    491480    {
    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);
    494484        if (this->bGraphicsLoaded_)
    495485        {
    496             // Update singletons just before rendering
    497             ScopedSingletonManager::postUpdate<ScopeID::Graphics>(time);
    498486            // Render (doesn't throw)
    499487            this->graphicsManager_->postUpdate(time);
    500488        }
    501489    }
    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     }
    520490}
Note: See TracChangeset for help on using the changeset viewer.