Changeset 3356 for code/branches/resource/src/core
- Timestamp:
- Jul 27, 2009, 11:13:25 AM (15 years ago)
- Location:
- code/branches/resource/src/core
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/resource/src/core/Core.cc
r3355 r3356 671 671 try 672 672 { 673 // process input events 674 this->inputManager_->update(time); 675 // process gui events 676 this->guiManager_->update(time); 673 if (this->bGraphicsLoaded_) 674 { 675 // process input events 676 this->inputManager_->update(time); 677 // process gui events 678 this->guiManager_->update(time); 679 } 677 680 // process thread commands 678 681 this->tclThreadManager_->update(time); … … 696 699 try 697 700 { 698 // Render (doesn't throw) 699 this->graphicsManager_->update(time); 701 if (this->bGraphicsLoaded_) 702 { 703 // Render (doesn't throw) 704 this->graphicsManager_->update(time); 705 } 700 706 } 701 707 catch (const std::exception& ex) -
code/branches/resource/src/core/Game.cc
r3355 r3356 70 70 struct GameStateTreeNode 71 71 { 72 GameState* state_;72 std::string name_; 73 73 weak_ptr<GameStateTreeNode> parent_; 74 74 std::vector<shared_ptr<GameStateTreeNode> > children_; … … 138 138 this->core_ = new Core(cmdLine); 139 139 140 // After the core has been created, we can safely instantiate the GameStates 140 // After the core has been created, we can safely instantiate the GameStates that don't require graphics 141 141 for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin(); 142 142 it != gameStateDeclarations_s.end(); ++it) 143 143 { 144 // Only create the states appropriate for the game mode 145 //if (GameMode::showsGraphics || !it->second.bGraphicsMode) 146 gameStates_[getLowercase(it->second.stateName)] = GameStateFactory::fabricate(it->second); 144 if (!it->second.bGraphicsMode) 145 constructedStates_[it->second.stateName] = GameStateFactory::fabricate(it->second); 147 146 } 148 147 149 148 // The empty root state is ALWAYS loaded! 150 149 this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode()); 151 this->rootStateNode_-> state_ = getState("emptyRootGameState");152 this-> activeStateNode_ = this->rootStateNode_;153 this-> activeStates_.push_back(this->rootStateNode_->state_);150 this->rootStateNode_->name_ = "emptyRootGameState"; 151 this->loadedTopStateNode_ = this->rootStateNode_; 152 this->loadedStates_.push_back(this->getState(rootStateNode_->name_)); 154 153 155 154 // Do this after the Core creation! … … 166 165 167 166 // Destroy the GameStates (note that the nodes still point to them, but doesn't matter) 168 for (std::map<std::string, GameState*>::const_iterator it = gameStates_.begin();169 it != gameStates_.end(); ++it)167 for (std::map<std::string, GameState*>::const_iterator it = constructedStates_.begin(); 168 it != constructedStates_.end(); ++it) 170 169 delete it->second; 171 170 … … 208 207 StatisticsTickInfo tickInfo = {0, 0}; 209 208 statisticsTickTimes_.push_back(tickInfo); 210 while (!this->bAbort_ && (!this-> activeStates_.empty() || this->requestedStateNodes_.size() > 0))209 while (!this->bAbort_ && (!this->loadedStates_.empty() || this->requestedStateNodes_.size() > 0)) 211 210 { 212 211 // Generate the dt … … 246 245 247 246 // UNLOAD all remaining states 248 while (this-> activeStates_.size() > 1)249 this->unloadState(this-> activeStates_.back());250 this-> activeStateNode_ = this->rootStateNode_;247 while (this->loadedStates_.size() > 1) 248 this->unloadState(this->loadedStates_.back()->getName()); 249 this->loadedTopStateNode_ = this->rootStateNode_; 251 250 this->requestedStateNodes_.clear(); 252 251 } … … 257 256 { 258 257 shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front(); 259 assert(this-> activeStateNode_);260 if (!this-> activeStateNode_->parent_.expired() && requestedStateNode == this->activeStateNode_->parent_.lock())261 this->unloadState( this->activeStateNode_->state_);258 assert(this->loadedTopStateNode_); 259 if (!this->loadedTopStateNode_->parent_.expired() && requestedStateNode == this->loadedTopStateNode_->parent_.lock()) 260 this->unloadState(loadedTopStateNode_->name_); 262 261 else // has to be child 263 262 { 264 263 try 265 264 { 266 this->loadState(requestedStateNode-> state_);265 this->loadState(requestedStateNode->name_); 267 266 } 268 267 catch (const std::exception& ex) 269 268 { 270 COUT(1) << "Error: Loading GameState '" << requestedStateNode-> state_->getName()<< "' failed: " << ex.what() << std::endl;269 COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << ex.what() << std::endl; 271 270 // All scheduled operations have now been rendered inert --> flush them and issue a warning 272 271 if (this->requestedStateNodes_.size() > 1) … … 276 275 } 277 276 } 278 this-> activeStateNode_ = requestedStateNode;277 this->loadedTopStateNode_ = requestedStateNode; 279 278 this->requestedStateNodes_.erase(this->requestedStateNodes_.begin()); 280 279 } … … 284 283 { 285 284 // Note: The first element is the empty root state, which doesn't need ticking 286 for (std::vector<GameState*>::const_iterator it = this-> activeStates_.begin() + 1;287 it != this-> activeStates_.end(); ++it)285 for (std::vector<GameState*>::const_iterator it = this->loadedStates_.begin() + 1; 286 it != this->loadedStates_.end(); ++it) 288 287 { 289 288 std::string exceptionMessage; … … 307 306 COUT(1) << "This should really never happen!" << std::endl; 308 307 COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl; 309 if ((*it)->getParent() != NULL) 310 this->requestState((*it)->getParent()->getName()); 308 shared_ptr<GameStateTreeNode> current = this->loadedTopStateNode_; 309 while (current->name_ != (*it)->getName() && current) 310 current = current->parent_.lock(); 311 if (current && current->parent_.lock()) 312 this->requestState(current->parent_.lock()->name_); 311 313 else 312 314 this->stop(); … … 382 384 void Game::requestState(const std::string& name) 383 385 { 384 GameState* state = this->getState(name); 385 if (state == NULL) 386 if (!this->checkState(name)) 387 { 388 COUT(2) << "Warning: GameState named '" << name << "' doesn't exist!" << std::endl; 386 389 return; 390 } 387 391 388 392 //if (this->bChangingState_) … … 394 398 shared_ptr<GameStateTreeNode> lastRequestedNode; 395 399 if (this->requestedStateNodes_.empty()) 396 lastRequestedNode = this-> activeStateNode_;400 lastRequestedNode = this->loadedTopStateNode_; 397 401 else 398 402 lastRequestedNode = this->requestedStateNodes_.back(); 399 if ( state == lastRequestedNode->state_)403 if (name == lastRequestedNode->name_) 400 404 { 401 405 COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl; … … 407 411 for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i) 408 412 { 409 if (lastRequestedNode->children_[i]-> state_ == state)413 if (lastRequestedNode->children_[i]->name_ == name) 410 414 { 411 415 requestedNodes.push_back(lastRequestedNode->children_[i]); … … 420 424 while (currentNode != NULL) 421 425 { 422 if (currentNode-> state_ == state)426 if (currentNode->name_ == name) 423 427 break; 424 428 currentNode = currentNode->parent_.lock(); … … 444 448 shared_ptr<GameStateTreeNode> lastRequestedNode; 445 449 if (this->requestedStateNodes_.empty()) 446 lastRequestedNode = this-> activeStateNode_;450 lastRequestedNode = this->loadedTopStateNode_; 447 451 else 448 452 lastRequestedNode = this->requestedStateNodes_.back(); 449 453 if (lastRequestedNode != this->rootStateNode_) 450 this->requestState(lastRequestedNode->parent_.lock()-> state_->getName());454 this->requestState(lastRequestedNode->parent_.lock()->name_); 451 455 else 452 456 COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl; … … 455 459 GameState* Game::getState(const std::string& name) 456 460 { 457 std::map<std::string, GameState*>::const_iterator it = gameStates_.find(getLowercase(name));458 if (it != gameStates_.end())461 std::map<std::string, GameState*>::const_iterator it = constructedStates_.find(name); 462 if (it != constructedStates_.end()) 459 463 return it->second; 460 464 else 461 465 { 462 COUT(1) << "Error: Could not find GameState '" << name << "'. Ignoring." << std::endl; 466 std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name); 467 if (it != gameStateDeclarations_s.end()) 468 COUT(1) << "Error: GameState '" << name << "' has not yet been loaded." << std::endl; 469 else 470 COUT(1) << "Error: Could not find GameState '" << name << "'." << std::endl; 463 471 return 0; 464 472 } … … 487 495 std::string newStateName = it->first; 488 496 unsigned newLevel = it->second + 1; // empty root is 0 489 GameState* newState = this->getState(newStateName); 490 if (!newState) 497 if (!this->checkState(newStateName)) 491 498 ThrowException(GameState, "GameState with name '" << newStateName << "' not found!"); 492 if (newState == this->rootStateNode_->state_)499 if (newStateName == this->rootStateNode_->name_) 493 500 ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy..."); 494 501 shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode); 495 newNode-> state_ = newState;502 newNode->name_ = newStateName; 496 503 497 504 if (newLevel <= currentLevel) … … 506 513 newNode->parent_ = currentNode; 507 514 currentNode->children_.push_back(newNode); 508 currentNode->state_->addChild(newNode->state_);509 515 } 510 516 else … … 523 529 core_->loadGraphics(); 524 530 GameMode::bShowsGraphics_s = true; 531 532 // Construct all the GameStates that require graphics 533 for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin(); 534 it != gameStateDeclarations_s.end(); ++it) 535 { 536 if (it->second.bGraphicsMode) 537 { 538 if (!constructedStates_.insert(std::make_pair( 539 it->second.stateName, GameStateFactory::fabricate(it->second))).second) 540 assert(false); // GameState was already created! 541 } 542 } 525 543 } 526 544 } … … 530 548 if (GameMode::bShowsGraphics_s) 531 549 { 550 // Destroy all the GameStates that require graphics 551 for (std::map<std::string, GameState*>::iterator it = constructedStates_.begin(); it != constructedStates_.end();) 552 { 553 if (it->second->getInfo().bGraphicsMode) 554 { 555 delete it->second; 556 it = constructedStates_.erase(it); 557 } 558 else 559 ++it; 560 } 561 532 562 core_->unloadGraphics(); 533 563 GameMode::bShowsGraphics_s = false; … … 535 565 } 536 566 537 void Game::loadState(GameState* state) 567 bool Game::checkState(const std::string& name) const 568 { 569 std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name); 570 if (it == gameStateDeclarations_s.end()) 571 return false; 572 else 573 return true; 574 } 575 576 void Game::loadState(const std::string& name) 538 577 { 539 578 this->bChangingState_ = true; 540 579 // If state requires graphics, load it 541 if ( state->getInfo().bGraphicsMode)580 if (gameStateDeclarations_s[name].bGraphicsMode) 542 581 this->loadGraphics(); 582 GameState* state = this->getState(name); 543 583 state->activate(); 544 if (!this-> activeStates_.empty())545 this-> activeStates_.back()->activity_.topState = false;546 this-> activeStates_.push_back(state);584 if (!this->loadedStates_.empty()) 585 this->loadedStates_.back()->activity_.topState = false; 586 this->loadedStates_.push_back(state); 547 587 state->activity_.topState = true; 548 588 this->bChangingState_ = false; 549 589 } 550 590 551 void Game::unloadState(orxonox::GameState* state) 552 { 591 void Game::unloadState(const std::string& name) 592 { 593 GameState* state = this->getState(name); 553 594 this->bChangingState_ = true; 554 595 state->activity_.topState = false; 555 this-> activeStates_.pop_back();556 if (!this-> activeStates_.empty())557 this-> activeStates_.back()->activity_.topState = true;596 this->loadedStates_.pop_back(); 597 if (!this->loadedStates_.empty()) 598 this->loadedStates_.back()->activity_.topState = true; 558 599 try 559 600 { … … 561 602 // Check if graphis is still required 562 603 bool graphicsRequired = false; 563 for (unsigned i = 0; i < activeStates_.size(); ++i)564 graphicsRequired |= activeStates_[i]->getInfo().bGraphicsMode;604 for (unsigned i = 0; i < loadedStates_.size(); ++i) 605 graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode; 565 606 if (!graphicsRequired) 566 607 this->unloadGraphics(); … … 568 609 catch (const std::exception& ex) 569 610 { 570 COUT(2) << "Warning: Unloading GameState '" << state->getName()<< "' threw an exception: " << ex.what() << std::endl;611 COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << ex.what() << std::endl; 571 612 COUT(2) << " There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl; 572 613 } -
code/branches/resource/src/core/Game.h
r3355 r3356 47 47 48 48 #include "util/Debug.h" 49 #include "util/StringUtils.h"50 49 51 50 /** … … 76 75 class _CoreExport Game 77 76 { 77 typedef boost::shared_ptr<GameStateTreeNode> GameStateTreeNodePtr; 78 78 public: 79 79 Game(const std::string& cmdLine); … … 134 134 void unloadGraphics(); 135 135 136 void loadState(GameState* state); 137 void unloadState(GameState* state); 136 bool checkState(const std::string& name) const; 137 void loadState(const std::string& name); 138 void unloadState(const std::string& name); 138 139 139 140 // Main loop structuring … … 143 144 void updateFPSLimiter(); 144 145 145 std::map<std::string, GameState*> gameStates_;146 std::vector<GameState*> activeStates_;147 boost::shared_ptr<GameStateTreeNode>rootStateNode_;148 boost::shared_ptr<GameStateTreeNode> activeStateNode_;149 std::vector< boost::shared_ptr<GameStateTreeNode>> requestedStateNodes_;146 std::map<std::string, GameState*> constructedStates_; 147 std::vector<GameState*> loadedStates_; 148 GameStateTreeNodePtr rootStateNode_; 149 GameStateTreeNodePtr loadedTopStateNode_; 150 std::vector<GameStateTreeNodePtr > requestedStateNodes_; 150 151 151 Core* core_;152 Clock* gameClock_;153 GameConfiguration* configuration_;152 Core* core_; 153 Clock* gameClock_; 154 GameConfiguration* configuration_; 154 155 155 bool bChangingState_;156 bool bAbort_;156 bool bChangingState_; 157 bool bAbort_; 157 158 158 159 // variables for time statistics 159 uint64_t statisticsStartTime_;160 std::list<StatisticsTickInfo> statisticsTickTimes_;161 uint32_t periodTime_;162 uint32_t periodTickTime_;163 float avgFPS_;164 float avgTickTime_;165 int excessSleepTime_;166 unsigned int minimumSleepTime_;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_; 167 168 168 169 static std::map<std::string, GameStateInfo> gameStateDeclarations_s; … … 173 174 /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode) 174 175 { 175 std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find( getLowercase(stateName));176 std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName); 176 177 if (it == gameStateDeclarations_s.end()) 177 178 { 178 GameStateInfo& info = gameStateDeclarations_s[ getLowercase(stateName)];179 GameStateInfo& info = gameStateDeclarations_s[stateName]; 179 180 info.stateName = stateName; 180 181 info.className = className; -
code/branches/resource/src/core/GameState.cc
r3355 r3356 48 48 GameState::GameState(const GameStateInfo& info) 49 49 : info_(info) 50 , parent_(0)51 50 { 52 51 this->activity_.activating = false; … … 70 69 { 71 70 return info_.stateName; 72 }73 74 /**75 @brief76 Adds a child to the current tree. The Child can contain children of its own.77 But you cannot a state tree that already has an active state.78 @param state79 The state to be added.80 */81 void GameState::addChild(GameState* state)82 {83 assert(state != NULL);84 85 std::map<std::string, GameState*>::const_iterator it = this->children_.find(state->getName());86 if (it == this->children_.end())87 {88 this->children_[state->getName()] = state;89 // mark us as parent90 state->setParent(this);91 }92 else93 {94 ThrowException(GameState, "Cannot add two children with the same name");95 }96 }97 98 /**99 @brief100 Removes a child by instance. This splits the tree in two parts,101 each of them functional on its own.102 @param state103 GameState by instance pointer104 */105 void GameState::removeChild(GameState* state)106 {107 assert(state != NULL);108 109 std::map<std::string, GameState*>::iterator it = this->children_.find(state->getName());110 if (it != this->children_.end())111 this->children_.erase(it);112 else113 {114 ThrowException(GameState, "Game state '" + this->getName() + "' doesn't have a child named '"115 + state->getName() + "'.");116 }117 71 } 118 72 -
code/branches/resource/src/core/GameState.h
r3355 r3356 82 82 const std::string& getName() const; 83 83 State getActivity() const { return activity_; } 84 GameState* getParent() const { return parent_; }85 84 const GameStateInfo& getInfo() const { return info_; } 86 87 void addChild(GameState* state);88 void removeChild(GameState* state);89 85 90 86 protected: … … 94 90 95 91 private: 96 void setParent(GameState* state) { this->parent_ = state; }97 92 void setActivity(State activity); 98 93 void activateInternal(); … … 100 95 void updateInternal(const Clock& time); 101 96 102 const GameStateInfo& info_; 103 State activity_; 104 GameState* parent_; 105 std::map<std::string, GameState*> children_; 97 const GameStateInfo& info_; 98 State activity_; 106 99 }; 107 100 }
Note: See TracChangeset
for help on using the changeset viewer.