Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 12, 2010, 12:47:30 AM (14 years ago)
Author:
rgrieder
Message:

Basic stuff up and running for the Qt sandbox.
No GUI support yet.

Location:
sandbox_qt/src/libraries/core
Files:
1 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • sandbox_qt/src/libraries/core/CMakeLists.txt

    r7284 r7421  
    1919
    2020SET_SOURCE_FILES(CORE_SRC_FILES
    21   CommandLineParser.cc
    22   ConfigValueContainer.cc
    2321  Core.cc
    24   DynLib.cc
    25   DynLibManager.cc
    26   Event.cc
    2722  Game.cc
    28   GameMode.cc
    29   GameState.cc
    30   GraphicsManager.cc
    31   GUIManager.cc
    32   Language.cc
    33   LuaState.cc
    34   ObjectListBase.cc
    35   OrxonoxClass.cc
    36   Resource.cc
    37   WindowEventListener.cc
    38 
    39   # hierarchy
    40   Identifier.cc
    41   MetaObjectList.cc
    42 
    43   # level
    44   BaseObject.cc
    45   ClassTreeMask.cc
    46   Loader.cc
    47   Namespace.cc
    48   NamespaceNode.cc
    49   Template.cc
    50   XMLPort.cc
    51   XMLNameListener.cc
    52 
    53 COMPILATION_BEGIN FilesystemCompilation.cc
    54   command/ArgumentCompletionFunctions.cc
    55   ConfigFileManager.cc
    56   MemoryArchive.cc
    5723  PathConfig.cc
    58 COMPILATION_END
    59 
    60   # multithreading
    61   ThreadPool.cc
    62 COMPILATION_BEGIN ThreadCompilation.cc
    63   command/TclThreadManager.cc
    64   Thread.cc
    65 COMPILATION_END
    6624)
    67 
    68 ADD_SUBDIRECTORY(command)
    69 ADD_SUBDIRECTORY(input)
    7025
    7126ORXONOX_ADD_LIBRARY(core
    7227  FIND_HEADER_FILES
    73   TOLUA_FILES
    74     command/CommandExecutor.h
    75     ConfigFileManager.h
    76     Game.h
    77     GameMode.h
    78     GUIManager.h
    79     Loader.h
    80     LuaState.h
    81     PathConfig.h
    82     input/InputManager.h
    83     input/KeyBinder.h
    84     input/KeyBinderManager.h
    85   PCH_FILE
    86     CorePrecompiledHeaders.h
    8728  LINK_LIBRARIES
    88     ${OGRE_LIBRARY}
    89     ${Boost_FILESYSTEM_LIBRARY}
    90     ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
    91     ${Boost_THREAD_LIBRARY}
    92     ${Boost_DATE_TIME_LIBRARY} # Thread dependency
    93     ${CEGUI_LIBRARY}
    94     ${CEGUILUA_LIBRARY}
    95     ${LUA_LIBRARIES}
    96     cpptcl_orxonox
    97     ogreceguirenderer_orxonox
    98     ois_orxonox
    99     tinyxml_orxonox
    100     tolua_orxonox
     29    ${QT_QTCORE_LIBRARY}
    10130    util
    10231  SOURCE_FILES
  • sandbox_qt/src/libraries/core/Core.cc

    r7401 r7421  
    3131@file
    3232@brief
    33     Implementation of the Core singleton with its global variables (avoids boost include)
     33    Implementation of the Core singleton
    3434*/
    3535
     
    3737
    3838#include <cassert>
     39#include <ctime>
    3940#include <fstream>
    4041#include <vector>
     
    4950#endif
    5051
    51 #include "util/Clock.h"
    5252#include "util/Debug.h"
    5353#include "util/Exception.h"
    54 #include "util/Scope.h"
    55 #include "util/ScopedSingletonManager.h"
    56 #include "util/SignalHandler.h"
    5754#include "PathConfig.h"
    58 #include "CommandLineParser.h"
    59 #include "ConfigFileManager.h"
    60 #include "ConfigValueIncludes.h"
    61 #include "CoreIncludes.h"
    62 #include "DynLibManager.h"
    63 #include "GameMode.h"
    64 #include "GraphicsManager.h"
    65 #include "GUIManager.h"
    66 #include "Identifier.h"
    67 #include "Language.h"
    68 #include "LuaState.h"
    69 #include "command/ConsoleCommand.h"
    70 #include "command/IOConsole.h"
    71 #include "command/TclBind.h"
    72 #include "command/TclThreadManager.h"
    73 #include "input/InputManager.h"
    7455
    7556namespace orxonox
     
    7859    Core* Core::singletonPtr_s  = 0;
    7960
    80     SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
    81     SetCommandLineSwitch(noIOConsole).information("Use this if you don't want to use the IOConsole (for instance for Lua debugging)");
    82 
    83 #ifdef ORXONOX_PLATFORM_WINDOWS
    84     SetCommandLineArgument(limitToCPU, 1).information("Limits the program to one CPU/core (1, 2, 3, etc.). Default is the first core (faster than off)");
    85 #endif
    86 
    8761    Core::Core(const std::string& cmdLine)
    88         // Cleanup guard for identifier destruction (incl. XMLPort, configValues, consoleCommands)
    89         : identifierDestroyer_(Identifier::destroyAllIdentifiers)
    90         // Cleanup guard for external console commands that don't belong to an Identifier
    91         , consoleCommandDestroyer_(ConsoleCommand::destroyAll)
    92         , bGraphicsLoaded_(false)
    93         , bStartIOConsole_(true)
    9462    {
    9563        // Set the hard coded fixed paths
    9664        this->pathConfig_.reset(new PathConfig());
    9765
    98         // Create a new dynamic library manager
    99         this->dynLibManager_.reset(new DynLibManager());
    100 
    101         // Load modules
    102         const std::vector<std::string>& modulePaths = this->pathConfig_->getModulePaths();
    103         for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it)
    104         {
    105             try
    106             {
    107                 this->dynLibManager_->load(*it);
    108             }
    109             catch (...)
    110             {
    111                 COUT(1) << "Couldn't load module \"" << *it << "\": " << Exception::handleMessage() << std::endl;
    112             }
    113         }
    114 
    115         // Parse command line arguments AFTER the modules have been loaded (static code!)
    116         CommandLineParser::parseCommandLine(cmdLine);
    117 
    11866        // Set configurable paths like log, config and media
    11967        this->pathConfig_->setConfigurablePaths();
    120 
    121         // create a signal handler (only active for Linux)
    122         // This call is placed as soon as possible, but after the directories are set
    123         this->signalHandler_.reset(new SignalHandler());
    124         this->signalHandler_->doCatch(PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log");
    12568
    12669        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% (Windows) was used
    12770        OutputHandler::getInstance().setLogPath(PathConfig::getLogPathString());
    12871
    129         // Parse additional options file now that we know its path
    130         CommandLineParser::parseFile();
    131 
    13272#ifdef ORXONOX_PLATFORM_WINDOWS
    13373        // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
    134         // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
    135         // the timer though).
    136         int limitToCPU = CommandLineParser::getValue("limitToCPU");
     74        int limitToCPU = 0;//CommandLineParser::getValue("limitToCPU");
    13775        if (limitToCPU > 0)
    13876            setThreadAffinity(static_cast<unsigned int>(limitToCPU));
    13977#endif
    14078
    141         // Manage ini files and set the default settings file (usually orxonox.ini)
    142         this->configFileManager_.reset(new ConfigFileManager());
    143         this->configFileManager_->setFilename(ConfigFileType::Settings,
    144             CommandLineParser::getValue("settingsFile").getString());
    145 
    146         // Required as well for the config values
    147         this->languageInstance_.reset(new Language());
    148 
    149         // Do this soon after the ConfigFileManager has been created to open up the
    150         // possibility to configure everything below here
    151         ClassIdentifier<Core>::getIdentifier("Core")->initialiseObject(this, "Core", true);
    152         this->setConfigValues();
    153 
    154         // create persistent io console
    155         if (CommandLineParser::getValue("noIOConsole").getBool())
    156         {
    157             ModifyConfigValue(bStartIOConsole_, tset, false);
    158         }
    159         if (this->bStartIOConsole_)
    160             this->ioConsole_.reset(new IOConsole());
    161 
    162         // creates the class hierarchy for all classes with factories
    163         Identifier::createClassHierarchy();
    164 
    165         // Load OGRE excluding the renderer and the render window
    166         this->graphicsManager_.reset(new GraphicsManager(false));
    167 
    168         // initialise Tcl
    169         this->tclBind_.reset(new TclBind(PathConfig::getDataPathString()));
    170         this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
    171 
    172         // Create singletons that always exist (in other libraries)
    173         this->rootScope_.reset(new Scope<ScopeID::Root>());
    174 
    17579        // Generate documentation instead of normal run?
    17680        std::string docFilename;
    177         CommandLineParser::getValue("generateDoc", &docFilename);
     81        //CommandLineParser::getValue("generateDoc", &docFilename);
    17882        if (!docFilename.empty())
    17983        {
     
    18185            if (docFile.is_open())
    18286            {
    183                 CommandLineParser::generateDoc(docFile);
     87                //CommandLineParser::generateDoc(docFile);
    18488                docFile.close();
    18589            }
     
    19195    /**
    19296    @brief
    193         All destruction code is handled by scoped_ptrs and ScopeGuards.
     97        All destruction code is handled by QScopedPointers
    19498    */
    19599    Core::~Core()
    196100    {
    197         // Remove us from the object lists again to avoid problems when destroying them
    198         this->unregisterObject();
    199101    }
    200102
     
    207109        const unsigned int defaultLevelLogFile = 4;
    208110#endif
     111        /*
    209112        SetConfigValueExternal(softDebugLevelLogFile_, "OutputHandler", "softDebugLevelLogFile", defaultLevelLogFile)
    210113            .description("The maximum level of debug output shown in the log file");
     
    219122        SetConfigValue(bStartIOConsole_, true)
    220123            .description("Set to false if you don't want to use the IOConsole (for Lua debugging for instance)");
    221     }
    222 
    223     //! Callback function if the language has changed.
    224     void Core::languageChanged()
    225     {
    226         // Read the translation file after the language was configured
    227         Language::getInstance().readTranslatedLanguageFile();
     124        */
    228125    }
    229126
     
    237134            bInitialized = true;
    238135        }
    239     }
    240 
    241     void Core::loadGraphics()
    242     {
    243         // Any exception should trigger this, even in upgradeToGraphics (see its remarks)
    244         Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics);
    245 
    246         // Upgrade OGRE to receive a render window
    247         try
    248         {
    249             graphicsManager_->upgradeToGraphics();
    250         }
    251         catch (...)
    252         {
    253             // Recovery from this is very difficult. It requires to completely
    254             // destroy Ogre related objects and load again (without graphics).
    255             // However since Ogre 1.7 there seems to be a problem when Ogre
    256             // throws an exception and the graphics engine then gets destroyed
    257             // and reloaded between throw and catch (access violation in MSVC).
    258             // That's why we abort completely and only display the exception.
    259             COUT(0) << "An exception occurred during upgrade to graphics. "
    260                     << "That is unrecoverable. The message was:" << endl
    261                     << Exception::handleMessage() << endl;
    262             abort();
    263         }
    264 
    265         // Calls the InputManager which sets up the input devices.
    266         inputManager_.reset(new InputManager());
    267 
    268         // Load the CEGUI interface
    269         guiManager_.reset(new GUIManager(inputManager_->getMousePosition()));
    270 
    271         bGraphicsLoaded_ = true;
    272         GameMode::bShowsGraphics_s = true;
    273 
    274         // Load some sort of a debug overlay (only denoted by its name, "debug.oxo")
    275         graphicsManager_->loadDebugOverlay();
    276 
    277         // Create singletons associated with graphics (in other libraries)
    278         graphicsScope_.reset(new Scope<ScopeID::Graphics>());
    279 
    280         unloader.Dismiss();
    281     }
    282 
    283     void Core::unloadGraphics()
    284     {
    285         this->graphicsScope_.reset();
    286         this->guiManager_.reset();
    287         this->inputManager_.reset();
    288         this->graphicsManager_.reset();
    289 
    290         // Load Ogre::Root again, but without the render system
    291         try
    292             { this->graphicsManager_.reset(new GraphicsManager(false)); }
    293         catch (...)
    294         {
    295             COUT(0) << "An exception occurred during 'unloadGraphics':" << Exception::handleMessage() << std::endl
    296                     << "Another exception might be being handled which may lead to undefined behaviour!" << std::endl
    297                     << "Terminating the program." << std::endl;
    298             abort();
    299         }
    300 
    301         bGraphicsLoaded_ = false;
    302         GameMode::bShowsGraphics_s = false;
    303     }
    304 
    305     //! Sets the language in the config-file back to the default.
    306     void Core::resetLanguage()
    307     {
    308         ResetConfigValue(language_);
    309136    }
    310137
     
    354181#endif
    355182    }
    356 
    357     void Core::preUpdate(const Clock& time)
    358     {
    359         // Update singletons before general ticking
    360         ScopedSingletonManager::preUpdate<ScopeID::Root>(time);
    361         if (this->bGraphicsLoaded_)
    362         {
    363             // Process input events
    364             this->inputManager_->preUpdate(time);
    365             // Update GUI
    366             this->guiManager_->preUpdate(time);
    367             // Update singletons before general ticking
    368             ScopedSingletonManager::preUpdate<ScopeID::Graphics>(time);
    369         }
    370         // Process console events and status line
    371         if (this->ioConsole_ != NULL)
    372             this->ioConsole_->preUpdate(time);
    373         // Process thread commands
    374         this->tclThreadManager_->preUpdate(time);
    375     }
    376 
    377     void Core::postUpdate(const Clock& time)
    378     {
    379         // Update singletons just before rendering
    380         ScopedSingletonManager::postUpdate<ScopeID::Root>(time);
    381         if (this->bGraphicsLoaded_)
    382         {
    383             // Update singletons just before rendering
    384             ScopedSingletonManager::postUpdate<ScopeID::Graphics>(time);
    385             // Render (doesn't throw)
    386             this->graphicsManager_->postUpdate(time);
    387         }
    388     }
    389183}
  • sandbox_qt/src/libraries/core/Core.h

    r7401 r7421  
    4545
    4646#include <string>
    47 #include <boost/scoped_ptr.hpp>
     47#include <QScopedPointer>
    4848#include <loki/ScopeGuard.h>
    4949
    5050#include "util/Singleton.h"
    51 #include "OrxonoxClass.h"
     51#include "PathConfig.h"
    5252
    5353namespace orxonox
     
    5959        You should only create this singleton once because it destroys the identifiers!
    6060    */
    61     class _CoreExport Core : public Singleton<Core>, public OrxonoxClass
     61    class _CoreExport Core : public Singleton<Core>
    6262    {
    6363        typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
     
    7878            void setConfigValues();
    7979
    80             //! Returns the configured language.
    81             const std::string& getLanguage()
    82                 { return this->language_; }
    83             void resetLanguage();
    84 
    8580        private:
    8681            Core(const Core&); //!< Don't use (undefined symbol)
    8782
    88             void languageChanged();
    8983            void initRandomNumberGenerator();
    9084
    91             void preUpdate(const Clock& time);
    92             void postUpdate(const Clock& time);
    93 
    94             void loadGraphics();
    95             void unloadGraphics();
     85            void update() {}
    9686
    9787            void setThreadAffinity(int limitToCPU);
    9888            // MANAGED SINGLETONS/OBJECTS
    9989            // Mind the order for the destruction!
    100             scoped_ptr<PathConfig>        pathConfig_;
    101             scoped_ptr<DynLibManager>     dynLibManager_;
    102             scoped_ptr<SignalHandler>     signalHandler_;
    103             SimpleScopeGuard              identifierDestroyer_;
    104             SimpleScopeGuard              consoleCommandDestroyer_;
    105             scoped_ptr<ConfigFileManager> configFileManager_;
    106             scoped_ptr<Language>          languageInstance_;
    107             scoped_ptr<IOConsole>         ioConsole_;
    108             scoped_ptr<TclBind>           tclBind_;
    109             scoped_ptr<TclThreadManager>  tclThreadManager_;
    110             scoped_ptr<Scope<ScopeID::Root> > rootScope_;
    111             // graphical
    112             scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
    113             scoped_ptr<InputManager>      inputManager_;        //!< Interface to OIS
    114             scoped_ptr<GUIManager>        guiManager_;          //!< Interface to GUI
    115             scoped_ptr<Scope<ScopeID::Graphics> > graphicsScope_;
     90            QScopedPointer<PathConfig>    pathConfig_;
    11691
    117             bool                          bGraphicsLoaded_;
    11892            int                           softDebugLevelLogFile_;      //!< The debug level for the log file (belongs to OutputHandler)
    119             std::string                   language_;                   //!< The language
    12093            bool                          bInitRandomNumberGenerator_; //!< If true, srand(time(0)) is called
    121             bool                          bStartIOConsole_;            //!< Set to false if you don't want to use the IOConsole
    12294
    12395            static Core*                  singletonPtr_s;
  • sandbox_qt/src/libraries/core/CorePrereqs.h

    r7284 r7421  
    3737
    3838#include "OrxonoxConfig.h"
    39 #include <boost/version.hpp>
    4039
    4140//-----------------------------------------------------------------------
     
    6362//-----------------------------------------------------------------------
    6463
    65 namespace orxonox
    66 {
    67     static const uint32_t OBJECTID_UNKNOWN = static_cast<uint32_t>(-1);
    68 }
    69 
    7064//-----------------------------------------------------------------------
    7165// Enums
    7266//-----------------------------------------------------------------------
    73 
    74 namespace orxonox
    75 {
    76     namespace XMLPort
    77     {
    78         enum Mode
    79         {
    80             NOP,
    81             LoadObject,
    82             SaveObject,
    83             ExpandObject
    84         };
    85     }
    86 
    87     namespace ConfigFileType
    88     {
    89         enum Value
    90         {
    91             Settings,
    92             JoyStickCalibration,
    93             CommandHistory
    94             // Don't forget to adjust the array size in the ConfigFileManager when adding a new entry here!
    95         };
    96     }
    97 
    98     namespace KeybindMode
    99     {
    100         enum Value
    101         {
    102             OnPress,
    103             OnHold,
    104             OnRelease,
    105             None
    106         };
    107     };
    108 }
    10967
    11068//-----------------------------------------------------------------------
     
    11472namespace orxonox
    11573{
    116     typedef std::string LanguageEntryLabel;
    117 
    118     template <class T, class U>
    119     T orxonox_cast(U*);
    120 
    121     class BaseObject;
    122     template <class T>
    123     class ClassFactory;
    124     template <class T>
    125     class ClassIdentifier;
    126     class ClassTreeMask;
    127     class ClassTreeMaskIterator;
    128     class ClassTreeMaskNode;
    129     class ClassTreeMaskObjectIterator;
    130     class CommandLineParser;
    131     class CommandLineArgument;
    132     class ConfigFile;
    133     class ConfigFileEntry;
    134     class ConfigFileEntryComment;
    135     class ConfigFileEntryValue;
    136     class ConfigFileManager;
    137     class ConfigFileSection;
    138     class ConfigValueContainer;
    13974    class Core;
    140     class DynLib;
    141     class DynLibManager;
    142     struct Event;
    143     class EventState;
    144     class Factory;
    14575    class Game;
    146     class GameState;
    147     struct GameStateInfo;
    148     struct GameStateTreeNode;
    149     class GraphicsManager;
    150     class GUIManager;
    151     class Identifier;
    152     template <class T>
    153     class Iterator;
    154     class Language;
    155     class LuaFunctor;
    156     class LuaState;
    157     class MemoryArchive;
    158     class MemoryArchiveFactory;
    159     class MetaObjectList;
    160     class MetaObjectListElement;
    161     class Namespace;
    162     class NamespaceNode;
    163     template <class T>
    164     class ObjectList;
    165     class ObjectListBase;
    166     class ObjectListBaseElement;
    167     template <class T>
    168     class ObjectListElement;
    169     template <class T>
    170     class ObjectListIterator;
    171     class OgreWindowEventListener;
    172     class OrxonoxClass;
    17376    class PathConfig;
    174     struct ResourceInfo;
    175     class SettingsConfigFile;
    176     template <class T>
    177     class SmartPtr;
    178     template <class T>
    179     class SubclassIdentifier;
    180     class Template;
    181     class Thread;
    182     class ThreadPool;
    183     template <class T>
    184     class WeakPtr;
    185     class WindowEventListener;
    186     class XMLFile;
    187     class XMLNameListener;
    188     template <class T, class O>
    189     class XMLPortClassObjectContainer;
    190     template <class T>
    191     class XMLPortClassParamContainer;
    192     class XMLPortObjectContainer;
    193     class XMLPortParamContainer;
    194 
    195     // Command
    196     class ArgumentCompleter;
    197     class ArgumentCompletionListElement;
    198     class CommandEvaluation;
    199     class ConsoleCommand;
    200     class Executor;
    201     template <class T>
    202     class ExecutorMember;
    203     class ExecutorStatic;
    204     class Functor;
    205     template <class O>
    206     class FunctorMember;
    207     typedef FunctorMember<void> FunctorStatic;
    208     template <class F, class O>
    209     class FunctorPointer;
    210     class IOConsole;
    211     class IRC;
    212     class Shell;
    213     class ShellListener;
    214     class TclBind;
    215     struct TclInterpreterBundle;
    216     template <class T>
    217     class TclThreadList;
    218     class TclThreadManager;
    219 
    220     // Input
    221     class BaseCommand;
    222     class BufferedParamCommand;
    223     class Button;
    224     class HalfAxis;
    225     class InputBuffer;
    226     class InputDevice;
    227     template <class Traits>
    228     class InputDeviceTemplated;
    229     class InputHandler;
    230     class InputManager;
    231     class InputState;
    232     struct InputStatePriority;
    233     class JoyStickQuantityListener;
    234     class JoyStick;
    235     class KeyBinder;
    236     class KeyBinderManager;
    237     class Keyboard;
    238     class KeyDetector;
    239     class KeyEvent;
    240     class Mouse;
    241     class ParamCommand;
    242     class SimpleCommand;
    243 }
    244 
    245 #include "command/FunctorPtr.h"
    246 #include "command/ExecutorPtr.h"
    247 
    248 // CppTcl
    249 namespace Tcl
    250 {
    251     class interpreter;
    252     class object;
    253 }
    254 
    255 // Boost
    256 namespace boost
    257 {
    258 #if (BOOST_VERSION < 104400)
    259     namespace filesystem
    260     {
    261         struct path_traits;
    262         template <class String, class Traits> class basic_path;
    263         typedef basic_path<std::string, path_traits> path;
    264     }
    265 #else
    266     namespace filesystem2
    267     {
    268         struct path_traits;
    269         template <class String, class Traits> class basic_path;
    270         typedef basic_path<std::string, path_traits> path;
    271     }
    272     namespace filesystem
    273     {
    274         using filesystem2::basic_path;
    275         using filesystem2::path_traits;
    276         using filesystem2::path;
    277     }
    278 #endif
    279     class thread;
    280     class mutex;
    281     class shared_mutex;
    282     class condition_variable;
    283 }
    284 
    285 // Ogre
    286 namespace Ogre
    287 {
    288     class DataStream;
    289     template <class T> class SharedPtr;
    290     typedef SharedPtr<DataStream> DataStreamPtr;
    291 }
    292 namespace orxonox
    293 {
    294     // Import the Ogre::DataStream
    295     using Ogre::DataStream;
    296     using Ogre::DataStreamPtr;
    297 }
    298 
    299 // CEGUI
    300 namespace CEGUI
    301 {
    302     class DefaultLogger;
    303     class Logger;
    304     class LuaScriptModule;
    305 
    306     class OgreCEGUIRenderer;
    307     class OgreCEGUIResourceProvider;
    308     class OgreCEGUITexture;
    309 }
    310 
    311 // Lua
    312 struct lua_State;
    313 
    314 // TinyXML and TinyXML++
    315 class TiXmlString;
    316 class TiXmlOutStream;
    317 class TiXmlNode;
    318 class TiXmlHandle;
    319 class TiXmlDocument;
    320 class TiXmlElement;
    321 class TiXmlComment;
    322 class TiXmlUnknown;
    323 class TiXmlAttribute;
    324 class TiXmlText;
    325 class TiXmlDeclaration;
    326 class TiXmlParsingData;
    327 namespace ticpp
    328 {
    329     class Document;
    330     class Element;
    331     class Declaration;
    332     class StylesheetReference;
    333     class Text;
    334     class Comment;
    335     class Attribute;
    336 }
    337 namespace orxonox
    338 {
    339     using ticpp::Element;
    34077}
    34178
  • sandbox_qt/src/libraries/core/Game.cc

    r7284 r7421  
    3636
    3737#include <exception>
    38 #include <boost/weak_ptr.hpp>
    39 #include <loki/ScopeGuard.h>
    4038
    41 #include "util/Clock.h"
    4239#include "util/Debug.h"
    4340#include "util/Exception.h"
    4441#include "util/Sleep.h"
    45 #include "util/SubString.h"
    46 #include "CommandLineParser.h"
    4742#include "Core.h"
    48 #include "CoreIncludes.h"
    49 #include "ConfigValueIncludes.h"
    50 #include "GameMode.h"
    51 #include "GameState.h"
    52 #include "GUIManager.h"
    53 #include "command/ConsoleCommand.h"
    5443
    5544namespace orxonox
    5645{
    57     static void stop_game()
    58         { Game::getInstance().stop(); }
    59     SetConsoleCommand("exit", &stop_game);
    60     static void printFPS()
    61         { COUT(0) << Game::getInstance().getAvgFPS() << std::endl; }
    62     SetConsoleCommand("printFPS", &printFPS);
    63     static void printTickTime()
    64         { COUT(0) << Game::getInstance().getAvgTickTime() << std::endl; }
    65     SetConsoleCommand("printTickTime", &printTickTime);
    66 
    67     std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
    6846    Game* Game::singletonPtr_s = 0;
    6947
    70     //! Represents one node of the game state tree.
    71     struct GameStateTreeNode
    72     {
    73         std::string name_;
    74         weak_ptr<GameStateTreeNode> parent_;
    75         std::vector<shared_ptr<GameStateTreeNode> > children_;
    76     };
    77 
    7848    Game::Game(const std::string& cmdLine)
    79         // Destroy factories before the Core!
    80         : gsFactoryDestroyer_(Game::GameStateFactory::getFactories(), &std::map<std::string, shared_ptr<GameStateFactory> >::clear)
    8149    {
    8250        this->bAbort_ = false;
    83         bChangingState_ = false;
    84 
    85 #ifdef ORXONOX_PLATFORM_WINDOWS
    86         minimumSleepTime_ = 1000/*us*/;
    87 #else
    88         minimumSleepTime_ = 0/*us*/;
    89 #endif
    90 
    91         // reset statistics
    92         this->statisticsStartTime_ = 0;
    93         this->statisticsTickTimes_.clear();
    94         this->periodTickTime_ = 0;
    95         this->periodTime_ = 0;
    96         this->avgFPS_ = 0.0f;
    97         this->avgTickTime_ = 0.0f;
    98         this->excessSleepTime_ = 0;
    99 
    100         // Create an empty root state
    101         this->declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
    102 
    103         // Set up a basic clock to keep time
    104         this->gameClock_.reset(new Clock());
    10551
    10652        // Create the Core
    10753        this->core_.reset(new Core(cmdLine));
    108 
    109         // Do this after the Core creation!
    110         ClassIdentifier<Game>::getIdentifier("Game")->initialiseObject(this, "Game", true);
    111         this->setConfigValues();
    112 
    113         // After the core has been created, we can safely instantiate the GameStates that don't require graphics
    114         for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
    115             it != gameStateDeclarations_s.end(); ++it)
    116         {
    117             if (!it->second.bGraphicsMode)
    118                 constructedStates_[it->second.stateName] = GameStateFactory::fabricate(it->second);
    119         }
    120 
    121         // The empty root state is ALWAYS loaded!
    122         this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
    123         this->rootStateNode_->name_ = "emptyRootGameState";
    124         this->loadedTopStateNode_ = this->rootStateNode_;
    125         this->loadedStates_.push_back(this->getState(rootStateNode_->name_));
    12654    }
    12755
    12856    /**
    12957    @brief
    130         All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
     58        All destruction code is handled by QScopedPointers.
    13159    */
    13260    Game::~Game()
    13361    {
    134         // Remove us from the object lists again to avoid problems when destroying them
    135         this->unregisterObject();
    13662    }
    13763
    13864    void Game::setConfigValues()
    13965    {
     66        /*
    14067        SetConfigValue(statisticsRefreshCycle_, 250000)
    14168            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
     
    14471        SetConfigValue(fpsLimit_, 50)
    14572            .description("Sets the desired frame rate (0 for no limit).");
     73        */
    14674    }
    14775
     
    14977    @brief
    15078        Main loop of the orxonox game.
    151     @note
    152         We use the Ogre::Timer to measure time since it uses the most precise
    153         method an any platform (however the windows timer lacks time when under
    154         heavy kernel load!).
    15579    */
    15680    void Game::run()
    15781    {
    158         if (this->requestedStateNodes_.empty())
    159             COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl;
    160 
    161         // START GAME
    162         // first delta time should be about 0 seconds
    163         this->gameClock_->capture();
    164         // A first item is required for the fps limiter
    165         StatisticsTickInfo tickInfo = {0, 0};
    166         statisticsTickTimes_.push_back(tickInfo);
    167         while (!this->bAbort_ && (!this->loadedStates_.empty() || this->requestedStateNodes_.size() > 0))
     82        while (!this->bAbort_)
    16883        {
    169             // Generate the dt
    170             this->gameClock_->capture();
    171 
    172             // Statistics init
    173             StatisticsTickInfo tickInfo = {gameClock_->getMicroseconds(), 0};
    174             statisticsTickTimes_.push_back(tickInfo);
    175             this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
    176 
    177             // Update the GameState stack if required
    178             this->updateGameStateStack();
    179 
    180             // Core preUpdate
    18184            try
    182                 { this->core_->preUpdate(*this->gameClock_); }
    183             catch (...)
    184             {
    185                 COUT(0) << "An exception occurred in the Core preUpdate: " << Exception::handleMessage() << std::endl;
    186                 COUT(0) << "This should really never happen! Closing the program." << std::endl;
    187                 this->stop();
    188                 break;
    189             }
    190 
    191             // Update the GameStates bottom up in the stack
    192             this->updateGameStates();
    193 
    194             // Core postUpdate
    195             try
    196                 { this->core_->postUpdate(*this->gameClock_); }
     85                { this->core_->update(); }
    19786            catch (...)
    19887            {
     
    20291                break;
    20392            }
    204 
    205             // Evaluate statistics
    206             this->updateStatistics();
    207 
    208             // Limit frame rate
    209             this->updateFPSLimiter();
    21093        }
    211 
    212         // UNLOAD all remaining states
    213         while (this->loadedStates_.size() > 1)
    214             this->unloadState(this->loadedStates_.back()->getName());
    215         this->loadedTopStateNode_ = this->rootStateNode_;
    216         this->requestedStateNodes_.clear();
    217     }
    218 
    219     void Game::updateGameStateStack()
    220     {
    221         while (this->requestedStateNodes_.size() > 0)
    222         {
    223             shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
    224             assert(this->loadedTopStateNode_);
    225             if (!this->loadedTopStateNode_->parent_.expired() && requestedStateNode == this->loadedTopStateNode_->parent_.lock())
    226                 this->unloadState(loadedTopStateNode_->name_);
    227             else // has to be child
    228             {
    229                 try
    230                 {
    231                     this->loadState(requestedStateNode->name_);
    232                 }
    233                 catch (...)
    234                 {
    235                     COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << Exception::handleMessage() << std::endl;
    236                     // All scheduled operations have now been rendered inert --> flush them and issue a warning
    237                     if (this->requestedStateNodes_.size() > 1)
    238                         COUT(4) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
    239                     this->requestedStateNodes_.clear();
    240                     break;
    241                 }
    242             }
    243             this->loadedTopStateNode_ = requestedStateNode;
    244             this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
    245         }
    246     }
    247 
    248     void Game::updateGameStates()
    249     {
    250         // Note: The first element is the empty root state, which doesn't need ticking
    251         for (GameStateVector::const_iterator it = this->loadedStates_.begin() + 1;
    252             it != this->loadedStates_.end(); ++it)
    253         {
    254             try
    255             {
    256                 // Add tick time for most of the states
    257                 uint64_t timeBeforeTick = 0;
    258                 if ((*it)->getInfo().bIgnoreTickTime)
    259                     timeBeforeTick = this->gameClock_->getRealMicroseconds();
    260                 (*it)->update(*this->gameClock_);
    261                 if ((*it)->getInfo().bIgnoreTickTime)
    262                     this->subtractTickTime(static_cast<int32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
    263             }
    264             catch (...)
    265             {
    266                 COUT(1) << "An exception occurred while updating '" << (*it)->getName() << "': " << Exception::handleMessage() << std::endl;
    267                 COUT(1) << "This should really never happen!" << std::endl;
    268                 COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
    269                 shared_ptr<GameStateTreeNode> current = this->loadedTopStateNode_;
    270                 while (current->name_ != (*it)->getName() && current)
    271                     current = current->parent_.lock();
    272                 if (current && current->parent_.lock())
    273                     this->requestState(current->parent_.lock()->name_);
    274                 else
    275                     this->stop();
    276                 break;
    277             }
    278         }
    279     }
    280 
    281     void Game::updateStatistics()
    282     {
    283         // Add the tick time of this frame (rendering time has already been subtracted)
    284         uint64_t currentTime = gameClock_->getMicroseconds();
    285         uint64_t currentRealTime = gameClock_->getRealMicroseconds();
    286         this->statisticsTickTimes_.back().tickLength += (uint32_t)(currentRealTime - currentTime);
    287         this->periodTickTime_ += (uint32_t)(currentRealTime - currentTime);
    288         if (this->periodTime_ > this->statisticsRefreshCycle_)
    289         {
    290             std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
    291             assert(it != this->statisticsTickTimes_.end());
    292             int64_t lastTime = currentTime - this->statisticsAvgLength_;
    293             if (static_cast<int64_t>(it->tickTime) < lastTime)
    294             {
    295                 do
    296                 {
    297                     assert(this->periodTickTime_ >= it->tickLength);
    298                     this->periodTickTime_ -= it->tickLength;
    299                     ++it;
    300                     assert(it != this->statisticsTickTimes_.end());
    301                 } while (static_cast<int64_t>(it->tickTime) < lastTime);
    302                 this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
    303             }
    304 
    305             uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
    306             // Why minus 1? No idea, but otherwise the fps rate is always (from 10 to 200!) one frame too low
    307             this->avgFPS_ = -1 + static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
    308             this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
    309 
    310             this->periodTime_ -= this->statisticsRefreshCycle_;
    311         }
    312     }
    313 
    314     void Game::updateFPSLimiter()
    315     {
    316         uint64_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / fpsLimit_);
    317         uint64_t currentRealTime = gameClock_->getRealMicroseconds();
    318         while (currentRealTime < nextTime - minimumSleepTime_)
    319         {
    320             usleep((unsigned long)(nextTime - currentRealTime));
    321             currentRealTime = gameClock_->getRealMicroseconds();
    322         }
    323         // Integrate excess to avoid steady state error
    324         excessSleepTime_ = (int)(currentRealTime - nextTime);
    325         // Anti windup
    326         if (excessSleepTime_ > 50000) // 20ms is about the maximum time Windows would sleep for too long
    327             excessSleepTime_ = 50000;
    32894    }
    32995
     
    33298        this->bAbort_ = true;
    33399    }
    334 
    335     void Game::subtractTickTime(int32_t length)
    336     {
    337         assert(!this->statisticsTickTimes_.empty());
    338         this->statisticsTickTimes_.back().tickLength -= length;
    339         this->periodTickTime_ -= length;
    340     }
    341 
    342 
    343     /***** GameState related *****/
    344 
    345     void Game::requestState(const std::string& name)
    346     {
    347         if (!this->checkState(name))
    348         {
    349             COUT(2) << "Warning: GameState named '" << name << "' doesn't exist!" << std::endl;
    350             return;
    351         }
    352 
    353         if (this->bChangingState_)
    354         {
    355             COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
    356             return;
    357         }
    358 
    359         shared_ptr<GameStateTreeNode> lastRequestedNode;
    360         if (this->requestedStateNodes_.empty())
    361             lastRequestedNode = this->loadedTopStateNode_;
    362         else
    363             lastRequestedNode = this->requestedStateNodes_.back();
    364         if (name == lastRequestedNode->name_)
    365         {
    366             COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl;
    367             return;
    368         }
    369 
    370         // Check children first
    371         std::vector<shared_ptr<GameStateTreeNode> > requestedNodes;
    372         for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
    373         {
    374             if (lastRequestedNode->children_[i]->name_ == name)
    375             {
    376                 requestedNodes.push_back(lastRequestedNode->children_[i]);
    377                 break;
    378             }
    379         }
    380 
    381         if (requestedNodes.empty())
    382         {
    383             // Check parent and all its grand parents
    384             shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode;
    385             while (currentNode != NULL)
    386             {
    387                 if (currentNode->name_ == name)
    388                     break;
    389                 currentNode = currentNode->parent_.lock();
    390                 requestedNodes.push_back(currentNode);
    391             }
    392             if (currentNode == NULL)
    393                 requestedNodes.clear();
    394         }
    395 
    396         if (requestedNodes.empty())
    397             COUT(1) << "Error: Requested GameState transition is not allowed. Ignoring." << std::endl;
    398         else
    399             this->requestedStateNodes_.insert(requestedStateNodes_.end(), requestedNodes.begin(), requestedNodes.end());
    400     }
    401 
    402     void Game::requestStates(const std::string& names)
    403     {
    404         SubString tokens(names, ",;", " ");
    405         for (unsigned int i = 0; i < tokens.size(); ++i)
    406             this->requestState(tokens[i]);
    407     }
    408 
    409     void Game::popState()
    410     {
    411         shared_ptr<GameStateTreeNode> lastRequestedNode;
    412         if (this->requestedStateNodes_.empty())
    413             lastRequestedNode = this->loadedTopStateNode_;
    414         else
    415             lastRequestedNode = this->requestedStateNodes_.back();
    416         if (lastRequestedNode != this->rootStateNode_)
    417             this->requestState(lastRequestedNode->parent_.lock()->name_);
    418         else
    419             COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl;
    420     }
    421 
    422     shared_ptr<GameState> Game::getState(const std::string& name)
    423     {
    424         GameStateMap::const_iterator it = constructedStates_.find(name);
    425         if (it != constructedStates_.end())
    426             return it->second;
    427         else
    428         {
    429             std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
    430             if (it != gameStateDeclarations_s.end())
    431                 COUT(1) << "Error: GameState '" << name << "' has not yet been loaded." << std::endl;
    432             else
    433                 COUT(1) << "Error: Could not find GameState '" << name << "'." << std::endl;
    434             return shared_ptr<GameState>();
    435         }
    436     }
    437 
    438     void Game::setStateHierarchy(const std::string& str)
    439     {
    440         // Split string into pieces of the form whitespacesText
    441         std::vector<std::pair<std::string, int> > stateStrings;
    442         size_t pos = 0;
    443         size_t startPos = 0;
    444         while (pos < str.size())
    445         {
    446             int indentation = 0;
    447             while (pos < str.size() && str[pos] == ' ')
    448                 ++indentation, ++pos;
    449             startPos = pos;
    450             while (pos < str.size() && str[pos] != ' ')
    451                 ++pos;
    452             stateStrings.push_back(std::make_pair(str.substr(startPos, pos - startPos), indentation));
    453         }
    454         if (stateStrings.empty())
    455             ThrowException(GameState, "Emtpy GameState hierarchy provided, terminating.");
    456         // Add element with large identation to detect the last with just an iterator
    457         stateStrings.push_back(std::make_pair("", -1));
    458 
    459         // Parse elements recursively
    460         std::vector<std::pair<std::string, int> >::const_iterator begin = stateStrings.begin();
    461         parseStates(begin, this->rootStateNode_);
    462     }
    463 
    464     /*** Internal ***/
    465 
    466     void Game::parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode)
    467     {
    468         SubString tokens(it->first, ",");
    469         std::vector<std::pair<std::string, int> >::const_iterator startIt = it;
    470 
    471         for (unsigned int i = 0; i < tokens.size(); ++i)
    472         {
    473             it = startIt; // Reset iterator to the beginning of the sub tree
    474             if (!this->checkState(tokens[i]))
    475                 ThrowException(GameState, "GameState with name '" << tokens[i] << "' not found!");
    476             if (tokens[i] == this->rootStateNode_->name_)
    477                 ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy...");
    478             shared_ptr<GameStateTreeNode> node(new GameStateTreeNode());
    479             node->name_ = tokens[i];
    480             node->parent_ = currentNode;
    481             currentNode->children_.push_back(node);
    482 
    483             int currentLevel = it->second;
    484             ++it;
    485             while (it->second != -1)
    486             {
    487                 if (it->second <= currentLevel)
    488                     break;
    489                 else if (it->second == currentLevel + 1)
    490                     parseStates(it, node);
    491                 else
    492                     ThrowException(GameState, "Indentation error while parsing the hierarchy.");
    493             }
    494         }
    495     }
    496 
    497     void Game::loadGraphics()
    498     {
    499         if (!GameMode::showsGraphics())
    500         {
    501             core_->loadGraphics();
    502             Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
    503 
    504             // Construct all the GameStates that require graphics
    505             for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
    506                 it != gameStateDeclarations_s.end(); ++it)
    507             {
    508                 if (it->second.bGraphicsMode)
    509                 {
    510                     // Game state loading failure is serious --> don't catch
    511                     shared_ptr<GameState> gameState = GameStateFactory::fabricate(it->second);
    512                     if (!constructedStates_.insert(std::make_pair(
    513                         it->second.stateName, gameState)).second)
    514                         assert(false); // GameState was already created!
    515                 }
    516             }
    517             graphicsUnloader.Dismiss();
    518         }
    519     }
    520 
    521     void Game::unloadGraphics()
    522     {
    523         if (GameMode::showsGraphics())
    524         {
    525             // Destroy all the GameStates that require graphics
    526             for (GameStateMap::iterator it = constructedStates_.begin(); it != constructedStates_.end();)
    527             {
    528                 if (it->second->getInfo().bGraphicsMode)
    529                     constructedStates_.erase(it++);
    530                 else
    531                     ++it;
    532             }
    533 
    534             core_->unloadGraphics();
    535         }
    536     }
    537 
    538     bool Game::checkState(const std::string& name) const
    539     {
    540         std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
    541         if (it == gameStateDeclarations_s.end())
    542             return false;
    543         else
    544             return true;
    545     }
    546 
    547     void Game::loadState(const std::string& name)
    548     {
    549         this->bChangingState_ = true;
    550         LOKI_ON_BLOCK_EXIT_OBJ(*this, &Game::resetChangingState);
    551 
    552         // If state requires graphics, load it
    553         Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
    554         if (gameStateDeclarations_s[name].bGraphicsMode && !GameMode::showsGraphics())
    555             this->loadGraphics();
    556         else
    557             graphicsUnloader.Dismiss();
    558 
    559         shared_ptr<GameState> state = this->getState(name);
    560         state->activateInternal();
    561         if (!this->loadedStates_.empty())
    562             this->loadedStates_.back()->activity_.topState = false;
    563         this->loadedStates_.push_back(state);
    564         state->activity_.topState = true;
    565 
    566         graphicsUnloader.Dismiss();
    567     }
    568 
    569     void Game::unloadState(const std::string& name)
    570     {
    571         this->bChangingState_ = true;
    572         try
    573         {
    574             shared_ptr<GameState> state = this->getState(name);
    575             state->activity_.topState = false;
    576             this->loadedStates_.pop_back();
    577             if (!this->loadedStates_.empty())
    578                 this->loadedStates_.back()->activity_.topState = true;
    579             state->deactivateInternal();
    580         }
    581         catch (...)
    582         {
    583             COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << Exception::handleMessage() << std::endl;
    584             COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
    585         }
    586         // Check if graphics is still required
    587         if (!bAbort_)
    588         {
    589             bool graphicsRequired = false;
    590             for (unsigned i = 0; i < loadedStates_.size(); ++i)
    591                 graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode;
    592             if (!graphicsRequired)
    593                 this->unloadGraphics();
    594         }
    595         this->bChangingState_ = false;
    596     }
    597 
    598     /*static*/ std::map<std::string, shared_ptr<Game::GameStateFactory> >& Game::GameStateFactory::getFactories()
    599     {
    600         static std::map<std::string, shared_ptr<GameStateFactory> > factories;
    601         return factories;
    602     }
    603 
    604     /*static*/ shared_ptr<GameState> Game::GameStateFactory::fabricate(const GameStateInfo& info)
    605     {
    606         std::map<std::string, shared_ptr<Game::GameStateFactory> >::const_iterator it = getFactories().find(info.className);
    607         assert(it != getFactories().end());
    608         return it->second->fabricateInternal(info);
    609     }
    610100}
  • sandbox_qt/src/libraries/core/Game.h

    r7401 r7421  
    3939#include "CorePrereqs.h"
    4040
    41 #include <cassert>
    42 #include <list>
    43 #include <map>
    4441#include <string>
    45 #include <vector>
    46 #include <boost/shared_ptr.hpp>
    47 #include <boost/scoped_ptr.hpp>
    48 #include <boost/preprocessor/cat.hpp>
    49 #include <loki/ScopeGuard.h>
     42#include <QScopedPointer>
     43#include "util/Singleton.h"
    5044
    51 #include "util/Debug.h"
    52 #include "util/Singleton.h"
    53 #include "OrxonoxClass.h"
    54 
    55 /**
    56 @brief
    57     Adds a new GameState to the Game. The second parameter is the name as string
    58     and every following paramter is a constructor argument (which is usually non existent)
    59 */
    60 #define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
    61     static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
    62 // tolua_begin
    6345namespace orxonox
    6446{
    65 // tolua_end
    66 
    67     //! Helper object required before GameStates are being constructed
    68     struct GameStateInfo
    69     {
    70         std::string stateName;
    71         std::string className;
    72         bool bIgnoreTickTime;
    73         bool bGraphicsMode;
    74     };
    75 
    7647    /**
    7748    @brief
     
    8051        You should only create this singleton once because it owns the Core class! (see remark there)
    8152    */
    82 // tolua_begin
    83     class _CoreExport Game
    84 // tolua_end
    85         : public Singleton<Game>, public OrxonoxClass
    86     { // tolua_export
     53    class _CoreExport Game : public Singleton<Game>
     54    {
    8755        friend class Singleton<Game>;
    88         typedef std::vector<shared_ptr<GameState> > GameStateVector;
    89         typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
    90         typedef shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
    9156
    9257    public:
     
    9661        void setConfigValues();
    9762
    98         void setStateHierarchy(const std::string& str);
    99         shared_ptr<GameState> getState(const std::string& name);
    100 
    10163        void run();
    10264        void stop();
    10365
    104         static Game& getInstance(){ return Singleton<Game>::getInstance(); } // tolua_export
    105 
    106         void requestState(const std::string& name); //tolua_export
    107         void requestStates(const std::string& names); //tolua_export
    108         void popState(); //tolua_export
    109 
    110         const Clock& getGameClock() { return *this->gameClock_; }
    111 
    112         float getAvgTickTime() { return this->avgTickTime_; }
    113         float getAvgFPS()      { return this->avgFPS_; }
    114 
    115         void subtractTickTime(int32_t length);
    116 
    117         template <class T>
    118         static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
    119 
    12066    private:
    121         class _CoreExport GameStateFactory
    122         {
    123         public:
    124             virtual ~GameStateFactory() { }
    125             static shared_ptr<GameState> fabricate(const GameStateInfo& info);
    126             template <class T>
    127             static void createFactory(const std::string& className)
    128                 { getFactories()[className].reset(new TemplateGameStateFactory<T>()); }
    129 
    130             virtual shared_ptr<GameState> fabricateInternal(const GameStateInfo& info) = 0;
    131             static std::map<std::string, shared_ptr<GameStateFactory> >& getFactories();
    132         };
    133         template <class T>
    134         class TemplateGameStateFactory : public GameStateFactory
    135         {
    136         public:
    137             shared_ptr<GameState> fabricateInternal(const GameStateInfo& info)
    138                 { return shared_ptr<GameState>(new T(info)); }
    139         };
    140         // For the factory destruction
    141         typedef Loki::ObjScopeGuardImpl0<std::map<std::string, shared_ptr<GameStateFactory> >, void (std::map<std::string, shared_ptr<GameStateFactory> >::*)()> ObjScopeGuard;
    142 
    143         struct StatisticsTickInfo
    144         {
    145             uint64_t    tickTime;
    146             uint32_t    tickLength;
    147         };
    148 
    14967        Game(Game&); // don't mess with singletons
    15068
    151         void loadGraphics();
    152         void unloadGraphics();
    153 
    154         void parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode);
    155         bool checkState(const std::string& name) const;
    156         void loadState(const std::string& name);
    157         void unloadState(const std::string& name);
    158 
    159         // Main loop structuring
    160         void updateGameStateStack();
    161         void updateGameStates();
    162         void updateStatistics();
    163         void updateFPSLimiter();
    164 
    165         // ScopeGuard helper function
    166         void resetChangingState() { this->bChangingState_ = false; }
    167 
    168         scoped_ptr<Clock>                  gameClock_;
    169         scoped_ptr<Core>                   core_;
    170         ObjScopeGuard                      gsFactoryDestroyer_;
    171 
    172         GameStateMap                       constructedStates_;
    173         GameStateVector                    loadedStates_;
    174         GameStateTreeNodePtr               rootStateNode_;
    175         GameStateTreeNodePtr               loadedTopStateNode_;
    176         std::vector<GameStateTreeNodePtr>  requestedStateNodes_;
    177 
    178         bool                               bChangingState_;
     69        QScopedPointer<Core>               core_;
    17970        bool                               bAbort_;
    18071
    181         // variables for time statistics
    182         uint64_t                           statisticsStartTime_;
    183         std::list<StatisticsTickInfo>      statisticsTickTimes_;
    184         uint32_t                           periodTime_;
    185         uint32_t                           periodTickTime_;
    186         float                              avgFPS_;
    187         float                              avgTickTime_;
    188         int                                excessSleepTime_;
    189         unsigned int                       minimumSleepTime_;
    190 
    191         // config values
    192         unsigned int                       statisticsRefreshCycle_;
    193         unsigned int                       statisticsAvgLength_;
    194         unsigned int                       fpsLimit_;
    195 
    196         static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
    19772        static Game* singletonPtr_s;        //!< Pointer to the Singleton
    198     }; //tolua_export
    199 
    200     template <class T>
    201     /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
    202     {
    203         std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
    204         if (it == gameStateDeclarations_s.end())
    205         {
    206             GameStateInfo& info = gameStateDeclarations_s[stateName];
    207             info.stateName = stateName;
    208             info.className = className;
    209             info.bIgnoreTickTime = bIgnoreTickTime;
    210             info.bGraphicsMode = bGraphicsMode;
    211         }
    212         else
    213         {
    214             COUT(0) << "Error: Cannot declare two GameStates with the same name." << std::endl;
    215             COUT(0) << "       Ignoring second one ('" << stateName << "')." << std::endl;
    216         }
    217 
    218         // Create a factory to delay GameState creation
    219         GameStateFactory::createFactory<T>(className);
    220 
    221         // just a required dummy return value
    222         return true;
    223     }
    224 } //tolua_export
     73    };
     74}
    22575
    22676#endif /* _Game_H__ */
  • sandbox_qt/src/libraries/core/PathConfig.cc

    r6417 r7421  
    3333#include <cstdio>
    3434#include <vector>
    35 #include <boost/version.hpp>
    36 #include <boost/filesystem.hpp>
    3735
    3836#ifdef ORXONOX_PLATFORM_WINDOWS
     
    5452#include "util/Debug.h"
    5553#include "util/Exception.h"
    56 #include "CommandLineParser.h"
    57 
    58 // Boost 1.36 has some issues with deprecated functions that have been omitted
    59 #if (BOOST_VERSION == 103600)
    60 #  define BOOST_LEAF_FUNCTION filename
    61 #else
    62 #  define BOOST_LEAF_FUNCTION leaf
    63 #endif
    6454
    6555namespace orxonox
    6656{
    67     namespace bf = boost::filesystem;
    68 
    6957    //! Static pointer to the singleton
    7058    PathConfig* PathConfig::singletonPtr_s  = 0;
    7159
    72     SetCommandLineArgument(externalDataPath, "").information("Path to the external data files");
    73     SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files");
    74 
    7560    PathConfig::PathConfig()
    76         : rootPath_(*(new bf::path()))
    77         , executablePath_(*(new bf::path()))
    78         , modulePath_(*(new bf::path()))
    79         , dataPath_(*(new bf::path()))
    80         , externalDataPath_(*(new bf::path()))
    81         , configPath_(*(new bf::path()))
    82         , logPath_(*(new bf::path()))
    83         , bDevRun_(false)
    8461    {
    8562        //////////////////////////
     
    125102#endif
    126103
    127         executablePath_ = bf::path(buffer);
     104        executablePath_ = QDir(buffer);
    128105#ifndef ORXONOX_PLATFORM_APPLE
    129         executablePath_ = executablePath_.branch_path(); // remove executable name
    130 #endif
    131 
    132         /////////////////////
    133         // SET MODULE PATH //
    134         /////////////////////
    135 
    136         if (bf::exists(executablePath_ / "orxonox_dev_build.keep_me"))
     106        executablePath_.cdUp(); // remove executable name
     107#endif
     108
     109        if (executablePath_.exists("orxonox_dev_build.keep_me"))
    137110        {
    138111            COUT(1) << "Running from the build tree." << std::endl;
    139112            PathConfig::bDevRun_ = true;
    140             modulePath_ = specialConfig::moduleDevDirectory;
    141113        }
    142114        else
     
    146118
    147119            // Also set the root path
    148             bf::path relativeExecutablePath(specialConfig::defaultRuntimePath);
     120            QDir relativeExecutablePath(specialConfig::defaultRuntimePath);
    149121            rootPath_ = executablePath_;
    150             while (!bf::equivalent(rootPath_ / relativeExecutablePath, executablePath_) && !rootPath_.empty())
    151                 rootPath_ = rootPath_.branch_path();
    152             if (rootPath_.empty())
    153                 ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
    154 
    155             // Module path is fixed as well
    156             modulePath_ = rootPath_ / specialConfig::defaultModulePath;
     122            while (rootPath_ / relativeExecutablePath != executablePath_)
     123            {
     124                if (!rootPath_.cdUp())
     125                    ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
     126            }
    157127
    158128#else
    159129
    160130            // There is no root path, so don't set it at all
    161             // Module path is fixed as well
    162             modulePath_ = specialConfig::moduleInstallDirectory;
    163131
    164132#endif
     
    168136    PathConfig::~PathConfig()
    169137    {
    170         delete &rootPath_;
    171         delete &executablePath_;
    172         delete &modulePath_;
    173         delete &dataPath_;
    174         delete &externalDataPath_;
    175         delete &configPath_;
    176         delete &logPath_;
    177138    }
    178139
     
    184145            configPath_       = specialConfig::configDevDirectory;
    185146            logPath_          = specialConfig::logDevDirectory;
    186 
    187             // Check for data path override by the command line
    188             if (!CommandLineParser::getArgument("externalDataPath")->hasDefaultValue())
    189                 externalDataPath_ = CommandLineParser::getValue("externalDataPath").getString();
    190             else
    191                 externalDataPath_ = specialConfig::externalDataDevDirectory;
    192147        }
    193148        else
     
    213168            if (userDataPathPtr == NULL)
    214169                ThrowException(General, "Could not retrieve user data path.");
    215             bf::path userDataPath(userDataPathPtr);
     170            QDir userDataPath(userDataPathPtr);
    216171            userDataPath /= ".orxonox";
    217172
     
    223178        }
    224179
    225         // Option to put all the config and log files in a separate folder
    226         if (!CommandLineParser::getArgument("writingPathSuffix")->hasDefaultValue())
    227         {
    228             const std::string& directory(CommandLineParser::getValue("writingPathSuffix").getString());
    229             configPath_ = configPath_ / directory;
    230             logPath_    = logPath_    / directory;
    231         }
    232 
    233180        // Create directories to avoid problems when opening files in non existent folders.
    234         std::vector<std::pair<bf::path, std::string> > directories;
    235         directories.push_back(std::make_pair(bf::path(configPath_), "config"));
    236         directories.push_back(std::make_pair(bf::path(logPath_), "log"));
    237 
    238         for (std::vector<std::pair<bf::path, std::string> >::iterator it = directories.begin();
     181        std::vector<std::pair<QDir, std::string> > directories;
     182        directories.push_back(std::make_pair(QDir(configPath_), "config"));
     183        directories.push_back(std::make_pair(QDir(logPath_), "log"));
     184
     185        for (std::vector<std::pair<QDir, std::string> >::iterator it = directories.begin();
    239186            it != directories.end(); ++it)
    240187        {
    241             if (bf::exists(it->first) && !bf::is_directory(it->first))
     188            if (!it->first.exists())
    242189            {
    243                 ThrowException(General, std::string("The ") + it->second + " directory has been preoccupied by a file! \
    244                                          Please remove " + it->first.string());
    245             }
    246             if (bf::create_directories(it->first)) // function may not return true at all (bug?)
    247             {
     190                if (!it->first.mkpath("."))
     191                    ThrowException(General, std::string("The ") + it->second + " directory could not be created.");
    248192                COUT(4) << "Created " << it->second << " directory" << std::endl;
    249193            }
     
    251195    }
    252196
    253     std::vector<std::string> PathConfig::getModulePaths()
    254     {
    255         std::vector<std::string> modulePaths;
    256 
    257         // We search for helper files with the following extension
    258         const std::string& moduleextension = specialConfig::moduleExtension;
    259         size_t moduleextensionlength = moduleextension.size();
    260 
    261         // Add that path to the PATH variable in case a module depends on another one
    262         std::string pathVariable(getenv("PATH"));
    263         putenv(const_cast<char*>(("PATH=" + pathVariable + ';' + modulePath_.string()).c_str()));
    264 
    265         // Make sure the path exists, otherwise don't load modules
    266         if (!boost::filesystem::exists(modulePath_))
    267             return modulePaths;
    268 
    269         boost::filesystem::directory_iterator file(modulePath_);
    270         boost::filesystem::directory_iterator end;
    271 
    272         // Iterate through all files
    273         while (file != end)
    274         {
    275             const std::string& filename = file->BOOST_LEAF_FUNCTION();
    276 
    277             // Check if the file ends with the exension in question
    278             if (filename.size() > moduleextensionlength)
    279             {
    280                 if (filename.substr(filename.size() - moduleextensionlength) == moduleextension)
    281                 {
    282                     // We've found a helper file
    283                     const std::string& library = filename.substr(0, filename.size() - moduleextensionlength);
    284                     modulePaths.push_back((modulePath_ / library).file_string());
    285                 }
    286             }
    287             ++file;
    288         }
    289 
    290         return modulePaths;
    291     }
    292 
    293197    /*static*/ std::string PathConfig::getRootPathString()
    294198    {
    295         return getInstance().rootPath_.string() + '/';
     199        return getInstance().rootPath_.path().toStdString() + '/';
    296200    }
    297201
    298202    /*static*/ std::string PathConfig::getExecutablePathString()
    299203    {
    300         return getInstance().executablePath_.string() + '/';
     204        return getInstance().executablePath_.path().toStdString() + '/';
    301205    }
    302206
    303207    /*static*/ std::string PathConfig::getDataPathString()
    304208    {
    305         return getInstance().dataPath_.string() + '/';
    306     }
    307 
    308     /*static*/ std::string PathConfig::getExternalDataPathString()
    309     {
    310         return getInstance().externalDataPath_.string() + '/';
     209        return getInstance().dataPath_.path().toStdString() + '/';
    311210    }
    312211
    313212    /*static*/ std::string PathConfig::getConfigPathString()
    314213    {
    315         return getInstance().configPath_.string() + '/';
     214        return getInstance().configPath_.path().toStdString() + '/';
    316215    }
    317216
    318217    /*static*/ std::string PathConfig::getLogPathString()
    319218    {
    320         return getInstance().logPath_.string() + '/';
    321     }
    322 
    323     /*static*/ std::string PathConfig::getModulePathString()
    324     {
    325         return getInstance().modulePath_.string() + '/';
     219        return getInstance().logPath_.path().toStdString() + '/';
    326220    }
    327221}
  • sandbox_qt/src/libraries/core/PathConfig.h

    r7401 r7421  
    3939#include <string>
    4040#include <vector>
     41#include <QDir>
    4142#include "util/Singleton.h"
    4243
    43 //tolua_begin
    4444namespace orxonox
    4545{
    46 //tolua_end
    4746    /**
    4847    @brief
    4948        The PathConfig class is a singleton used to configure different paths.
    5049    @details
    51         The class provides information about the data, config, log, executable,
    52         root and module path.
     50        The class provides information about the data, config, log, executable
     51        and root path.
    5352        It determines those by the use of platform specific functions.
    5453    @remarks
    5554        Not all paths are always available:
    5655        - root only when installed copyable
    57         - externalData only for development builds in the build tree
    5856    */
    59     class _CoreExport PathConfig //tolua_export
    60         : public Singleton<PathConfig>
    61     { //tolua_export
     57    class _CoreExport PathConfig : public Singleton<PathConfig>
     58    {
    6259        friend class Singleton<PathConfig>;
    6360        friend class Core;
     
    6663            /**
    6764            @brief
    68                 Retrievs the executable path and sets all hard coded fixed paths (currently only the module path)
     65                Retrieves the executable path and sets all hard coded fixed paths (currently only the module path)
    6966                Also checks for "orxonox_dev_build.keep_me" in the executable diretory.
    7067                If found it means that this is not an installed run, hence we
     
    7673            ~PathConfig();
    7774
    78             //! Returns the path to the root folder as boost::filesystem::path
    79             static const boost::filesystem::path& getRootPath()
     75            //! Returns the path to the root folder as QDir
     76            static const QDir& getRootPath()
    8077                { return getInstance().rootPath_; }
    81             //! Returns the path to the executable folder as boost::filesystem::path
    82             static const boost::filesystem::path& getExecutablePath()
     78            //! Returns the path to the executable folder as QDir
     79            static const QDir& getExecutablePath()
    8380                { return getInstance().executablePath_; }
    84             //! Returns the path to the data files as boost::filesystem::path
    85             static const boost::filesystem::path& getDataPath()
     81            //! Returns the path to the data files as QDir
     82            static const QDir& getDataPath()
    8683                { return getInstance().dataPath_; }
    87             //! Returns the path to the external data files as boost::filesystem::path
    88             static const boost::filesystem::path& getExternalDataPath()
    89                 { return getInstance().externalDataPath_; }
    90             //! Returns the path to the config files as boost::filesystem::path
    91             static const boost::filesystem::path& getConfigPath()
     84            //! Returns the path to the config files as QDir
     85            static const QDir& getConfigPath()
    9286                { return getInstance().configPath_; }
    93             //! Returns the path to the log files as boost::filesystem::path
    94             static const boost::filesystem::path& getLogPath()
     87            //! Returns the path to the log files as QDir
     88            static const QDir& getLogPath()
    9589                { return getInstance().logPath_; }
    96             //! Returns the path to the modules as boost::filesystem::path
    97             static const boost::filesystem::path& getModulePath()
    98                 { return getInstance().modulePath_; }
    9990
    10091            //! Returns the path to the root folder as std::string
     
    10495            //! Returns the path to the data files as std::string
    10596            static std::string getDataPathString();
    106             //! Returns the path to the external data files as std::string
    107             static std::string getExternalDataPathString();
    10897            //! Returns the path to the config files as std::string
    10998            static std::string getConfigPathString(); //tolua_export
    11099            //! Returns the path to the log files as std::string
    111100            static std::string getLogPathString();
    112             //! Returns the path to the modules as std::string
    113             static std::string getModulePathString();
    114101
    115102            //! Return trrue for runs in the build directory (not installed)
     
    126113            */
    127114            void setConfigurablePaths();
    128             //! Returns a list with all modules declared by a *.module file in the module folder.
    129             std::vector<std::string> getModulePaths();
    130115
    131116            //! Path to the parent directory of the ones above if program was installed with relativ paths
    132             boost::filesystem::path& rootPath_;
    133             boost::filesystem::path& executablePath_;        //!< Path to the executable
    134             boost::filesystem::path& modulePath_;            //!< Path to the modules
    135             boost::filesystem::path& dataPath_;              //!< Path to the data files folder
    136             boost::filesystem::path& externalDataPath_;      //!< Path to the external data files folder
    137             boost::filesystem::path& configPath_;            //!< Path to the config files folder
    138             boost::filesystem::path& logPath_;               //!< Path to the log files folder
     117            QDir               rootPath_;
     118            QDir               executablePath_;        //!< Path to the executable
     119            QDir               dataPath_;              //!< Path to the data files folder
     120            QDir               configPath_;            //!< Path to the config files folder
     121            QDir               logPath_;               //!< Path to the log files folder
    139122
    140             bool                     bDevRun_;               //!< True for runs in the build directory (not installed)
     123            bool               bDevRun_;               //!< True for runs in the build directory (not installed)
    141124            static PathConfig* singletonPtr_s;
    142125    }; //tolua_export
Note: See TracChangeset for help on using the changeset viewer.