Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/Game.h @ 7284

Last change on this file since 7284 was 7266, checked in by rgrieder, 14 years ago

Moved Loki library files to separate loki folder in externals.
Also added TypeManip.h (now used in Convert.h) and static_check.h.

  • Property svn:eol-style set to native
File size: 7.8 KB
RevLine 
[2805]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Reto Grieder
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30@file
31@brief
32    Declaration of Game Singleton.
33 */
34
35#ifndef _Game_H__
36#define _Game_H__
37
[2844]38#include "CorePrereqs.h"
[3196]39
[2805]40#include <cassert>
[2817]41#include <list>
[2844]42#include <map>
[3196]43#include <string>
[2844]44#include <vector>
[3196]45#include <boost/shared_ptr.hpp>
[3370]46#include <boost/scoped_ptr.hpp>
[3196]47#include <boost/preprocessor/cat.hpp>
[7266]48#include <loki/ScopeGuard.h>
[3196]49
[3280]50#include "util/Debug.h"
[3370]51#include "util/Singleton.h"
[6746]52#include "OrxonoxClass.h"
[2805]53
[3084]54/**
55@def
56    Adds a new GameState to the Game. The second parameter is the name as string
57    and every following paramter is a constructor argument (which is usually non existent)
58*/
[3280]59#define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
60    static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
[6417]61// tolua_begin
[2805]62namespace orxonox
63{
[6417]64// tolua_end
[3280]65
[3370]66    //! Helper object required before GameStates are being constructed
67    struct GameStateInfo
68    {
69        std::string stateName;
70        std::string className;
71        bool bIgnoreTickTime;
72        bool bGraphicsMode;
73    };
74
[2805]75    /**
76    @brief
77        Main class responsible for running the game.
[3370]78    @remark
79        You should only create this singleton once because it owns the Core class! (see remark there)
[2805]80    */
[6417]81// tolua_begin
82    class _CoreExport Game
83// tolua_end
84        : public Singleton<Game>, public OrxonoxClass
85    { // tolua_export
[3370]86        friend class Singleton<Game>;
87        typedef std::vector<shared_ptr<GameState> > GameStateVector;
88        typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
[5695]89        typedef shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
[5693]90
[2805]91    public:
[3323]92        Game(const std::string& cmdLine);
[2805]93        ~Game();
94
[6417]95        void setConfigValues();
96
[2844]97        void setStateHierarchy(const std::string& str);
[3370]98        shared_ptr<GameState> getState(const std::string& name);
[2844]99
[2805]100        void run();
101        void stop();
102
[6417]103        static Game& getInstance(){ return Singleton<Game>::getInstance(); } // tolua_export
[2844]104
[6417]105        void requestState(const std::string& name); //tolua_export
106        void requestStates(const std::string& names); //tolua_export
107        void popState(); //tolua_export
108
[2846]109        const Clock& getGameClock() { return *this->gameClock_; }
110
[2817]111        float getAvgTickTime() { return this->avgTickTime_; }
112        float getAvgFPS()      { return this->avgFPS_; }
113
[3370]114        void subtractTickTime(int32_t length);
[2817]115
[3280]116        template <class T>
117        static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
[2805]118
119    private:
[3280]120        class _CoreExport GameStateFactory
[2817]121        {
[3280]122        public:
123            virtual ~GameStateFactory() { }
[3370]124            static shared_ptr<GameState> fabricate(const GameStateInfo& info);
[3280]125            template <class T>
126            static void createFactory(const std::string& className)
[5929]127                { getFactories()[className].reset(new TemplateGameStateFactory<T>()); }
[5693]128
[3370]129            virtual shared_ptr<GameState> fabricateInternal(const GameStateInfo& info) = 0;
[5929]130            static std::map<std::string, shared_ptr<GameStateFactory> >& getFactories();
[3280]131        };
132        template <class T>
133        class TemplateGameStateFactory : public GameStateFactory
134        {
135        public:
[3370]136            shared_ptr<GameState> fabricateInternal(const GameStateInfo& info)
137                { return shared_ptr<GameState>(new T(info)); }
[3280]138        };
[5693]139        // For the factory destruction
140        typedef Loki::ObjScopeGuardImpl0<std::map<std::string, shared_ptr<GameStateFactory> >, void (std::map<std::string, shared_ptr<GameStateFactory> >::*)()> ObjScopeGuard;
[3280]141
142        struct StatisticsTickInfo
143        {
[2817]144            uint64_t    tickTime;
145            uint32_t    tickLength;
146        };
147
[2805]148        Game(Game&); // don't mess with singletons
149
[3370]150        void loadGraphics();
151        void unloadGraphics();
[2805]152
[5929]153        void parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode);
[3370]154        bool checkState(const std::string& name) const;
155        void loadState(const std::string& name);
156        void unloadState(const std::string& name);
[2805]157
[3370]158        // Main loop structuring
159        void updateGameStateStack();
160        void updateGameStates();
161        void updateStatistics();
162        void updateFPSLimiter();
[2844]163
[3370]164        // ScopeGuard helper function
165        void resetChangingState() { this->bChangingState_ = false; }
[2844]166
[3370]167        scoped_ptr<Clock>                  gameClock_;
168        scoped_ptr<Core>                   core_;
[5693]169        ObjScopeGuard                      gsFactoryDestroyer_;
[3370]170
171        GameStateMap                       constructedStates_;
172        GameStateVector                    loadedStates_;
173        GameStateTreeNodePtr               rootStateNode_;
174        GameStateTreeNodePtr               loadedTopStateNode_;
175        std::vector<GameStateTreeNodePtr>  requestedStateNodes_;
176
177        bool                               bChangingState_;
178        bool                               bAbort_;
179
[2817]180        // variables for time statistics
[3370]181        uint64_t                           statisticsStartTime_;
182        std::list<StatisticsTickInfo>      statisticsTickTimes_;
183        uint32_t                           periodTime_;
184        uint32_t                           periodTickTime_;
185        float                              avgFPS_;
186        float                              avgTickTime_;
187        int                                excessSleepTime_;
188        unsigned int                       minimumSleepTime_;
[2817]189
[6417]190        // config values
191        unsigned int                       statisticsRefreshCycle_;
192        unsigned int                       statisticsAvgLength_;
193        unsigned int                       fpsLimit_;
194
[3280]195        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
[3370]196        static Game* singletonPtr_s;        //!< Pointer to the Singleton
[6417]197    }; //tolua_export
[3280]198
199    template <class T>
200    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
201    {
[3370]202        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
[3280]203        if (it == gameStateDeclarations_s.end())
204        {
[3370]205            GameStateInfo& info = gameStateDeclarations_s[stateName];
[3280]206            info.stateName = stateName;
207            info.className = className;
208            info.bIgnoreTickTime = bIgnoreTickTime;
209            info.bGraphicsMode = bGraphicsMode;
210        }
211        else
212        {
213            COUT(0) << "Error: Cannot declare two GameStates with the same name." << std::endl;
214            COUT(0) << "       Ignoring second one ('" << stateName << "')." << std::endl;
215        }
216
217        // Create a factory to delay GameState creation
218        GameStateFactory::createFactory<T>(className);
219
220        // just a required dummy return value
221        return true;
222    }
[6417]223} //tolua_export
[3280]224
[2805]225#endif /* _Game_H__ */
Note: See TracBrowser for help on using the repository browser.