[Orxonox-commit 716] r3247 - in branches/core4/src: core orxonox

rgrieder at orxonox.net rgrieder at orxonox.net
Mon Jun 29 14:01:51 CEST 2009


Author: rgrieder
Date: 2009-06-29 14:01:51 +0200 (Mon, 29 Jun 2009)
New Revision: 3247

Modified:
   branches/core4/src/core/Core.cc
   branches/core4/src/core/Core.h
   branches/core4/src/core/Game.cc
   branches/core4/src/core/Game.h
   branches/core4/src/core/Language.cc
   branches/core4/src/core/Language.h
   branches/core4/src/orxonox/Main.cc
Log:
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.

Modified: branches/core4/src/core/Core.cc
===================================================================
--- branches/core4/src/core/Core.cc	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/core/Core.cc	2009-06-29 12:01:51 UTC (rev 3247)
@@ -76,13 +76,6 @@
 
 namespace orxonox
 {
-    //! Path to the parent directory of the ones above if program was installed with relativ pahts
-    static boost::filesystem::path rootPath_g;
-    static boost::filesystem::path executablePath_g;            //!< Path to the executable
-    static boost::filesystem::path mediaPath_g;                 //!< Path to the media file folder
-    static boost::filesystem::path configPath_g;                //!< Path to the config file folder
-    static boost::filesystem::path logPath_g;                   //!< Path to the log file folder
-
     //! Static pointer to the singleton
     Core* Core::singletonRef_s  = 0;
 
@@ -91,26 +84,159 @@
     SetCommandLineArgument(settingsFile, "orxonox.ini");
     SetCommandLineArgument(limitToCPU, 0).information("0: off | #cpu");
 
-    Core::Core()
+    /**
+    @brief
+        Helper class for the Core singleton: we cannot derive
+        Core from OrxonoxClass because we need to handle the Identifier
+        destruction in the Core destructor.
+    */
+    class CoreConfiguration : public OrxonoxClass
     {
-        RegisterRootObject(Core);
+    public:
+        CoreConfiguration()
+        {
+        }
 
+        void CoreConfiguration::initialise()
+        {
+            RegisterRootObject(CoreConfiguration);
+            this->setConfigValues();
+
+            // Possible media path override by the command line
+            if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
+                tsetMediaPath(CommandLine::getValue("mediaPath"));
+        }
+
+        /**
+            @brief Function to collect the SetConfigValue-macro calls.
+        */
+        void setConfigValues()
+        {
+#ifdef NDEBUG
+            const unsigned int defaultLevelConsole = 1;
+            const unsigned int defaultLevelLogfile = 3;
+            const unsigned int defaultLevelShell   = 1;
+#else
+            const unsigned int defaultLevelConsole = 3;
+            const unsigned int defaultLevelLogfile = 4;
+            const unsigned int defaultLevelShell   = 3;
+#endif
+            SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
+                .description("The maximal level of debug output shown in the console")
+                .callback(this, &CoreConfiguration::debugLevelChanged);
+            SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
+                .description("The maximal level of debug output shown in the logfile")
+                .callback(this, &CoreConfiguration::debugLevelChanged);
+            SetConfigValue(softDebugLevelShell_, defaultLevelShell)
+                .description("The maximal level of debug output shown in the ingame shell")
+                .callback(this, &CoreConfiguration::debugLevelChanged);
+
+            SetConfigValue(language_, Language::getLanguage().defaultLanguage_)
+                .description("The language of the ingame text")
+                .callback(this, &CoreConfiguration::languageChanged);
+            SetConfigValue(bInitializeRandomNumberGenerator_, true)
+                .description("If true, all random actions are different each time you start the game")
+                .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
+
+            SetConfigValue(mediaPathString_, mediaPath_.string())
+                .description("Relative path to the game data.")
+                .callback(this, &CoreConfiguration::mediaPathChanged);
+        }
+
+        /**
+            @brief Callback function if the debug level has changed.
+        */
+        void debugLevelChanged()
+        {
+            // softDebugLevel_ is the maximum of the 3 variables
+            this->softDebugLevel_ = this->softDebugLevelConsole_;
+            if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
+                this->softDebugLevel_ = this->softDebugLevelLogfile_;
+            if (this->softDebugLevelShell_ > this->softDebugLevel_)
+                this->softDebugLevel_ = this->softDebugLevelShell_;
+
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
+            OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
+        }
+
+        /**
+            @brief Callback function if the language has changed.
+        */
+        void languageChanged()
+        {
+            // Read the translation file after the language was configured
+            Language::getLanguage().readTranslatedLanguageFile();
+        }
+
+        /**
+        @brief
+            Callback function if the media path has changed.
+        */
+        void mediaPathChanged()
+        {
+            mediaPath_ = boost::filesystem::path(this->mediaPathString_);
+        }
+
+        /**
+            @brief Sets the language in the config-file back to the default.
+        */
+        void resetLanguage()
+        {
+            ResetConfigValue(language_);
+        }
+
+        /**
+        @brief
+            Temporary sets the media path
+        @param path
+            The new media path
+        */
+        void tsetMediaPath(const std::string& path)
+        {
+            ModifyConfigValue(mediaPathString_, tset, path);
+        }
+
+        void initializeRandomNumberGenerator()
+        {
+            static bool bInitialized = false;
+            if (!bInitialized && this->bInitializeRandomNumberGenerator_)
+            {
+                srand(static_cast<unsigned int>(time(0)));
+                rand();
+                bInitialized = true;
+            }
+        }
+
+        int softDebugLevel_;                            //!< The debug level
+        int softDebugLevelConsole_;                     //!< The debug level for the console
+        int softDebugLevelLogfile_;                     //!< The debug level for the logfile
+        int softDebugLevelShell_;                       //!< The debug level for the ingame shell
+        std::string language_;                          //!< The language
+        bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
+        std::string mediaPathString_;                   //!< Path to the data/media file folder as string
+
+        //! Path to the parent directory of the ones above if program was installed with relativ pahts
+        boost::filesystem::path rootPath_;
+        boost::filesystem::path executablePath_;        //!< Path to the executable
+        boost::filesystem::path mediaPath_;             //!< Path to the media file folder
+        boost::filesystem::path configPath_;            //!< Path to the config file folder
+        boost::filesystem::path logPath_;               //!< Path to the log file folder
+    };
+
+
+    Core::Core(int argc, char** argv)
+    {
         assert(Core::singletonRef_s == 0);
         Core::singletonRef_s = this;
-    }
 
-    void Core::initialise(int argc, char** argv)
-    {
-        // Parse command line arguments fist
+        // We need the variables very soon. But don't configure them yet!
+        this->configuration_ = new CoreConfiguration();
+
+        // Parse command line arguments first
         CommandLine::parseCommandLine(argc, argv);
 
-        // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
-        // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
-        // the timer though).
-        int limitToCPU = CommandLine::getValue("limitToCPU");
-        if (limitToCPU > 0)
-            setThreadAffinity((unsigned int)limitToCPU);
-
         // Determine and set the location of the executable
         setExecutablePath();
 
@@ -124,13 +250,21 @@
         // create a signal handler (only active for linux)
         // This call is placed as soon as possible, but after the directories are set
         this->signalHandler_ = new SignalHandler();
-        this->signalHandler_->doCatch(executablePath_g.string(), Core::getLogPathString() + "orxonox_crash.log");
+        this->signalHandler_->doCatch(configuration_->executablePath_.string(), Core::getLogPathString() + "orxonox_crash.log");
 
         // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
         OutputHandler::getOutStream().setLogPath(Core::getLogPathString());
 
+        // Parse additional options file now that we know its path
         CommandLine::parseFile();
 
+        // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
+        // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
+        // the timer though).
+        int limitToCPU = CommandLine::getValue("limitToCPU");
+        if (limitToCPU > 0)
+            setThreadAffinity((unsigned int)limitToCPU);
+
         // Manage ini files and set the default settings file (usually orxonox.ini)
         this->configFileManager_ = new ConfigFileManager();
         this->configFileManager_->setFilename(ConfigFileType::Settings,
@@ -140,15 +274,8 @@
 
         // Do this soon after the ConfigFileManager has been created to open up the
         // possibility to configure everything below here
-        this->setConfigValues();
+        this->configuration_->initialise();
 
-        // Possible media path override by the command line
-        if (!CommandLine::getArgument("mediaPath")->hasDefaultValue())
-        {
-            //std::string mediaPath = CommandLine::getValue("mediaPath");
-            Core::tsetMediaPath(CommandLine::getValue("mediaPath"));
-        }
-
         // Create the lua interface
         this->luaBind_ = new LuaBind();
 
@@ -161,8 +288,6 @@
 
         // creates the class hierarchy for all classes with factories
         Factory::createClassHierarchy();
-        
-        this->loaded_ = true;
     }
 
     /**
@@ -170,12 +295,11 @@
     */
     Core::~Core()
     {
-        this->loaded_ = false;
-
         delete this->shell_;
         delete this->tclThreadManager_;
         delete this->tclBind_;
         delete this->luaBind_;
+        delete this->configuration_;
         delete this->languageInstance_;
         delete this->configFileManager_;
 
@@ -184,92 +308,31 @@
         // Also delete external console command that don't belong to an Identifier
         CommandExecutor::destroyExternalCommands();
 
+        // Clean up class hierarchy stuff (identifiers, XMLPort, configValues, consoleCommand)
+        Identifier::destroyAllIdentifiers();
+
         assert(Core::singletonRef_s);
         Core::singletonRef_s = 0;
         delete this->signalHandler_;
     }
 
     /**
-        @brief Function to collect the SetConfigValue-macro calls.
-    */
-    void Core::setConfigValues()
-    {
-#ifdef NDEBUG
-        const unsigned int defaultLevelConsole = 1;
-        const unsigned int defaultLevelLogfile = 3;
-        const unsigned int defaultLevelShell   = 1;
-#else
-        const unsigned int defaultLevelConsole = 3;
-        const unsigned int defaultLevelLogfile = 4;
-        const unsigned int defaultLevelShell   = 3;
-#endif
-        SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
-            .description("The maximal level of debug output shown in the console").callback(this, &Core::debugLevelChanged);
-        SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
-            .description("The maximal level of debug output shown in the logfile").callback(this, &Core::debugLevelChanged);
-        SetConfigValue(softDebugLevelShell_, defaultLevelShell)
-            .description("The maximal level of debug output shown in the ingame shell").callback(this, &Core::debugLevelChanged);
-
-        SetConfigValue(language_, Language::getLanguage().defaultLanguage_).description("The language of the ingame text").callback(this, &Core::languageChanged);
-        SetConfigValue(bInitializeRandomNumberGenerator_, true).description("If true, all random actions are different each time you start the game").callback(this, &Core::initializeRandomNumberGenerator);
-
-        SetConfigValue(mediaPathString_, mediaPath_g.string())
-            .description("Relative path to the game data.").callback(this, &Core::mediaPathChanged);
-    }
-
-    /**
-        @brief Callback function if the debug level has changed.
-    */
-    void Core::debugLevelChanged()
-    {
-        // softDebugLevel_ is the maximum of the 3 variables
-        this->softDebugLevel_ = this->softDebugLevelConsole_;
-        if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
-            this->softDebugLevel_ = this->softDebugLevelLogfile_;
-        if (this->softDebugLevelShell_ > this->softDebugLevel_)
-            this->softDebugLevel_ = this->softDebugLevelShell_;
-
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
-        OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
-    }
-
-    /**
-        @brief Callback function if the language has changed.
-    */
-    void Core::languageChanged()
-    {
-        // Read the translation file after the language was configured
-        Language::getLanguage().readTranslatedLanguageFile();
-    }
-
-    /**
-    @brief
-        Callback function if the media path has changed.
-    */
-    void Core::mediaPathChanged()
-    {
-        mediaPath_g = boost::filesystem::path(this->mediaPathString_);
-    }
-
-    /**
-        @brief Returns the softDebugLevel for the given device (returns a default-value if the class ist right about to be created).
+        @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).
         @param device The device
         @return The softDebugLevel
     */
-    int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
+    /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
     {
         switch (device)
         {
         case OutputHandler::LD_All:
-            return Core::getInstance().softDebugLevel_;
+            return Core::getInstance().configuration_->softDebugLevel_;
         case OutputHandler::LD_Console:
-            return Core::getInstance().softDebugLevelConsole_;
+            return Core::getInstance().configuration_->softDebugLevelConsole_;
         case OutputHandler::LD_Logfile:
-            return Core::getInstance().softDebugLevelLogfile_;
+            return Core::getInstance().configuration_->softDebugLevelLogfile_;
         case OutputHandler::LD_Shell:
-            return Core::getInstance().softDebugLevelShell_;
+            return Core::getInstance().configuration_->softDebugLevelShell_;
         default:
             assert(0);
             return 2;
@@ -281,94 +344,68 @@
         @param device The device
         @param level The level
     */
-     void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
-     {
+    /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
+    {
         if (device == OutputHandler::LD_All)
-            Core::getInstance().softDebugLevel_ = level;
+            Core::getInstance().configuration_->softDebugLevel_ = level;
         else if (device == OutputHandler::LD_Console)
-            Core::getInstance().softDebugLevelConsole_ = level;
+            Core::getInstance().configuration_->softDebugLevelConsole_ = level;
         else if (device == OutputHandler::LD_Logfile)
-            Core::getInstance().softDebugLevelLogfile_ = level;
+            Core::getInstance().configuration_->softDebugLevelLogfile_ = level;
         else if (device == OutputHandler::LD_Shell)
-            Core::getInstance().softDebugLevelShell_ = level;
+            Core::getInstance().configuration_->softDebugLevelShell_ = level;
 
         OutputHandler::setSoftDebugLevel(device, level);
-     }
+    }
 
     /**
         @brief Returns the configured language.
     */
-    const std::string& Core::getLanguage()
+    /*static*/ const std::string& Core::getLanguage()
     {
-        return Core::getInstance().language_;
+        return Core::getInstance().configuration_->language_;
     }
 
     /**
         @brief Sets the language in the config-file back to the default.
     */
-    void Core::resetLanguage()
+    /*static*/ void Core::resetLanguage()
     {
-        Core::getInstance().resetLanguageIntern();
+        Core::getInstance().configuration_->resetLanguage();
     }
 
-    /**
-        @brief Sets the language in the config-file back to the default.
-    */
-    void Core::resetLanguageIntern()
+    /*static*/ void Core::tsetMediaPath(const std::string& path)
     {
-        ResetConfigValue(language_);
+        getInstance().configuration_->tsetMediaPath(path);
     }
 
-    /**
-    @brief
-        Temporary sets the media path
-    @param path
-        The new media path
-    */
-    void Core::_tsetMediaPath(const std::string& path)
-    {
-        ModifyConfigValue(mediaPathString_, tset, path);
-    }
-
     /*static*/ const boost::filesystem::path& Core::getMediaPath()
     {
-        return mediaPath_g;
+        return getInstance().configuration_->mediaPath_;
     }
     /*static*/ std::string Core::getMediaPathString()
     {
-        return mediaPath_g.string() + '/';
+        return getInstance().configuration_->mediaPath_.string() + '/';
     }
 
     /*static*/ const boost::filesystem::path& Core::getConfigPath()
     {
-        return configPath_g;
+        return getInstance().configuration_->configPath_;
     }
     /*static*/ std::string Core::getConfigPathString()
     {
-        return configPath_g.string() + '/';
+        return getInstance().configuration_->configPath_.string() + '/';
     }
 
     /*static*/ const boost::filesystem::path& Core::getLogPath()
     {
-        return logPath_g;
+        return getInstance().configuration_->logPath_;
     }
     /*static*/ std::string Core::getLogPathString()
     {
-        return logPath_g.string() + '/';
+        return getInstance().configuration_->logPath_.string() + '/';
     }
 
-    void Core::initializeRandomNumberGenerator()
-    {
-        static bool bInitialized = false;
-        if (!bInitialized && this->bInitializeRandomNumberGenerator_)
-        {
-            srand(static_cast<unsigned int>(time(0)));
-            rand();
-            bInitialized = true;
-        }
-    }
-
-
     /**
     @note
         The code of this function has been copied and adjusted from OGRE, an open source graphics engine.
@@ -458,9 +495,9 @@
         buffer[ret] = 0;
 #endif
 
-        executablePath_g = boost::filesystem::path(buffer);
+        configuration_->executablePath_ = boost::filesystem::path(buffer);
 #ifndef ORXONOX_PLATFORM_APPLE
-        executablePath_g = executablePath_g.branch_path(); // remove executable name
+        configuration_->executablePath_ = configuration_->executablePath_.branch_path(); // remove executable name
 #endif
     }
 
@@ -474,33 +511,34 @@
     */
     void Core::checkDevBuild()
     {
-        if (boost::filesystem::exists(executablePath_g / "orxonox_dev_build.keep_me"))
+        if (boost::filesystem::exists(configuration_->executablePath_ / "orxonox_dev_build.keep_me"))
         {
             COUT(1) << "Running from the build tree." << std::endl;
             Core::isDevBuild_ = true;
-            mediaPath_g  = ORXONOX_MEDIA_DEV_PATH;
-            configPath_g = ORXONOX_CONFIG_DEV_PATH;
-            logPath_g    = ORXONOX_LOG_DEV_PATH;
+            configuration_->mediaPath_  = ORXONOX_MEDIA_DEV_PATH;
+            configuration_->configPath_ = ORXONOX_CONFIG_DEV_PATH;
+            configuration_->logPath_    = ORXONOX_LOG_DEV_PATH;
         }
         else
         {
 #ifdef INSTALL_COPYABLE // --> relative paths
             // Also set the root path
             boost::filesystem::path relativeExecutablePath(ORXONOX_RUNTIME_INSTALL_PATH);
-            rootPath_g = executablePath_g;
-            while (!boost::filesystem::equivalent(rootPath_g / relativeExecutablePath, executablePath_g) && !rootPath_g.empty())
-                rootPath_g = rootPath_g.branch_path();
-            if (rootPath_g.empty())
+            configuration_->rootPath_ = configuration_->executablePath_;
+            while (!boost::filesystem::equivalent(configuration_->rootPath_ / relativeExecutablePath, configuration_->executablePath_)
+                   && !configuration_->rootPath_.empty())
+                configuration_->rootPath_ = configuration_->rootPath_.branch_path();
+            if (configuration_->rootPath_.empty())
                 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
 
             // Using paths relative to the install prefix, complete them
-            mediaPath_g  = rootPath_g / ORXONOX_MEDIA_INSTALL_PATH;
-            configPath_g = rootPath_g / ORXONOX_CONFIG_INSTALL_PATH;
-            logPath_g    = rootPath_g / ORXONOX_LOG_INSTALL_PATH;
+            configuration_->mediaPath_  = configuration_->rootPath_ / ORXONOX_MEDIA_INSTALL_PATH;
+            configuration_->configPath_ = configuration_->rootPath_ / ORXONOX_CONFIG_INSTALL_PATH;
+            configuration_->logPath_    = configuration_->rootPath_ / ORXONOX_LOG_INSTALL_PATH;
 #else
             // There is no root path, so don't set it at all
 
-            mediaPath_g  = ORXONOX_MEDIA_INSTALL_PATH;
+            configuration_->mediaPath_  = ORXONOX_MEDIA_INSTALL_PATH;
 
             // Get user directory
 #  ifdef ORXONOX_PLATFORM_UNIX /* Apple? */
@@ -513,8 +551,8 @@
             boost::filesystem::path userDataPath(userDataPathPtr);
             userDataPath /= ".orxonox";
 
-            configPath_g = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
-            logPath_g    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
+            configuration_->configPath_ = userDataPath / ORXONOX_CONFIG_INSTALL_PATH;
+            configuration_->logPath_    = userDataPath / ORXONOX_LOG_INSTALL_PATH;
 #endif
         }
 
@@ -522,8 +560,8 @@
         if (!CommandLine::getArgument("writingPathSuffix")->hasDefaultValue())
         {
             std::string directory(CommandLine::getValue("writingPathSuffix").getString());
-            configPath_g = configPath_g / directory;
-            logPath_g    = logPath_g    / directory;
+            configuration_->configPath_ = configuration_->configPath_ / directory;
+            configuration_->logPath_    = configuration_->logPath_    / directory;
         }
     }
 
@@ -537,8 +575,8 @@
     void Core::createDirectories()
     {
         std::vector<std::pair<boost::filesystem::path, std::string> > directories;
-        directories.push_back(std::make_pair(boost::filesystem::path(configPath_g), "config"));
-        directories.push_back(std::make_pair(boost::filesystem::path(logPath_g), "log"));
+        directories.push_back(std::make_pair(boost::filesystem::path(configuration_->configPath_), "config"));
+        directories.push_back(std::make_pair(boost::filesystem::path(configuration_->logPath_), "log"));
 
         for (std::vector<std::pair<boost::filesystem::path, std::string> >::iterator it = directories.begin();
             it != directories.end(); ++it)

Modified: branches/core4/src/core/Core.h
===================================================================
--- branches/core4/src/core/Core.h	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/core/Core.h	2009-06-29 12:01:51 UTC (rev 3247)
@@ -42,11 +42,12 @@
 #include "CorePrereqs.h"
 
 #include <cassert>
-#include "OrxonoxClass.h"
 #include "util/OutputHandler.h"
 
 namespace orxonox
 {
+    class CoreConfiguration;
+
     /**
     @brief
         The Core class is a singleton used to configure the program basics.
@@ -54,7 +55,7 @@
         The class provides information about the media, config and log path.
         It determines those by the use of platform specific functions.
     */
-    class _CoreExport Core : public OrxonoxClass
+    class _CoreExport Core
     {
         public:
             /**
@@ -64,10 +65,9 @@
             @throws
                 GeneralException
             */
-            Core();
+            Core(int argc, char** argv);
             ~Core();
 
-            void initialise(int argc, char** argv);
             void setConfigValues();
 
             void update(const Clock& time);
@@ -79,8 +79,7 @@
             static const std::string& getLanguage();
             static void  resetLanguage();
 
-            static void tsetMediaPath(const std::string& path)
-            { assert(singletonRef_s); singletonRef_s->_tsetMediaPath(path); }
+            static void tsetMediaPath(const std::string& path);
             //! Returns the path to the config files as boost::filesystem::path
             static const boost::filesystem::path& getMediaPath();
             //! Returns the path to the config files as boost::filesystem::path
@@ -102,13 +101,6 @@
             void createDirectories();
             void setThreadAffinity(int limitToCPU);
 
-            void resetLanguageIntern();
-            void initializeRandomNumberGenerator();
-            void debugLevelChanged();
-            void languageChanged();
-            void mediaPathChanged();
-            void _tsetMediaPath(const std::string& path);
-
             // Singletons
             ConfigFileManager*    configFileManager_;
             Language*             languageInstance_;
@@ -118,15 +110,8 @@
             TclBind*              tclBind_;
             TclThreadManager*     tclThreadManager_;
 
-            int softDebugLevel_;                            //!< The debug level
-            int softDebugLevelConsole_;                     //!< The debug level for the console
-            int softDebugLevelLogfile_;                     //!< The debug level for the logfile
-            int softDebugLevelShell_;                       //!< The debug level for the ingame shell
-            std::string language_;                          //!< The language
-            bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
-            std::string mediaPathString_;                   //!< Path to the data/media file folder as string
             bool isDevBuild_;                               //!< True for builds in the build directory (not installed)
-            bool loaded_;                                   //!< Only true if constructor was interrupted
+            CoreConfiguration*    configuration_;
 
             static Core* singletonRef_s;
     };

Modified: branches/core4/src/core/Game.cc
===================================================================
--- branches/core4/src/core/Game.cc	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/core/Game.cc	2009-06-29 12:01:51 UTC (rev 3247)
@@ -57,18 +57,52 @@
         { Game::getInstance().stop(); }
     SetConsoleCommandShortcutExternAlias(stop_game, "exit");
 
-    struct _CoreExport GameStateTreeNode
+    std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s;
+    Game* Game::singletonRef_s = 0;
+
+
+    /**
+    @brief
+        Represents one node of the game state tree.
+    */
+    struct GameStateTreeNode
     {
         GameState* state_;
         weak_ptr<GameStateTreeNode> parent_;
         std::vector<shared_ptr<GameStateTreeNode> > children_;
     };
 
-    std::map<std::string, Game::GameStateInfo> Game::gameStateDeclarations_s;
-    Game* Game::singletonRef_s = 0;
 
     /**
     @brief
+        Another helper class for the Game singleton: we cannot derive
+        Game from OrxonoxClass because we need to handle the Identifier
+        destruction in the Core destructor.
+    */
+    class GameConfiguration : public OrxonoxClass
+    {
+    public:
+        GameConfiguration()
+        {
+            RegisterRootObject(GameConfiguration);
+            this->setConfigValues();
+        }
+
+        void setConfigValues()
+        {
+            SetConfigValue(statisticsRefreshCycle_, 250000)
+                .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
+            SetConfigValue(statisticsAvgLength_, 1000000)
+                .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
+        }
+
+        unsigned int statisticsRefreshCycle_;
+        unsigned int statisticsAvgLength_;
+    };
+
+
+    /**
+    @brief
         Non-initialising constructor.
     */
     Game::Game(int argc, char** argv)
@@ -98,8 +132,7 @@
         this->gameClock_ = new Clock();
 
         // Create the Core
-        this->core_ = new orxonox::Core();
-        this->core_->initialise(argc, argv);
+        this->core_ = new Core(argc, argv);
 
         // After the core has been created, we can safely instantiate the GameStates
         for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
@@ -117,9 +150,8 @@
         this->activeStateNode_ = this->rootStateNode_;
         this->activeStates_.push_back(this->rootStateNode_->state_);
 
-        // Do this after Core creation!
-        RegisterRootObject(Game);
-        this->setConfigValues();
+        // Do this after the Core creation!
+        this->configuration_ = new GameConfiguration();
     }
 
     /**
@@ -127,6 +159,9 @@
     */
     Game::~Game()
     {
+        // Destroy the configuration helper class instance
+        delete this->configuration_;
+
         // Destroy the GameStates (note that the nodes still point to them, but doesn't matter)
         for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin();
             it != gameStates_.end(); ++it)
@@ -136,20 +171,12 @@
         delete this->core_;
         delete this->gameClock_;
 
-        // Also, take care of the GameStateFactories
+        // Take care of the GameStateFactories
         GameStateFactory::destroyFactories();
 
         // Don't assign singletonRef_s with NULL! Recreation is not supported
     }
 
-    void Game::setConfigValues()
-    {
-        SetConfigValue(statisticsRefreshCycle_, 250000)
-            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
-        SetConfigValue(statisticsAvgLength_, 1000000)
-            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
-    }
-
     /**
     @brief
         Main loop of the orxonox game.
@@ -244,11 +271,11 @@
             }
 
             // STATISTICS
-            if (this->periodTime_ > statisticsRefreshCycle_)
+            if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
             {
                 std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
                 assert(it != this->statisticsTickTimes_.end());
-                int64_t lastTime = currentTime - this->statisticsAvgLength_;
+                int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
                 if ((int64_t)it->tickTime < lastTime)
                 {
                     do
@@ -265,7 +292,7 @@
                 this->avgFPS_ = static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
                 this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
 
-                this->periodTime_ -= this->statisticsRefreshCycle_;
+                this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
             }
         }
 

Modified: branches/core4/src/core/Game.h
===================================================================
--- branches/core4/src/core/Game.h	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/core/Game.h	2009-06-29 12:01:51 UTC (rev 3247)
@@ -46,7 +46,7 @@
 #include <boost/preprocessor/cat.hpp>
 
 #include "util/Debug.h"
-#include "OrxonoxClass.h"
+#include "util/String.h"
 
 /**
 @def
@@ -56,19 +56,19 @@
 #define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
     static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
 
-// tolua_begin
 namespace orxonox
 {
+    class GameConfiguration;
+
     /**
     @brief
         Main class responsible for running the game.
     */
-    class _CoreExport Game : public OrxonoxClass
+    class _CoreExport Game
     {
     public:
         Game(int argc, char** argv);
         ~Game();
-        void setConfigValues();
 
         void setStateHierarchy(const std::string& str);
         GameState* getState(const std::string& name);
@@ -140,6 +140,7 @@
 
         Core*                           core_;
         Clock*                          gameClock_;
+        GameConfiguration*              configuration_;
 
         bool                            bChangingState_;
         bool                            bAbort_;
@@ -152,10 +153,6 @@
         float                           avgFPS_;
         float                           avgTickTime_;
 
-        // config values
-        unsigned int                    statisticsRefreshCycle_;
-        unsigned int                    statisticsAvgLength_;
-
         static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
         static Game* singletonRef_s;        //!< Pointer to the Singleton
     };

Modified: branches/core4/src/core/Language.cc
===================================================================
--- branches/core4/src/core/Language.cc	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/core/Language.cc	2009-06-29 12:01:51 UTC (rev 3247)
@@ -193,7 +193,7 @@
         @param language The name of the language
         @return The filename
     */
-    const std::string Language::getFilename(const std::string& language)
+    std::string Language::getFilename(const std::string& language)
     {
         return std::string("translation_" + language + ".lang");
     }

Modified: branches/core4/src/core/Language.h
===================================================================
--- branches/core4/src/core/Language.h	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/core/Language.h	2009-06-29 12:01:51 UTC (rev 3247)
@@ -113,7 +113,7 @@
     //! The Language class manges the language files and entries and stores the LanguageEntry objects in a map.
     class _CoreExport Language
     {
-        friend class Core;
+        friend class CoreConfiguration;
 
         public:
             Language();
@@ -129,7 +129,7 @@
             void readDefaultLanguageFile();
             void readTranslatedLanguageFile();
             void writeDefaultLanguageFile() const;
-            static const std::string getFilename(const std::string& language);
+            static std::string getFilename(const std::string& language);
             LanguageEntry* createEntry(const LanguageEntryLabel& label, const std::string& entry);
 
             std::string defaultLanguage_;                           //!< The default language

Modified: branches/core4/src/orxonox/Main.cc
===================================================================
--- branches/core4/src/orxonox/Main.cc	2009-06-29 11:43:41 UTC (rev 3246)
+++ branches/core4/src/orxonox/Main.cc	2009-06-29 12:01:51 UTC (rev 3247)
@@ -36,7 +36,7 @@
 #include "OrxonoxPrereqs.h"
 
 #include "util/Debug.h"
-#include "core/Identifier.h"
+#include "util/Exception.h"
 #include "core/Game.h"
 
 /*
@@ -49,10 +49,14 @@
 int main(int argc, char** argv)
 #endif
 {
+    using namespace orxonox;
+
+    Game* game = 0;
+    try
     {
-        orxonox::Game orxonox(argc, argv);
+        game = new Game(argc, argv);
 
-        orxonox.setStateHierarchy(
+        game->setStateHierarchy(
         "root"
         " graphics"
         "  mainMenu"
@@ -67,13 +71,22 @@
         " ioConsole"
         );
 
-        orxonox.requestState("root");
-        orxonox.run();
+        game->requestState("root");
     }
+    catch (const std::exception& ex)
+    {
+        COUT(0) << "Orxonox failed to initialise: " << ex.what() << std::endl;
+        COUT(0) << "Terminating program." << std::endl;
+        return 1;
+    }
+    catch (...)
+    {
+        COUT(0) << "Orxonox failed to initialise: " << std::endl;
+        COUT(0) << "Terminating program." << std::endl;
+        return 1;
+    }
 
-    // Clean up class hierarchy stuff (identifiers, xmlport, configvalue, consolecommand)
-    // Needs to be done after Game destructor because of ~OrxonoxClass
-    orxonox::Identifier::destroyAllIdentifiers();
+    game->run();
 
     return 0;
 }




More information about the Orxonox-commit mailing list