Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 29, 2009, 2:01:51 PM (15 years ago)
Author:
rgrieder
Message:

Removed OrxonoxClass inheritance from Game and Core: this allows the Core class to deal with everything core-related, including identifier destruction.
Instead I moved the config-values to CoreConfiguration and GameConfiguration which in turn are member variables (as pointers).
Also handled exceptions better: Game or Core must not fail to initialise, otherwise orxonox will not start. This now gets displayed properly.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/core4/src/core/Core.cc

    r3246 r3247  
    7777namespace orxonox
    7878{
    79     //! Path to the parent directory of the ones above if program was installed with relativ pahts
    80     static boost::filesystem::path rootPath_g;
    81     static boost::filesystem::path executablePath_g;            //!< Path to the executable
    82     static boost::filesystem::path mediaPath_g;                 //!< Path to the media file folder
    83     static boost::filesystem::path configPath_g;                //!< Path to the config file folder
    84     static boost::filesystem::path logPath_g;                   //!< Path to the log file folder
    85 
    8679    //! Static pointer to the singleton
    8780    Core* Core::singletonRef_s  = 0;
     
    9285    SetCommandLineArgument(limitToCPU, 0).information("0: off | #cpu");
    9386
    94     Core::Core()
    95     {
    96         RegisterRootObject(Core);
    97 
     87    /**
     88    @brief
     89        Helper class for the Core singleton: we cannot derive
     90        Core from OrxonoxClass because we need to handle the Identifier
     91        destruction in the Core destructor.
     92    */
     93    class CoreConfiguration : public OrxonoxClass
     94    {
     95    public:
     96        CoreConfiguration()
     97        {
     98        }
     99
     100        void CoreConfiguration::initialise()
     101        {
     102            RegisterRootObject(CoreConfiguration);
     103            this->setConfigValues();
     104
     105            // Possible media path override by the command line
     106            if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
     107                tsetMediaPath(CommandLine::getValue("mediaPath"));
     108        }
     109
     110        /**
     111            @brief Function to collect the SetConfigValue-macro calls.
     112        */
     113        void setConfigValues()
     114        {
     115#ifdef NDEBUG
     116            const unsigned int defaultLevelConsole = 1;
     117            const unsigned int defaultLevelLogfile = 3;
     118            const unsigned int defaultLevelShell   = 1;
     119#else
     120            const unsigned int defaultLevelConsole = 3;
     121            const unsigned int defaultLevelLogfile = 4;
     122            const unsigned int defaultLevelShell   = 3;
     123#endif
     124            SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
     125                .description("The maximal level of debug output shown in the console")
     126                .callback(this, &CoreConfiguration::debugLevelChanged);
     127            SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
     128                .description("The maximal level of debug output shown in the logfile")
     129                .callback(this, &CoreConfiguration::debugLevelChanged);
     130            SetConfigValue(softDebugLevelShell_, defaultLevelShell)
     131                .description("The maximal level of debug output shown in the ingame shell")
     132                .callback(this, &CoreConfiguration::debugLevelChanged);
     133
     134            SetConfigValue(language_, Language::getLanguage().defaultLanguage_)
     135                .description("The language of the ingame text")
     136                .callback(this, &CoreConfiguration::languageChanged);
     137            SetConfigValue(bInitializeRandomNumberGenerator_, true)
     138                .description("If true, all random actions are different each time you start the game")
     139                .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
     140
     141            SetConfigValue(mediaPathString_, mediaPath_.string())
     142                .description("Relative path to the game data.")
     143                .callback(this, &CoreConfiguration::mediaPathChanged);
     144        }
     145
     146        /**
     147            @brief Callback function if the debug level has changed.
     148        */
     149        void debugLevelChanged()
     150        {
     151            // softDebugLevel_ is the maximum of the 3 variables
     152            this->softDebugLevel_ = this->softDebugLevelConsole_;
     153            if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
     154                this->softDebugLevel_ = this->softDebugLevelLogfile_;
     155            if (this->softDebugLevelShell_ > this->softDebugLevel_)
     156                this->softDebugLevel_ = this->softDebugLevelShell_;
     157
     158            OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
     159            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
     160            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
     161            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
     162        }
     163
     164        /**
     165            @brief Callback function if the language has changed.
     166        */
     167        void languageChanged()
     168        {
     169            // Read the translation file after the language was configured
     170            Language::getLanguage().readTranslatedLanguageFile();
     171        }
     172
     173        /**
     174        @brief
     175            Callback function if the media path has changed.
     176        */
     177        void mediaPathChanged()
     178        {
     179            mediaPath_ = boost::filesystem::path(this->mediaPathString_);
     180        }
     181
     182        /**
     183            @brief Sets the language in the config-file back to the default.
     184        */
     185        void resetLanguage()
     186        {
     187            ResetConfigValue(language_);
     188        }
     189
     190        /**
     191        @brief
     192            Temporary sets the media path
     193        @param path
     194            The new media path
     195        */
     196        void tsetMediaPath(const std::string& path)
     197        {
     198            ModifyConfigValue(mediaPathString_, tset, path);
     199        }
     200
     201        void initializeRandomNumberGenerator()
     202        {
     203            static bool bInitialized = false;
     204            if (!bInitialized && this->bInitializeRandomNumberGenerator_)
     205            {
     206                srand(static_cast<unsigned int>(time(0)));
     207                rand();
     208                bInitialized = true;
     209            }
     210        }
     211
     212        int softDebugLevel_;                            //!< The debug level
     213        int softDebugLevelConsole_;                     //!< The debug level for the console
     214        int softDebugLevelLogfile_;                     //!< The debug level for the logfile
     215        int softDebugLevelShell_;                       //!< The debug level for the ingame shell
     216        std::string language_;                          //!< The language
     217        bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
     218        std::string mediaPathString_;                   //!< Path to the data/media file folder as string
     219
     220        //! Path to the parent directory of the ones above if program was installed with relativ pahts
     221        boost::filesystem::path rootPath_;
     222        boost::filesystem::path executablePath_;        //!< Path to the executable
     223        boost::filesystem::path mediaPath_;             //!< Path to the media file folder
     224        boost::filesystem::path configPath_;            //!< Path to the config file folder
     225        boost::filesystem::path logPath_;               //!< Path to the log file folder
     226    };
     227
     228
     229    Core::Core(int argc, char** argv)
     230    {
    98231        assert(Core::singletonRef_s == 0);
    99232        Core::singletonRef_s = this;
    100     }
    101 
    102     void Core::initialise(int argc, char** argv)
    103     {
    104         // Parse command line arguments fist
     233
     234        // We need the variables very soon. But don't configure them yet!
     235        this->configuration_ = new CoreConfiguration();
     236
     237        // Parse command line arguments first
    105238        CommandLine::parseCommandLine(argc, argv);
     239
     240        // Determine and set the location of the executable
     241        setExecutablePath();
     242
     243        // Determine whether we have an installed or a binary dir run
     244        // The latter occurs when simply running from the build directory
     245        checkDevBuild();
     246
     247        // Make sure the directories we write in exist or else make them
     248        createDirectories();
     249
     250        // create a signal handler (only active for linux)
     251        // This call is placed as soon as possible, but after the directories are set
     252        this->signalHandler_ = new SignalHandler();
     253        this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");
     254
     255        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
     256        OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
     257
     258        // Parse additional options file now that we know its path
     259        CommandLine::parseFile();
    106260
    107261        // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
     
    112266            setThreadAffinity((unsigned int)limitToCPU);
    113267
    114         // Determine and set the location of the executable
    115         setExecutablePath();
    116 
    117         // Determine whether we have an installed or a binary dir run
    118         // The latter occurs when simply running from the build directory
    119         checkDevBuild();
    120 
    121         // Make sure the directories we write in exist or else make them
    122         createDirectories();
    123 
    124         // create a signal handler (only active for linux)
    125         // This call is placed as soon as possible, but after the directories are set
    126         this->signalHandler_ = new SignalHandler();
    127         this->signalHandler_->doCatch(executablePath_g.string(), Core::getLogPathString() + "orxonox_crash.log");
    128 
    129         // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
    130         OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
    131 
    132         CommandLine::parseFile();
    133 
    134268        // Manage ini files and set the default settings file (usually orxonox.ini)
    135269        this->configFileManager_ = new ConfigFileManager();
     
    141275        // Do this soon after the ConfigFileManager has been created to open up the
    142276        // possibility to configure everything below here
    143         this->setConfigValues();
    144 
    145         // Possible media path override by the command line
    146         if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
    147         {
    148             //std::string mediaPath = CommandLine::getValue("mediaPath");
    149             Core::tsetMediaPath(CommandLine::getValue("mediaPath"));
    150         }
     277        this->configuration_->initialise();
    151278
    152279        // Create the lua interface
     
    162289        // creates the class hierarchy for all classes with factories
    163290        Factory::createClassHierarchy();
    164        
    165         this->loaded_ = true;
    166291    }
    167292
     
    171296    Core::~Core()
    172297    {
    173         this->loaded_ = false;
    174 
    175298        delete this->shell_;
    176299        delete this->tclThreadManager_;
    177300        delete this->tclBind_;
    178301        delete this->luaBind_;
     302        delete this->configuration_;
    179303        delete this->languageInstance_;
    180304        delete this->configFileManager_;
     
    185309        CommandExecutor::destroyExternalCommands();
    186310
     311        // Clean up class hierarchy stuff (identifiers, XMLPort, configValues, consoleCommand)
     312        Identifier::destroyAllIdentifiers();
     313
    187314        assert(Core::singletonRef_s);
    188315        Core::singletonRef_s = 0;
     
    191318
    192319    /**
    193         @brief Function to collect the SetConfigValue-macro calls.
    194     */
    195     void Core::setConfigValues()
    196     {
    197 #ifdef NDEBUG
    198         const unsigned int defaultLevelConsole = 1;
    199         const unsigned int defaultLevelLogfile = 3;
    200         const unsigned int defaultLevelShell   = 1;
    201 #else
    202         const unsigned int defaultLevelConsole = 3;
    203         const unsigned int defaultLevelLogfile = 4;
    204         const unsigned int defaultLevelShell   = 3;
    205 #endif
    206         SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
    207             .description("The maximal level of debug output shown in the console").callback(this, &Core::debugLevelChanged);
    208         SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
    209             .description("The maximal level of debug output shown in the logfile").callback(this, &Core::debugLevelChanged);
    210         SetConfigValue(softDebugLevelShell_, defaultLevelShell)
    211             .description("The maximal level of debug output shown in the ingame shell").callback(this, &Core::debugLevelChanged);
    212 
    213         SetConfigValue(language_, Language::getLanguage().defaultLanguage_).description("The language of the ingame text").callback(this, &Core::languageChanged);
    214         SetConfigValue(bInitializeRandomNumberGenerator_, true).description("If true, all random actions are different each time you start the game").callback(this, &Core::initializeRandomNumberGenerator);
    215 
    216         SetConfigValue(mediaPathString_, mediaPath_g.string())
    217             .description("Relative path to the game data.").callback(this, &Core::mediaPathChanged);
    218     }
    219 
    220     /**
    221         @brief Callback function if the debug level has changed.
    222     */
    223     void Core::debugLevelChanged()
    224     {
    225         // softDebugLevel_ is the maximum of the 3 variables
    226         this->softDebugLevel_ = this->softDebugLevelConsole_;
    227         if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
    228             this->softDebugLevel_ = this->softDebugLevelLogfile_;
    229         if (this->softDebugLevelShell_ > this->softDebugLevel_)
    230             this->softDebugLevel_ = this->softDebugLevelShell_;
    231 
    232         OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
    233         OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
    234         OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
    235         OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
    236     }
    237 
    238     /**
    239         @brief Callback function if the language has changed.
    240     */
    241     void Core::languageChanged()
    242     {
    243         // Read the translation file after the language was configured
    244         Language::getLanguage().readTranslatedLanguageFile();
    245     }
    246 
    247     /**
    248     @brief
    249         Callback function if the media path has changed.
    250     */
    251     void Core::mediaPathChanged()
    252     {
    253         mediaPath_g = boost::filesystem::path(this->mediaPathString_);
    254     }
    255 
    256     /**
    257         @brief Returns the softDebugLevel for the given device (returns a default-value if the class ist right about to be created).
     320        @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).
    258321        @param device The device
    259322        @return The softDebugLevel
    260323    */
    261     int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
     324    /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
    262325    {
    263326        switch (device)
    264327        {
    265328        case OutputHandler::LD_All:
    266             return Core::getInstance().softDebugLevel_;
     329            return Core::getInstance().configuration_->softDebugLevel_;
    267330        case OutputHandler::LD_Console:
    268             return Core::getInstance().softDebugLevelConsole_;
     331            return Core::getInstance().configuration_->softDebugLevelConsole_;
    269332        case OutputHandler::LD_Logfile:
    270             return Core::getInstance().softDebugLevelLogfile_;
     333            return Core::getInstance().configuration_->softDebugLevelLogfile_;
    271334        case OutputHandler::LD_Shell:
    272             return Core::getInstance().softDebugLevelShell_;
     335            return Core::getInstance().configuration_->softDebugLevelShell_;
    273336        default:
    274337            assert(0);
     
    282345        @param level The level
    283346    */
    284     void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
    285      {
     347    /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
     348    {
    286349        if (device == OutputHandler::LD_All)
    287             Core::getInstance().softDebugLevel_ = level;
     350            Core::getInstance().configuration_->softDebugLevel_ = level;
    288351        else if (device == OutputHandler::LD_Console)
    289             Core::getInstance().softDebugLevelConsole_ = level;
     352            Core::getInstance().configuration_->softDebugLevelConsole_ = level;
    290353        else if (device == OutputHandler::LD_Logfile)
    291             Core::getInstance().softDebugLevelLogfile_ = level;
     354            Core::getInstance().configuration_->softDebugLevelLogfile_ = level;
    292355        else if (device == OutputHandler::LD_Shell)
    293             Core::getInstance().softDebugLevelShell_ = level;
     356            Core::getInstance().configuration_->softDebugLevelShell_ = level;
    294357
    295358        OutputHandler::setSoftDebugLevel(device, level);
    296      }
     359    }
    297360
    298361    /**
    299362        @brief Returns the configured language.
    300363    */
    301     const std::string& Core::getLanguage()
    302     {
    303         return Core::getInstance().language_;
     364    /*static*/ const std::string& Core::getLanguage()
     365    {
     366        return Core::getInstance().configuration_->language_;
    304367    }
    305368
     
    307370        @brief Sets the language in the config-file back to the default.
    308371    */
    309     void Core::resetLanguage()
    310     {
    311         Core::getInstance().resetLanguageIntern();
    312     }
    313 
    314     /**
    315         @brief Sets the language in the config-file back to the default.
    316     */
    317     void Core::resetLanguageIntern()
    318     {
    319         ResetConfigValue(language_);
    320     }
    321 
    322     /**
    323     @brief
    324         Temporary sets the media path
    325     @param path
    326         The new media path
    327     */
    328     void Core::_tsetMediaPath(const std::string& path)
    329     {
    330         ModifyConfigValue(mediaPathString_, tset, path);
     372    /*static*/ void Core::resetLanguage()
     373    {
     374        Core::getInstance().configuration_->resetLanguage();
     375    }
     376
     377    /*static*/ void Core::tsetMediaPath(const std::string& path)
     378    {
     379        getInstance().configuration_->tsetMediaPath(path);
    331380    }
    332381
    333382    /*static*/ const boost::filesystem::path& Core::getMediaPath()
    334383    {
    335         return mediaPath_g;
     384        return getInstance().configuration_->mediaPath_;
    336385    }
    337386    /*static*/ std::string Core::getMediaPathString()
    338387    {
    339         return mediaPath_g.string() + '/';
     388        return getInstance().configuration_->mediaPath_.string() + '/';
    340389    }
    341390
    342391    /*static*/ const boost::filesystem::path& Core::getConfigPath()
    343392    {
    344         return configPath_g;
     393        return getInstance().configuration_->configPath_;
    345394    }
    346395    /*static*/ std::string Core::getConfigPathString()
    347396    {
    348         return configPath_g.string() + '/';
     397        return getInstance().configuration_->configPath_.string() + '/';
    349398    }
    350399
    351400    /*static*/ const boost::filesystem::path& Core::getLogPath()
    352401    {
    353         return logPath_g;
     402        return getInstance().configuration_->logPath_;
    354403    }
    355404    /*static*/ std::string Core::getLogPathString()
    356405    {
    357         return logPath_g.string() + '/';
    358     }
    359 
    360     void Core::initializeRandomNumberGenerator()
    361     {
    362         static bool bInitialized = false;
    363         if (!bInitialized && this->bInitializeRandomNumberGenerator_)
    364         {
    365             srand(static_cast<unsigned int>(time(0)));
    366             rand();
    367             bInitialized = true;
    368         }
    369     }
    370 
     406        return getInstance().configuration_->logPath_.string() + '/';
     407    }
    371408
    372409    /**
     
    459496#endif
    460497
    461         executablePath_g = boost::filesystem::path(buffer);
     498        configuration_->executablePath_ = boost::filesystem::path(buffer);
    462499#ifndef ORXONOX_PLATFORM_APPLE
    463         executablePath_g = executablePath_g.branch_path(); // remove executable name
     500        configuration_->executablePath_ = configuration_->executablePath_.branch_path(); // remove executable name
    464501#endif
    465502    }
     
    475512    void Core::checkDevBuild()
    476513    {
    477         if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me"))
     514        if (boost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me"))
    478515        {
    479516            COUT(1) << "Running from the build tree." << std::endl;
    480517            Core::isDevBuild_ = true;
    481             mediaPath_g  = ORXONOX_MEDIA_DEV_PATH;
    482             configPath_g = ORXONOX_CONFIG_DEV_PATH;
    483             logPath_g    = ORXONOX_LOG_DEV_PATH;
     518            configuration_->mediaPath_  = ORXONOX_MEDIA_DEV_PATH;
     519            configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH;
     520            configuration_->logPath_    = ORXONOX_LOG_DEV_PATH;
    484521        }
    485522        else
     
    488525            // Also set the root path
    489526            boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH);
    490             rootPath_g = executablePath_g;
    491             while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) && !rootPath_g.empty())
    492                 rootPath_g = rootPath_g.branch_path();
    493             if (rootPath_g.empty())
     527            configuration_->rootPath_ = configuration_->executablePath_;
     528            while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_)
     529                   && !configuration_->rootPath_.empty())
     530                configuration_->rootPath_ = configuration_->rootPath_.branch_path();
     531            if (configuration_->rootPath_.empty())
    494532                ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
    495533
    496534            // Using paths relative to the install prefix, complete them
    497             mediaPath_g  = rootPath_g / ORXONOX_MEDIA_INSTALL_PATH;
    498             configPath_g = rootPath_g / ORXONOX_CONFIG_INSTALL_PATH;
    499             logPath_g    = rootPath_g / ORXONOX_LOG_INSTALL_PATH;
     535            configuration_->mediaPath_  = configuration_->rootPath_ / ORXONOX_MEDIA_INSTALL_PATH;
     536            configuration_->configPath_ = configuration_->rootPath_ / ORXONOX_CONFIG_INSTALL_PATH;
     537            configuration_->logPath_    = configuration_->rootPath_ / ORXONOX_LOG_INSTALL_PATH;
    500538#else
    501539            // There is no root path, so don't set it at all
    502540
    503             mediaPath_g  = ORXONOX_MEDIA_INSTALL_PATH;
     541            configuration_->mediaPath_  = ORXONOX_MEDIA_INSTALL_PATH;
    504542
    505543            // Get user directory
     
    514552            userDataPath /= ".orxonox";
    515553
    516             configPath_g = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
    517             logPath_g    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
     554            configuration_->configPath_ = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
     555            configuration_->logPath_    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
    518556#endif
    519557        }
     
    523561        {
    524562            std::string directory(CommandLine::getValue("writingPathSuffix").getString());
    525             configPath_g = configPath_g / directory;
    526             logPath_g    = logPath_g    / directory;
     563            configuration_->configPath_ = configuration_->configPath_ / directory;
     564            configuration_->logPath_    = configuration_->logPath_    / directory;
    527565        }
    528566    }
     
    538576    {
    539577        std::vector<std::pair<boost::filesystem::path, std::string> > directories;
    540         directories.push_back(std::make_pair(boost::filesystem::path(configPath_g), "config"));
    541         directories.push_back(std::make_pair(boost::filesystem::path(logPath_g), "log"));
     578        directories.push_back(std::make_pair(boost::filesystem::path(configuration_->configPath_), "config"));
     579        directories.push_back(std::make_pair(boost::filesystem::path(configuration_->logPath_), "log"));
    542580
    543581        for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin();
Note: See TracChangeset for help on using the changeset viewer.