Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/resource/src/core/Game.h @ 3356

Last change on this file since 3356 was 3356, checked in by rgrieder, 15 years ago

GameStates requiring graphics (Level is not one of them because it uses showsGraphics() to distinguish) are now only constructed when basic graphic support is given (GraphicsManager, InputManager and GUIManager loaded).

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
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
38#include "CorePrereqs.h"
39
40#include <cassert>
41#include <list>
42#include <map>
43#include <string>
44#include <vector>
45#include <boost/shared_ptr.hpp>
46#include <boost/preprocessor/cat.hpp>
47
48#include "util/Debug.h"
49
50/**
51@def
52    Adds a new GameState to the Game. The second parameter is the name as string
53    and every following paramter is a constructor argument (which is usually non existent)
54*/
55#define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
56    static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
57
58namespace orxonox
59{
60    class GameConfiguration;
61
62    //! Helper object required before GameStates are being constructed
63    struct GameStateInfo
64    {
65        std::string stateName;
66        std::string className;
67        bool bIgnoreTickTime;
68        bool bGraphicsMode;
69    };
70
71    /**
72    @brief
73        Main class responsible for running the game.
74    */
75    class _CoreExport Game
76    {
77        typedef boost::shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
78    public:
79        Game(const std::string& cmdLine);
80        ~Game();
81
82        void setStateHierarchy(const std::string& str);
83        GameState* getState(const std::string& name);
84
85        void run();
86        void stop();
87
88        void requestState(const std::string& name);
89        void requestStates(const std::string& names);
90        void popState();
91
92        const Clock& getGameClock() { return *this->gameClock_; }
93
94        float getAvgTickTime() { return this->avgTickTime_; }
95        float getAvgFPS()      { return this->avgFPS_; }
96
97        void subtractTickTime(int32_t length);
98
99        template <class T>
100        static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
101        static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; }
102
103    private:
104        class _CoreExport GameStateFactory
105        {
106        public:
107            virtual ~GameStateFactory() { }
108            static GameState* fabricate(const GameStateInfo& info);
109            template <class T>
110            static void createFactory(const std::string& className)
111                { factories_s[className] = new TemplateGameStateFactory<T>(); }
112            static void destroyFactories();
113        private:
114            virtual GameState* fabricateInternal(const GameStateInfo& info) = 0;
115            static std::map<std::string, GameStateFactory*> factories_s;
116        };
117        template <class T>
118        class TemplateGameStateFactory : public GameStateFactory
119        {
120        public:
121            GameState* fabricateInternal(const GameStateInfo& info)
122                { return new T(info); }
123        };
124
125        struct StatisticsTickInfo
126        {
127            uint64_t    tickTime;
128            uint32_t    tickLength;
129        };
130
131        Game(Game&); // don't mess with singletons
132
133        void loadGraphics();
134        void unloadGraphics();
135
136        bool checkState(const std::string& name) const;
137        void loadState(const std::string& name);
138        void unloadState(const std::string& name);
139
140        // Main loop structuring
141        void updateGameStateStack();
142        void updateGameStates();
143        void updateStatistics();
144        void updateFPSLimiter();
145
146        std::map<std::string, GameState*>  constructedStates_;
147        std::vector<GameState*>            loadedStates_;
148        GameStateTreeNodePtr               rootStateNode_;
149        GameStateTreeNodePtr               loadedTopStateNode_;
150        std::vector<GameStateTreeNodePtr > requestedStateNodes_;
151
152        Core*                              core_;
153        Clock*                             gameClock_;
154        GameConfiguration*                 configuration_;
155
156        bool                               bChangingState_;
157        bool                               bAbort_;
158
159        // variables for time statistics
160        uint64_t                           statisticsStartTime_;
161        std::list<StatisticsTickInfo>      statisticsTickTimes_;
162        uint32_t                           periodTime_;
163        uint32_t                           periodTickTime_;
164        float                              avgFPS_;
165        float                              avgTickTime_;
166        int                                excessSleepTime_;
167        unsigned int                       minimumSleepTime_;
168
169        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
170        static Game* singletonRef_s;        //!< Pointer to the Singleton
171    };
172
173    template <class T>
174    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
175    {
176        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
177        if (it == gameStateDeclarations_s.end())
178        {
179            GameStateInfo& info = gameStateDeclarations_s[stateName];
180            info.stateName = stateName;
181            info.className = className;
182            info.bIgnoreTickTime = bIgnoreTickTime;
183            info.bGraphicsMode = bGraphicsMode;
184        }
185        else
186        {
187            COUT(0) << "Error: Cannot declare two GameStates with the same name." << std::endl;
188            COUT(0) << "       Ignoring second one ('" << stateName << "')." << std::endl;
189        }
190
191        // Create a factory to delay GameState creation
192        GameStateFactory::createFactory<T>(className);
193
194        // just a required dummy return value
195        return true;
196    }
197}
198
199#endif /* _Game_H__ */
Note: See TracBrowser for help on using the repository browser.