Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/core/Game.h @ 10513

Last change on this file since 10513 was 10479, checked in by landauf, 10 years ago

moved config values and all related functions from Game and Core to GameConfig and CoreConfig respectively. this ensures that no framework features are used by Game and Core before Core itself initialized the framework.

  • Property svn:eol-style set to native
File size: 7.7 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@ingroup Management CoreGame
32@brief
33    Declaration of Game Singleton which is responsible for running the game.
34 */
35
36#ifndef _Game_H__
37#define _Game_H__
38
39#include "CorePrereqs.h"
40
41#include <cassert>
42#include <list>
43#include <map>
44#include <string>
45#include <vector>
46#include <boost/shared_ptr.hpp>
47#include <boost/preprocessor/cat.hpp>
48
49#include "util/Output.h"
50#include "util/DestructionHelper.h"
51#include "util/Singleton.h"
52
53/**
54@brief
55    Adds a new GameState to the Game. The second parameter is the name as string
56    and every following parameter is a constructor argument (which is usually non existent)
57*/
58#define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
59    static bool BOOST_PP_CAT(bGameStateDummy_##className, __UNIQUE_NUMBER__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
60// tolua_begin
61namespace orxonox
62{
63// tolua_end
64
65    //! Helper object required before GameStates are being constructed
66    struct GameStateInfo
67    {
68        std::string stateName;
69        std::string className;
70        bool bIgnoreTickTime;
71        bool bGraphicsMode;
72    };
73
74    /**
75    @brief
76        Main class responsible for running the game.
77    @remark
78        You should only create this singleton once because it owns the Core class! (see remark there)
79    */
80// tolua_begin
81    class _CoreExport Game
82// tolua_end
83        : public Singleton<Game>
84    { // tolua_export
85        friend class Singleton<Game>;
86        typedef std::vector<shared_ptr<GameState> > GameStateVector;
87        typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
88        typedef shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
89
90    public:
91        Game(const std::string& cmdLine);
92
93        //! Leave empty and use cleanup() instead
94        ~Game() {}
95        /// Destructor that also executes when object fails to construct
96        void destroy();
97
98        void setStateHierarchy(const std::string& str);
99        shared_ptr<GameState> getState(const std::string& name);
100
101        void run();
102        void stop();
103
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
120    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
141        struct StatisticsTickInfo
142        {
143            uint64_t    tickTime;
144            uint32_t    tickLength;
145        };
146
147        Game(Game&); // don't mess with singletons
148
149        void loadGraphics();
150        void unloadGraphics();
151
152        void parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode);
153        bool checkState(const std::string& name) const;
154        void loadState(const std::string& name);
155        void unloadState(const std::string& name);
156
157        // Main loop structuring
158        void updateGameStateStack();
159        void updateGameStates();
160        void updateStatistics();
161        void updateFPSLimiter();
162
163        // ScopeGuard helper function
164        void resetChangingState() { this->bChangingState_ = false; }
165
166        Clock*                             gameClock_;
167        Core*                              core_;
168
169        GameStateMap                       constructedStates_;
170        GameStateVector                    loadedStates_;
171        GameStateTreeNodePtr               rootStateNode_;
172        GameStateTreeNodePtr               loadedTopStateNode_;
173        std::vector<GameStateTreeNodePtr>  requestedStateNodes_;
174
175        bool                               bChangingState_;
176        bool                               bAbort_;
177
178        // variables for time statistics
179        uint64_t                           statisticsStartTime_;
180        std::list<StatisticsTickInfo>      statisticsTickTimes_;
181        uint32_t                           periodTime_;
182        uint32_t                           periodTickTime_;
183        float                              avgFPS_;
184        float                              avgTickTime_;
185        int                                excessSleepTime_;
186        unsigned int                       minimumSleepTime_;
187
188        /// Helper object that stores the config values
189        GameConfig*                        config_;
190
191        /// Helper object that executes the surrogate destructor destroy()
192        DestructionHelper<Game>            destructionHelper_;
193
194        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
195        static Game* singletonPtr_s;        //!< Pointer to the Singleton
196    }; //tolua_export
197
198    template <class T>
199    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
200    {
201        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
202        if (it == gameStateDeclarations_s.end())
203        {
204            GameStateInfo& info = gameStateDeclarations_s[stateName];
205            info.stateName = stateName;
206            info.className = className;
207            info.bIgnoreTickTime = bIgnoreTickTime;
208            info.bGraphicsMode = bGraphicsMode;
209        }
210        else
211        {
212            orxout(internal_warning) << "Cannot declare two GameStates with the same name." << endl;
213            orxout(internal_warning) << "Ignoring second one ('" << stateName << "')." << endl;
214        }
215
216        // Create a factory to delay GameState creation
217        GameStateFactory::createFactory<T>(className);
218
219        // just a required dummy return value
220        return true;
221    }
222} //tolua_export
223
224#endif /* _Game_H__ */
Note: See TracBrowser for help on using the repository browser.