Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jul 27, 2009, 11:13:25 AM (15 years ago)
Author:
rgrieder
Message:

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).

Location:
code/branches/resource/src/core
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • code/branches/resource/src/core/Core.cc

    r3355 r3356  
    671671        try
    672672        {
    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            }
    677680            // process thread commands
    678681            this->tclThreadManager_->update(time);
     
    696699        try
    697700        {
    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            }
    700706        }
    701707        catch (const std::exception& ex)
  • code/branches/resource/src/core/Game.cc

    r3355 r3356  
    7070    struct GameStateTreeNode
    7171    {
    72         GameState* state_;
     72        std::string name_;
    7373        weak_ptr<GameStateTreeNode> parent_;
    7474        std::vector<shared_ptr<GameStateTreeNode> > children_;
     
    138138        this->core_ = new Core(cmdLine);
    139139
    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
    141141        for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
    142142            it != gameStateDeclarations_s.end(); ++it)
    143143        {
    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);
    147146        }
    148147
    149148        // The empty root state is ALWAYS loaded!
    150149        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_));
    154153
    155154        // Do this after the Core creation!
     
    166165
    167166        // 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)
    170169            delete it->second;
    171170
     
    208207        StatisticsTickInfo tickInfo = {0, 0};
    209208        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))
    211210        {
    212211            // Generate the dt
     
    246245
    247246        // 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_;
    251250        this->requestedStateNodes_.clear();
    252251    }
     
    257256        {
    258257            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_);
    262261            else // has to be child
    263262            {
    264263                try
    265264                {
    266                     this->loadState(requestedStateNode->state_);
     265                    this->loadState(requestedStateNode->name_);
    267266                }
    268267                catch (const std::exception& ex)
    269268                {
    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;
    271270                    // All scheduled operations have now been rendered inert --> flush them and issue a warning
    272271                    if (this->requestedStateNodes_.size() > 1)
     
    276275                }
    277276            }
    278             this->activeStateNode_ = requestedStateNode;
     277            this->loadedTopStateNode_ = requestedStateNode;
    279278            this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
    280279        }
     
    284283    {
    285284        // 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)
    288287        {
    289288            std::string exceptionMessage;
     
    307306                COUT(1) << "This should really never happen!" << std::endl;
    308307                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_);
    311313                else
    312314                    this->stop();
     
    382384    void Game::requestState(const std::string& name)
    383385    {
    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;
    386389            return;
     390        }
    387391
    388392        //if (this->bChangingState_)
     
    394398        shared_ptr<GameStateTreeNode> lastRequestedNode;
    395399        if (this->requestedStateNodes_.empty())
    396             lastRequestedNode = this->activeStateNode_;
     400            lastRequestedNode = this->loadedTopStateNode_;
    397401        else
    398402            lastRequestedNode = this->requestedStateNodes_.back();
    399         if (state == lastRequestedNode->state_)
     403        if (name == lastRequestedNode->name_)
    400404        {
    401405            COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl;
     
    407411        for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
    408412        {
    409             if (lastRequestedNode->children_[i]->state_ == state)
     413            if (lastRequestedNode->children_[i]->name_ == name)
    410414            {
    411415                requestedNodes.push_back(lastRequestedNode->children_[i]);
     
    420424            while (currentNode != NULL)
    421425            {
    422                 if (currentNode->state_ == state)
     426                if (currentNode->name_ == name)
    423427                    break;
    424428                currentNode = currentNode->parent_.lock();
     
    444448        shared_ptr<GameStateTreeNode> lastRequestedNode;
    445449        if (this->requestedStateNodes_.empty())
    446             lastRequestedNode = this->activeStateNode_;
     450            lastRequestedNode = this->loadedTopStateNode_;
    447451        else
    448452            lastRequestedNode = this->requestedStateNodes_.back();
    449453        if (lastRequestedNode != this->rootStateNode_)
    450             this->requestState(lastRequestedNode->parent_.lock()->state_->getName());
     454            this->requestState(lastRequestedNode->parent_.lock()->name_);
    451455        else
    452456            COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl;
     
    455459    GameState* Game::getState(const std::string& name)
    456460    {
    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())
    459463            return it->second;
    460464        else
    461465        {
    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;
    463471            return 0;
    464472        }
     
    487495            std::string newStateName = it->first;
    488496            unsigned newLevel = it->second + 1; // empty root is 0
    489             GameState* newState = this->getState(newStateName);
    490             if (!newState)
     497            if (!this->checkState(newStateName))
    491498                ThrowException(GameState, "GameState with name '" << newStateName << "' not found!");
    492             if (newState == this->rootStateNode_->state_)
     499            if (newStateName == this->rootStateNode_->name_)
    493500                ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy...");
    494501            shared_ptr<GameStateTreeNode> newNode(new GameStateTreeNode);
    495             newNode->state_ = newState;
     502            newNode->name_ = newStateName;
    496503
    497504            if (newLevel <= currentLevel)
     
    506513                newNode->parent_ = currentNode;
    507514                currentNode->children_.push_back(newNode);
    508                 currentNode->state_->addChild(newNode->state_);
    509515            }
    510516            else
     
    523529            core_->loadGraphics();
    524530            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            }
    525543        }
    526544    }
     
    530548        if (GameMode::bShowsGraphics_s)
    531549        {
     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
    532562            core_->unloadGraphics();
    533563            GameMode::bShowsGraphics_s = false;
     
    535565    }
    536566
    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)
    538577    {
    539578        this->bChangingState_ = true;
    540579        // If state requires graphics, load it
    541         if (state->getInfo().bGraphicsMode)
     580        if (gameStateDeclarations_s[name].bGraphicsMode)
    542581            this->loadGraphics();
     582        GameState* state = this->getState(name);
    543583        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);
    547587        state->activity_.topState = true;
    548588        this->bChangingState_ = false;
    549589    }
    550590
    551     void Game::unloadState(orxonox::GameState* state)
    552     {
     591    void Game::unloadState(const std::string& name)
     592    {
     593        GameState* state = this->getState(name);
    553594        this->bChangingState_ = true;
    554595        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;
    558599        try
    559600        {
     
    561602            // Check if graphis is still required
    562603            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;
    565606            if (!graphicsRequired)
    566607                this->unloadGraphics();
     
    568609        catch (const std::exception& ex)
    569610        {
    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;
    571612            COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
    572613        }
  • code/branches/resource/src/core/Game.h

    r3355 r3356  
    4747
    4848#include "util/Debug.h"
    49 #include "util/StringUtils.h"
    5049
    5150/**
     
    7675    class _CoreExport Game
    7776    {
     77        typedef boost::shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
    7878    public:
    7979        Game(const std::string& cmdLine);
     
    134134        void unloadGraphics();
    135135
    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);
    138139
    139140        // Main loop structuring
     
    143144        void updateFPSLimiter();
    144145
    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_;
    150151
    151         Core*                           core_;
    152         Clock*                          gameClock_;
    153         GameConfiguration*              configuration_;
     152        Core*                              core_;
     153        Clock*                             gameClock_;
     154        GameConfiguration*                 configuration_;
    154155
    155         bool                            bChangingState_;
    156         bool                            bAbort_;
     156        bool                               bChangingState_;
     157        bool                               bAbort_;
    157158
    158159        // 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_;
    167168
    168169        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
     
    173174    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
    174175    {
    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);
    176177        if (it == gameStateDeclarations_s.end())
    177178        {
    178             GameStateInfo& info = gameStateDeclarations_s[getLowercase(stateName)];
     179            GameStateInfo& info = gameStateDeclarations_s[stateName];
    179180            info.stateName = stateName;
    180181            info.className = className;
  • code/branches/resource/src/core/GameState.cc

    r3355 r3356  
    4848    GameState::GameState(const GameStateInfo& info)
    4949        : info_(info)
    50         , parent_(0)
    5150    {
    5251        this->activity_.activating   = false;
     
    7069    {
    7170        return info_.stateName;
    72     }
    73 
    74     /**
    75     @brief
    76         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 state
    79         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 parent
    90             state->setParent(this);
    91         }
    92         else
    93         {
    94             ThrowException(GameState, "Cannot add two children with the same name");
    95         }
    96     }
    97 
    98     /**
    99     @brief
    100         Removes a child by instance. This splits the tree in two parts,
    101         each of them functional on its own.
    102     @param state
    103         GameState by instance pointer
    104     */
    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         else
    113         {
    114             ThrowException(GameState, "Game state '" + this->getName() + "' doesn't have a child named '"
    115                 + state->getName() + "'.");
    116         }
    11771    }
    11872
  • code/branches/resource/src/core/GameState.h

    r3355 r3356  
    8282        const std::string& getName()   const;
    8383        State getActivity()            const { return activity_; }
    84         GameState* getParent()         const { return parent_; }
    8584        const GameStateInfo& getInfo() const { return info_; }
    86 
    87         void addChild(GameState* state);
    88         void removeChild(GameState* state);
    8985
    9086    protected:
     
    9490
    9591    private:
    96         void setParent(GameState* state) { this->parent_ = state; }
    9792        void setActivity(State activity);
    9893        void activateInternal();
     
    10095        void updateInternal(const Clock& time);
    10196
    102         const GameStateInfo&                     info_;
    103         State                                    activity_;
    104         GameState*                               parent_;
    105         std::map<std::string, GameState*>        children_;
     97        const GameStateInfo& info_;
     98        State                activity_;
    10699    };
    107100}
Note: See TracChangeset for help on using the changeset viewer.