Changeset 2844 for code/branches/gui/src/core
- Timestamp:
- Mar 25, 2009, 5:23:00 PM (16 years ago)
- Location:
- code/branches/gui/src/core
- Files:
-
- 2 deleted
- 4 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
code/branches/gui/src/core/CMakeLists.txt
r2710 r2844 24 24 Core.cc 25 25 Event.cc 26 Game.cc 26 27 GameState.cc 27 28 Language.cc … … 29 30 ObjectListBase.cc 30 31 OrxonoxClass.cc 31 RootGameState.cc32 32 33 33 # command -
code/branches/gui/src/core/CorePrereqs.h
r2817 r2844 166 166 167 167 // game states 168 class Game; 168 169 class GameState; 169 class RootGameState;170 struct GameStateTreeNode; 170 171 171 172 // input -
code/branches/gui/src/core/Game.cc
r2843 r2844 33 33 */ 34 34 35 #include "OrxonoxStableHeaders.h"36 35 #include "Game.h" 37 36 … … 41 40 #include "util/Debug.h" 42 41 #include "util/Exception.h" 43 #include "core/CommandLine.h" 44 #include "core/ConsoleCommand.h" 45 #include "core/Core.h" 46 #include "core/Identifier.h" 47 #include "core/CoreIncludes.h" 48 #include "core/ConfigValueIncludes.h" 49 50 #include "gamestates/GSRoot.h" 51 #include "gamestates/GSGraphics.h" 52 #include "gamestates/GSStandalone.h" 53 #include "gamestates/GSServer.h" 54 #include "gamestates/GSClient.h" 55 #include "gamestates/GSDedicated.h" 56 #include "gamestates/GSGUI.h" 57 #include "gamestates/GSIOConsole.h" 58 59 /* 60 @brief 61 Main method. Game starts here (except for static initialisations). 62 */ 63 int main(int argc, char** argv) 64 { 65 { 66 orxonox::Game orxonox(argc, argv); 67 orxonox.run(); 68 // objects gets destroyed here! 69 } 70 71 // Clean up class hierarchy stuff (identifiers, xmlport, configvalue, consolecommand) 72 // Needs to be done after Game destructor because of ~OrxonoxClass 73 orxonox::Identifier::destroyAllIdentifiers(); 74 75 return 0; 76 } 42 #include "Clock.h" 43 #include "CommandLine.h" 44 #include "ConsoleCommand.h" 45 #include "Core.h" 46 #include "CoreIncludes.h" 47 #include "ConfigValueIncludes.h" 48 #include "GameState.h" 77 49 78 50 namespace orxonox … … 83 55 } 84 56 57 struct _CoreExport GameStateTreeNode 58 { 59 GameState* state_; 60 GameStateTreeNode* parent_; 61 std::vector<GameStateTreeNode*> children_; 62 }; 63 85 64 SetCommandLineArgument(state, "gui").shortcut("s"); 65 SetCommandLineSwitch(startWithConsole); 86 66 SetConsoleCommandShortcutExternAlias(stop_game, "exit"); 87 67 68 std::map<std::string, GameState*> Game::allStates_s; 88 69 Game* Game::singletonRef_s = 0; 89 70 … … 96 77 assert(singletonRef_s == 0); 97 78 singletonRef_s = this; 79 80 this->rootStateNode_ = 0; 81 this->activeStateNode_ = 0; 98 82 99 83 this->abort_ = false; … … 121 105 // Destroy pretty much everyhting left 122 106 delete this->core_; 107 108 // Delete all GameStates created by the macros 109 for (std::map<std::string, GameState*>::const_iterator it = allStates_s.begin(); it != allStates_s.end(); ++it) 110 delete it->second; 123 111 124 112 assert(singletonRef_s); … … 144 132 void Game::run() 145 133 { 146 // create the gamestates 147 GSRoot root; 148 GSGraphics graphics; 149 GSStandalone standalone; 150 GSServer server; 151 GSClient client; 152 GSDedicated dedicated; 153 GSGUI gui; 154 GSIOConsole ioConsole; 155 156 // make the hierarchy 157 root.addChild(&graphics); 158 graphics.addChild(&standalone); 159 graphics.addChild(&server); 160 graphics.addChild(&client); 161 graphics.addChild(&gui); 162 root.addChild(&ioConsole); 163 root.addChild(&dedicated); 164 165 root.activate(); 166 167 // get initial state from command line 168 root.gotoState(CommandLine::getValue("state")); 134 // </EXPORT THIS> 135 this->setStateHierarchy( 136 "root" 137 " graphics" 138 " gui" 139 " standalone" 140 " level" 141 " server" 142 " level" 143 " client" 144 " level" 145 " dedicated" 146 " level" 147 " ioConsole" 148 ); 149 // </EXPORT THIS> 150 151 152 // Always start with the root state 153 this->requestedStateNodes_.push_back(this->rootStateNode_); 154 this->activeStateNode_ = this->rootStateNode_; 155 this->loadState(this->rootStateNode_->state_); 156 157 // <EXPORT THIS> 158 if (CommandLine::getValue("startWithConsole").getBool()) 159 { 160 // Start the game in the console 161 this->requestState("ioConsole"); 162 } 163 else 164 { 165 // Start in GUI main menu 166 this->requestState("graphics"); 167 this->requestState("gui"); 168 } 169 // </EXPORT THIS> 169 170 170 171 this->gameClock_->capture(); // first delta time should be about 0 seconds 171 while (!this->abort_ )172 while (!this->abort_ && !this->activeStates_.empty()) 172 173 { 173 174 this->gameClock_->capture(); … … 179 180 this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds(); 180 181 181 // UPDATE 182 root.tick(*this->gameClock_); 182 // UPDATE STATE STACK 183 while (this->requestedStateNodes_.size() > 1) 184 { 185 // Note: this->requestedStateNodes_.front() is the currently active state node 186 std::vector<GameStateTreeNode*>::iterator it = this->requestedStateNodes_.begin() + 1; 187 if (*it == this->activeStateNode_->parent_) 188 this->unloadState(this->activeStateNode_->state_); 189 else // has to be child 190 this->loadState((*it)->state_); 191 this->activeStateNode_ = *it; 192 this->requestedStateNodes_.erase(this->requestedStateNodes_.begin()); 193 } 194 195 // UPDATE, bottom to top in the stack 196 for (std::vector<GameState*>::const_iterator it = this->activeStates_.begin(); 197 it != this->activeStates_.end(); ++it) 198 (*it)->update(*this->gameClock_); 183 199 184 200 // STATISTICS … … 206 222 this->periodTime_ -= this->statisticsRefreshCycle_; 207 223 } 208 209 if (root.stateRequest_ != "") 210 root.gotoState(root.stateRequest_);211 }212 213 root.gotoState("root");214 root.deactivate();224 } 225 226 // Unload all remaining states 227 while (!this->activeStates_.empty()) 228 this->unloadState(this->activeStates_.back()); 229 this->activeStateNode_ = 0; 230 this->requestedStateNodes_.clear(); 215 231 } 216 232 … … 226 242 this->periodTickTime_+=length; 227 243 } 244 245 246 /***** GameState related *****/ 247 248 void Game::requestState(const std::string& name) 249 { 250 GameState* state = this->getState(name); 251 if (state == NULL || this->activeStateNode_ == NULL) 252 return; 253 254 GameStateTreeNode* requestedNode = 0; 255 256 // this->requestedStateNodes_.back() is the currently active state 257 GameStateTreeNode* lastRequestedNode = this->requestedStateNodes_.back(); 258 259 // Already the active node? 260 if (state == lastRequestedNode->state_) 261 { 262 COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl; 263 return; 264 } 265 266 // Check children first 267 for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i) 268 { 269 if (lastRequestedNode->children_[i]->state_ == state) 270 { 271 requestedNode = lastRequestedNode->children_[i]; 272 break; 273 } 274 } 275 276 // Check parent and all its grand parents 277 GameStateTreeNode* currentNode = lastRequestedNode; 278 while (requestedNode == NULL && currentNode->parent_ != NULL) 279 { 280 if (currentNode->state_ == state) 281 requestedNode = currentNode; 282 currentNode = currentNode->parent_; 283 } 284 285 if (requestedNode == NULL) 286 COUT(1) << "Error: Requested GameState transition is not allowed. Ignoring." << std::endl; 287 else 288 this->requestedStateNodes_.push_back(requestedNode); 289 } 290 291 void Game::popState() 292 { 293 if (this->activeStateNode_ != NULL && this->requestedStateNodes_.back()->parent_) 294 this->requestState(this->requestedStateNodes_.back()->parent_->state_->getName()); 295 else 296 COUT(2) << "Warning: Could not pop GameState. Ignoring." << std::endl; 297 } 298 299 GameState* Game::getState(const std::string& name) 300 { 301 std::map<std::string, GameState*>::const_iterator it = allStates_s.find(name); 302 if (it != allStates_s.end()) 303 return it->second; 304 else 305 { 306 COUT(1) << "Error: Could not find GameState '" << name << "'. Ignoring." << std::endl; 307 return 0; 308 } 309 } 310 311 void Game::setStateHierarchy(const std::string& str) 312 { 313 // Split string into pieces of the form whitespacesText 314 std::vector<std::pair<std::string, unsigned> > stateStrings; 315 size_t pos = 0; 316 size_t startPos = 0; 317 while (pos < str.size()) 318 { 319 unsigned indentation = 0; 320 while(pos < str.size() && str[pos] == ' ') 321 ++indentation, ++pos; 322 startPos = pos; 323 while(pos < str.size() && str[pos] != ' ') 324 ++pos; 325 stateStrings.push_back(std::pair<std::string, unsigned>( 326 str.substr(startPos, pos - startPos), indentation)); 327 } 328 unsigned int currentLevel = 0; 329 GameStateTreeNode* currentNode = 0; 330 for (std::vector<std::pair<std::string, unsigned> >::const_iterator it = stateStrings.begin(); it != stateStrings.end(); ++it) 331 { 332 std::string newStateName = it->first; 333 unsigned newLevel = it->second; 334 GameState* newState = this->getState(newStateName); 335 if (!newState) 336 ThrowException(GameState, std::string("GameState with name '") + newStateName + "' not found!"); 337 if (newLevel == 0) 338 { 339 // root 340 if (this->rootStateNode_ != NULL) 341 ThrowException(GameState, "No two root GameStates are allowed!"); 342 GameStateTreeNode* newNode = new GameStateTreeNode; 343 newNode->state_ = newState; 344 newNode->parent_ = 0; 345 this->rootStateNode_ = newNode; 346 currentNode = this->rootStateNode_; 347 } 348 else if (currentNode) 349 { 350 GameStateTreeNode* newNode = new GameStateTreeNode; 351 newNode->state_ = newState; 352 if (newLevel < currentLevel) 353 { 354 // Get down the hierarchy 355 do 356 currentNode = currentNode->parent_; 357 while (newLevel < --currentLevel); 358 } 359 if (newLevel == currentLevel) 360 { 361 // same level 362 newNode->parent_ = currentNode->parent_; 363 newNode->parent_->children_.push_back(newNode); 364 } 365 else if (newLevel == currentLevel + 1) 366 { 367 // child 368 newNode->parent_ = currentNode; 369 currentNode->children_.push_back(newNode); 370 } 371 else 372 ThrowException(GameState, "Indentation error while parsing the hierarchy."); 373 currentNode = newNode; 374 currentLevel = newLevel; 375 } 376 else 377 { 378 ThrowException(GameState, "No root GameState specified!"); 379 } 380 } 381 } 382 383 /*** Internal ***/ 384 385 void Game::loadState(GameState* state) 386 { 387 state->activate(); 388 this->activeStates_.push_back(state); 389 } 390 391 void Game::unloadState(orxonox::GameState* state) 392 { 393 state->deactivate(); 394 this->activeStates_.pop_back(); 395 } 396 397 /*static*/ bool Game::addGameState(GameState* state) 398 { 399 std::map<std::string, GameState*>::const_iterator it = allStates_s.find(state->getName()); 400 if (it == allStates_s.end()) 401 allStates_s[state->getName()] = state; 402 else 403 ThrowException(GameState, "Cannot add two GameStates with the same name to 'Game'."); 404 405 // just a required dummy return value 406 return true; 407 } 228 408 } -
code/branches/gui/src/core/Game.h
r2843 r2844 36 36 #define _Game_H__ 37 37 38 #include " OrxonoxPrereqs.h"38 #include "CorePrereqs.h" 39 39 #include <cassert> 40 40 #include <list> 41 #include "core/OrxonoxClass.h" 41 #include <map> 42 #include <vector> 43 #include "OrxonoxClass.h" 44 45 #define AddGameState(classname, name, ...) \ 46 static bool bGameStateDummy_##classname##__LINE__ = orxonox::Game::addGameState(new classname(name, __VA_ARGS__)) 42 47 43 48 namespace orxonox … … 47 52 Main class responsible for running the game. 48 53 */ 49 class _ OrxonoxExport Game : public OrxonoxClass54 class _CoreExport Game : public OrxonoxClass 50 55 { 51 56 public: … … 54 59 void setConfigValues(); 55 60 61 void setStateHierarchy(const std::string& str); 62 GameState* getState(const std::string& name); 63 56 64 void run(); 57 65 void stop(); 66 67 void requestState(const std::string& name); 68 void popState(); 58 69 59 70 float getAvgTickTime() { return this->avgTickTime_; } … … 62 73 void addTickTime(uint32_t length); 63 74 75 static bool addGameState(GameState* state); 64 76 static Game& getInstance() { assert(singletonRef_s); return *singletonRef_s; } 65 77 … … 73 85 Game(Game&); // don't mess with singletons 74 86 75 Core* core_;76 Clock* gameClock_;87 void loadState(GameState* state); 88 void unloadState(GameState* state); 77 89 78 bool abort_; 90 std::vector<GameState*> activeStates_; 91 GameStateTreeNode* rootStateNode_; 92 GameStateTreeNode* activeStateNode_; 93 std::vector<GameStateTreeNode*> requestedStateNodes_; 94 95 Core* core_; 96 Clock* gameClock_; 97 98 bool abort_; 79 99 80 100 // variables for time statistics 81 uint64_t statisticsStartTime_; 82 std::list<statisticsTickInfo> 83 statisticsTickTimes_; 84 uint32_t periodTime_; 85 uint32_t periodTickTime_; 86 float avgFPS_; 87 float avgTickTime_; 101 uint64_t statisticsStartTime_; 102 std::list<statisticsTickInfo> statisticsTickTimes_; 103 uint32_t periodTime_; 104 uint32_t periodTickTime_; 105 float avgFPS_; 106 float avgTickTime_; 88 107 89 108 // config values 90 unsigned int statisticsRefreshCycle_;91 unsigned int statisticsAvgLength_;109 unsigned int statisticsRefreshCycle_; 110 unsigned int statisticsAvgLength_; 92 111 112 static std::map<std::string, GameState*> allStates_s; 93 113 static Game* singletonRef_s; //!< Pointer to the Singleton 94 114 }; -
code/branches/gui/src/core/GameState.cc
r2817 r2844 34 34 35 35 #include "GameState.h" 36 #include <cassert> 36 37 #include "util/Debug.h" 37 38 #include "util/Exception.h" 39 #include "Clock.h" 38 40 39 41 namespace orxonox … … 46 48 : name_(name) 47 49 , parent_(0) 48 , activeChild_(0)49 //, bPausegetParent()(false)50 50 { 51 Operationstemp = {false, false, false, false, false};52 this-> operation_ = temp;51 State temp = {false, false, false, false, false}; 52 this->activity_ = temp; 53 53 } 54 54 … … 59 59 GameState::~GameState() 60 60 { 61 OrxAssert(this-> operation_.active == false, "Deleting an active GameState is a very bad idea..");61 OrxAssert(this->activity_.active == false, "Deleting an active GameState is a very bad idea.."); 62 62 } 63 63 … … 71 71 void GameState::addChild(GameState* state) 72 72 { 73 if (!state) 74 return; 75 // check if the state/tree to be added has states in it that already exist in this tree. 76 for (std::map<std::string, GameState*>::const_iterator it = state->allChildren_.begin(); 77 it != state->allChildren_.end(); ++it) 73 assert(state != NULL); 74 75 std::map<std::string, GameState*>::const_iterator it = this->children_.find(state->getName()); 76 if (it == this->children_.end()) 78 77 { 79 if (this->getState(it->second->getName())) 80 { 81 ThrowException(GameState, "Cannot add a GameState to the hierarchy twice."); 82 return; 83 } 78 this->children_[state->getName()] = state; 79 // mark us as parent 80 state->setParent(this); 84 81 } 85 if (this->getState(state->name_))82 else 86 83 { 87 ThrowException(GameState, "Cannot add a GameState to the hierarchy twice."); 88 return; 84 ThrowException(GameState, "Cannot add two children with the same name"); 89 85 } 90 // Make sure we don't add a tree that already has an active state.91 if (state->getCurrentState())92 {93 ThrowException(GameState, "Cannot merge a tree that is already active.");94 return;95 }96 97 // merge the child's children into this tree98 for (std::map<std::string, GameState*>::const_iterator it = state->allChildren_.begin();99 it != state->allChildren_.end(); ++it)100 this->grandchildAdded(state, it->second);101 // merge 'state' into this tree102 this->grandchildAdded(state, state);103 104 // mark us as parent105 state->setParent(this);106 86 } 107 87 … … 115 95 void GameState::removeChild(GameState* state) 116 96 { 117 std::map<GameState*, GameState*>::iterator it = this->grandchildrenToChildren_.find(state); 118 if (it != this->grandchildrenToChildren_.end()) 119 { 120 if (state->isInSubtree(getCurrentState())) 121 { 122 ThrowException(GameState, "Cannot remove an active game state child '" 123 + state->getName() + "' from '" + name_ + "'."); 124 //COUT(2) << "Warning: Cannot remove an active game state child '" << state->getName() 125 // << "' from '" << name_ << "'." << std::endl; 126 } 127 else 128 { 129 for (std::map<GameState*, GameState*>::const_iterator it = state->grandchildrenToChildren_.begin(); 130 it != state->grandchildrenToChildren_.end(); ++it) 131 this->grandchildRemoved(it->first); 132 this->grandchildRemoved(state); 133 } 134 } 97 assert(state != NULL); 98 99 std::map<std::string, GameState*>::iterator it = this->children_.find(state->getName()); 100 if (it != this->children_.end()) 101 this->children_.erase(it); 135 102 else 136 103 { 137 104 ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '" 138 105 + state->getName() + "'."); 139 //COUT(2) << "Warning: Game state '" << name_ << "' doesn't have a child named '"140 // << state->getName() << "'. Removal skipped." << std::endl;141 106 } 142 107 } 143 108 144 /** 145 @brief 146 Removes a child by name. This splits the tree in two parts, 147 each of them functional on its own. 148 @param state 149 GameState by name 150 */ 151 152 void GameState::removeChild(const std::string& name) 109 void GameState::activateInternal() 153 110 { 154 GameState* state = getState(name); 155 if (state) 156 { 157 removeChild(state); 158 } 159 else 160 { 161 ThrowException(GameState, "GameState '" + name + "' doesn't exist."); 162 //COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl; 163 } 111 this->activity_.activating = true; 112 this->activate(); 113 this->activity_.activating = false; 114 this->activity_.active = true; 164 115 } 165 116 166 /** 167 @brief 168 Tells a state that one of its children has added a child. This is necessary 169 to fill the internal maps correctly. 170 @param child 171 The child who notices this state. 172 @param grandchild 173 The child that has been added. 174 */ 175 inline void GameState::grandchildAdded(GameState* child, GameState* grandchild) 117 void GameState::deactivateInternal() 176 118 { 177 // fill the two maps correctly. 178 this->allChildren_[grandchild->getName()] = grandchild; 179 this->grandchildrenToChildren_[grandchild] = child; 180 if (this->getParent()) 181 this->getParent()->grandchildAdded(this, grandchild); 119 this->activity_.active = false; 120 this->activity_.deactivating = true; 121 this->activate(); 122 this->activity_.deactivating = false; 123 this->activity_.suspended = false; 124 this->activity_.updating = false; 182 125 } 183 126 184 /** 185 @brief 186 Tells a state that one of its children has removed a child. This is necessary 187 to fill the internal maps correctly. 188 @param child 189 The child who notices this state. 190 @param grandchild 191 The child that has been removed. 192 */ 193 inline void GameState::grandchildRemoved(GameState* grandchild) 127 void GameState::updateInternal(const Clock& time) 194 128 { 195 // adjust the two maps correctly. 196 this->allChildren_.erase(grandchild->getName()); 197 this->grandchildrenToChildren_.erase(grandchild); 198 if (this->getParent()) 199 this->getParent()->grandchildRemoved(grandchild); 200 } 201 202 /** 203 @brief 204 Checks whether a specific game states exists in the hierarchy. 205 @remarks 206 Remember that the every node has a map with all its child nodes. 207 */ 208 GameState* GameState::getState(const std::string& name) 209 { 210 if (this->getParent()) 211 return this->getParent()->getState(name); 212 else 213 { 214 // The map only contains children, so check ourself first 215 if (name == this->name_) 216 return this; 217 // Search in the map. If there is no entry, we can be sure the state doesn't exist. 218 std::map<std::string, GameState*>::const_iterator it = this->allChildren_.find(name); 219 return (it!= this->allChildren_.end() ? it->second : 0); 220 } 221 } 222 223 /** 224 @brief 225 Returns the root node of the tree. 226 */ 227 GameState* GameState::getRoot() 228 { 229 if (this->getParent()) 230 return this->getParent()->getRoot(); 231 else 232 return this; 233 } 234 235 /** 236 @brief 237 Returns the current active state. 238 @remarks 239 Remember that the current active state is the one that does not 240 have active children itself. Many states can be active at once. 241 */ 242 GameState* GameState::getCurrentState() 243 { 244 if (this->operation_.active) 245 { 246 if (this->activeChild_) 247 return this->activeChild_->getCurrentState(); 248 else 249 return this; 250 } 251 else 252 { 253 if (this->getParent()) 254 return this->getParent()->getCurrentState(); 255 else 256 return 0; 257 } 258 } 259 260 /** 261 @brief 262 Determines whether 'state' is in this subtree, including this node. 263 */ 264 bool GameState::isInSubtree(GameState* state) const 265 { 266 return (grandchildrenToChildren_.find(state) != grandchildrenToChildren_.end() 267 || state == this); 268 } 269 270 /** 271 @brief 272 Makes a state transition according to the state tree. You can choose any state 273 in the tree to do the call. The function finds the current state on its own. 274 @param state 275 The state to be entered, has to exist in the tree. 276 */ 277 void GameState::requestState(const std::string& name) 278 { 279 assert(getRoot()); 280 getRoot()->requestState(name); 281 } 282 283 /** 284 @brief 285 Internal method that actually makes the state transition. Since it is internal, 286 the method can assume certain things to be granted (like 'this' is always active). 287 */ 288 void GameState::makeTransition(GameState* source, GameState* destination) 289 { 290 if (source == this->getParent()) 291 { 292 // call is from the parent 293 this->activate(); 294 } 295 else if (source == 0) 296 { 297 // call was just started by root 298 // don't do anyting yet 299 } 300 else 301 { 302 // call is from a child 303 this->activeChild_ = 0; 304 } 305 306 if (destination == this) 307 return; 308 309 // Check for 'destination' in the children map first 310 std::map<GameState*, GameState*>::const_iterator it 311 = this->grandchildrenToChildren_.find(destination); 312 if (it != this->grandchildrenToChildren_.end()) 313 { 314 // child state. Don't use 'state', might be a grandchild! 315 this->activeChild_ = it->second; 316 it->second->makeTransition(this, destination); 317 } 318 else 319 { 320 // parent. We can be sure of this. 321 assert(this->getParent() != 0); 322 323 this->deactivate(); 324 this->getParent()->makeTransition(this, destination); 325 } 326 } 327 328 /** 329 @brief 330 Activates the state. Only sets bActive_ to true and notifies the parent. 331 */ 332 void GameState::activate() 333 { 334 this->operation_.active = true; 335 this->operation_.entering = true; 336 this->enter(); 337 this->operation_.entering = false; 338 } 339 340 /** 341 Activates the state. Only sets bActive_ to false and notifies the parent. 342 */ 343 void GameState::deactivate() 344 { 345 this->operation_.leaving = true; 346 this->leave(); 347 this->operation_.leaving = false; 348 this->operation_.active = false; 349 } 350 351 /** 352 @brief 353 Update method that calls ticked() with enclosed bRunning_ = true 354 If there was a state transition request within ticked() then this 355 method will transition in the end. 356 @param dt Delta time 357 @note 358 This method is not virtual! You cannot override it therefore. 359 */ 360 void GameState::tick(const Clock& time) 361 { 362 this->operation_.running = true; 363 this->ticked(time); 364 this->operation_.running = false; 129 this->activity_.updating = true; 130 this->update(time); 131 this->activity_.updating = false; 365 132 } 366 133 } -
code/branches/gui/src/core/GameState.h
r2817 r2844 39 39 40 40 #include <string> 41 #include <vector>42 41 #include <map> 43 #include <cassert> 44 #include "Clock.h" 42 #include "CorePrereqs.h" 45 43 46 44 namespace orxonox … … 62 60 class _CoreExport GameState 63 61 { 64 friend class RootGameState;65 // Hack66 62 friend class Game; 67 63 … … 71 67 Gives information about what the GameState is currently doing 72 68 */ 73 struct Operations69 struct State 74 70 { 75 unsigned active : 1;76 unsigned entering: 1;77 unsigned leaving: 1;78 unsigned running: 1;79 unsigned suspended : 1;71 unsigned active : 1; 72 unsigned activating : 1; 73 unsigned deactivating : 1; 74 unsigned updating : 1; 75 unsigned suspended : 1; 80 76 }; 81 77 … … 85 81 86 82 const std::string& getName() const { return name_; } 87 const Operations getOperation() const { return this->operation_; } 88 bool isInSubtree(GameState* state) const; 89 90 GameState* getState(const std::string& name); 91 GameState* getRoot(); 92 //! Returns the currently active game state 93 virtual GameState* getCurrentState(); 94 95 virtual void requestState(const std::string& name); 83 const State getActivity() const { return this->activity_; } 84 GameState* getParent() const { return this->parent_; } 96 85 97 86 void addChild(GameState* state); 98 87 void removeChild(GameState* state); 99 void removeChild(const std::string& name);100 88 101 89 protected: 102 virtual void enter() = 0; 103 virtual void leave() = 0; 104 virtual void ticked(const Clock& time) = 0; 105 106 GameState* getActiveChild() { return this->activeChild_; } 107 108 void tickChild(const Clock& time) { if (this->getActiveChild()) this->getActiveChild()->tick(time); } 109 110 GameState* getParent() const { return this->parent_; } 111 void setParent(GameState* state) { this->parent_ = state; } 90 virtual void activate() = 0; 91 virtual void deactivate() = 0; 92 virtual void update(const Clock& time) = 0; 112 93 113 94 private: 114 //! Performs a transition to 'destination' 115 virtual void makeTransition(GameState* source, GameState* destination); 116 117 void grandchildAdded(GameState* child, GameState* grandchild); 118 void grandchildRemoved(GameState* grandchild); 119 120 void tick(const Clock& time); 121 void activate(); 122 void deactivate(); 95 void setParent(GameState* state) { this->parent_ = state; } 96 void setActivity(State activity); 97 void activateInternal(); 98 void deactivateInternal(); 99 void updateInternal(const Clock& time); 123 100 124 101 const std::string name_; 125 Operations operation_;102 State activity_; 126 103 GameState* parent_; 127 GameState* activeChild_; 128 //bool bPauseParent_; 129 std::map<std::string, GameState*> allChildren_; 130 std::map<GameState*, GameState*> grandchildrenToChildren_; 104 std::map<std::string, GameState*> children_; 131 105 }; 132 106 }
Note: See TracChangeset
for help on using the changeset viewer.