Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 27, 2008, 10:21:39 PM (16 years ago)
Author:
rgrieder
Message:
  • Changed GameState so that the new RootGameState can override 2 virtual methods
  • added RootGameState that takes care of state transitions (can only happen between ticks)
  • moved main loop to GSRoot instead of GSGraphics
  • network GameStates not yet finished
  • GraphicsEngine not yet merged into GSGraphics
Location:
code/branches/gui/src/core
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • code/branches/gui/src/core/CMakeLists.txt

    r1665 r1672  
    1010  OutputBuffer.cc
    1111  OutputHandler.cc
     12  RootGameState.cc
    1213  Script.cc
    1314  SignalHandler.cc
  • code/branches/gui/src/core/CorePrereqs.h

    r1663 r1672  
    161161  class XMLPortParamContainer;
    162162
     163  // game states
     164  class BaseGameState;
     165  class GameState;
     166  class RootGameState;
     167
    163168  // input
    164169  class BaseCommand;
  • code/branches/gui/src/core/GameState.cc

    r1670 r1672  
    4646    GameState::GameState(const std::string& name)
    4747        : name_(name)
    48         , bPauseParent_(false)
    49         //, bActive_(false)
    50         //, bSuspended_(false)
    51         //, bRunning_(false)
    52         , scheduledTransition_(0)
    5348        , parent_(0)
    5449        , activeChild_(0)
     50        //, bPauseParent_(false)
    5551    {
    5652        Operations temp = {false, false, false, false, false};
     
    6460    GameState::~GameState()
    6561    {
    66         if (this->operation_.active)
    67         {
    68             if (this->parent_)
    69                 this->requestState(this->parent_->getName());
    70             else
    71                 this->requestState("");
    72         }
     62        OrxAssert(!isInSubtree(getCurrentState()), "Deleting an active GameState is a very bad idea..");
    7363    }
    7464
     
    8878            it != state->allChildren_.end(); ++it)
    8979        {
    90             if (this->checkState(it->second->getName()))
     80            if (this->getState(it->second->getName()))
    9181            {
    9282                ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
     
    9484            }
    9585        }
    96         if (this->checkState(state->name_))
     86        if (this->getState(state->name_))
    9787        {
    9888            ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
     
    10999        for (std::map<std::string, GameState*>::const_iterator it = state->allChildren_.begin();
    110100            it != state->allChildren_.end(); ++it)
    111         {
    112             this->allChildren_[it->second->getName()] = it->second;
    113             this->grandchildrenToChildren_[it->second] = state;
    114             if (this->parent_)
    115                 this->parent_->grandchildAdded(this, it->second);
    116         }
     101            this->grandchildAdded(state, it->second);
    117102        // merge 'state' into this tree
    118         this->allChildren_[state->name_] = state;
    119         this->grandchildrenToChildren_[state] = state;
    120         if (this->parent_)
    121             this->parent_->grandchildAdded(this, state);
     103        this->grandchildAdded(state, state);
    122104
    123105        // mark us as parent
     
    137119        if (it != this->grandchildrenToChildren_.end())
    138120        {
    139             if (state->getOperation().active)
     121            if (state->isInSubtree(getCurrentState()))
    140122            {
    141                 ThrowException(GameState, "Cannot remove active game state child '"
     123                ThrowException(GameState, "Cannot remove an active game state child '"
    142124                    + state->getName() + "' from '" + name_ + "'.");
    143                 //COUT(2) << "Warning: Cannot remove active game state child '" << state->getName()
     125                //COUT(2) << "Warning: Cannot remove an active game state child '" << state->getName()
    144126                //    << "' from '" << name_ << "'." << std::endl;
    145127            }
     
    148130                for (std::map<GameState*, GameState*>::const_iterator it = state->grandchildrenToChildren_.begin();
    149131                    it != state->grandchildrenToChildren_.end(); ++it)
    150                 {
    151132                    this->grandchildRemoved(it->first);
    152                 }
    153133                this->grandchildRemoved(state);
    154134            }
     
    157137        {
    158138            ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '"
    159                 + state->getName() + "'. Removal skipped.");
     139                + state->getName() + "'.");
    160140            //COUT(2) << "Warning: Game state '" << name_ << "' doesn't have a child named '"
    161141            //    << state->getName() << "'. Removal skipped." << std::endl;
     
    173153    void GameState::removeChild(const std::string& name)
    174154    {
    175         GameState* state = checkState(name);
     155        GameState* state = getState(name);
    176156        if (state)
    177157        {
     
    194174        The child that has been added.
    195175    */
    196     void GameState::grandchildAdded(GameState* child, GameState* grandchild)
     176    inline void GameState::grandchildAdded(GameState* child, GameState* grandchild)
    197177    {
    198178        // fill the two maps correctly.
     
    212192        The child that has been removed.
    213193    */
    214     void GameState::grandchildRemoved(GameState* grandchild)
     194    inline void GameState::grandchildRemoved(GameState* grandchild)
    215195    {
    216196        // adjust the two maps correctly.
     
    227207        Remember that the every node has a map with all its child nodes.
    228208    */
    229     GameState* GameState::checkState(const std::string& name)
     209    GameState* GameState::getState(const std::string& name)
    230210    {
    231211        if (this->parent_)
    232             return this->parent_->checkState(name);
     212            return this->parent_->getState(name);
    233213        else
    234214        {
     
    244224    /**
    245225    @brief
     226        Returns the root node of the tree.
     227    */
     228    GameState* GameState::getRoot()
     229    {
     230        if (this->parent_)
     231            return this->parent_->getRoot();
     232        else
     233            return this;
     234    }
     235
     236    /**
     237    @brief
    246238        Returns the current active state.
    247239    @remarks
     
    260252        else
    261253        {
    262             if (this->parent_)
    263                 return this->parent_->getCurrentState();
     254            if (this->getParent())
     255                return this->getParent()->getCurrentState();
    264256            else
    265257                return 0;
     
    269261    /**
    270262    @brief
    271         Returns the root node of the tree.
    272     */
    273     GameState* GameState::getRootNode()
    274     {
    275         if (this->parent_)
    276             return this->parent_->getRootNode();
    277         else
    278             return this;
     263        Determines whether 'state' is in this subtree, including this node.
     264    */
     265    bool GameState::isInSubtree(GameState* state) const
     266    {
     267        return (grandchildrenToChildren_.find(state) != grandchildrenToChildren_.end()
     268                || state == this);
    279269    }
    280270
     
    288278    void GameState::requestState(const std::string& name)
    289279    {
    290         GameState* current = getCurrentState();
    291         if (current != 0 && (current->getOperation().entering || current->getOperation().leaving))
    292         {
    293             ThrowException(GameState, "Making state transitions during enter()/leave() is forbidden.");
    294         }
    295         //if (name == "")
    296         //{
    297         //    // user would like to leave every state.
    298         //    if (current)
    299         //    {
    300         //        // Deactivate all states but root
    301         //        GameState* root = getRootNode();
    302         //        current->makeTransition(root);
    303         //        //// Kick root too
    304         //        //assert(!(root->getOperation().entering || root->getOperation().leaving));
    305         //        //if (root->operation_.running)
    306         //        //    root->scheduledTransition_ = 0;
    307         //        //else
    308         //        //    root->deactivate();
    309         //    }
    310         //}
    311         else
    312         {
    313             GameState* request = checkState(name);
    314             if (request)
    315             {
    316                 if (current)
    317                 {
    318                     // There is already an active state
    319                     current->makeTransition(request);
    320                 }
    321                 else
    322                 {
    323                     // no active state --> we have to activate the root node first.
    324                     GameState* root = getRootNode();
    325                     root->activate();
    326                     root->makeTransition(request);
    327                 }
    328             }
    329             else
    330             {
    331                 COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl;
    332             }
    333         }
     280        assert(getRoot());
     281        getRoot()->requestState(name);
    334282    }
    335283
     
    339287        the method can assume certain things to be granted (like 'this' is always active).
    340288    */
    341     void GameState::makeTransition(GameState* state)
    342     {
    343         // we're always already active
    344         assert(this->operation_.active);
    345 
    346         if (state == this)
     289    void GameState::makeTransition(GameState* source, GameState* destination)
     290    {
     291        if (source == this->getParent())
     292        {
     293            // call is from the parent
     294            this->activate();
     295        }
     296        else if (source == 0)
     297        {
     298            // call was just started by root
     299            // don't do anyting yet
     300        }
     301        else
     302        {
     303            // call is from a child
     304            this->activeChild_ = 0;
     305        }
     306
     307        if (destination == this)
    347308            return;
    348309
    349         // Check for 'state' in the children map first
    350         std::map<GameState*, GameState*>::const_iterator it = this->grandchildrenToChildren_.find(state);
     310        // Check for 'destination' in the children map first
     311        std::map<GameState*, GameState*>::const_iterator it
     312            = this->grandchildrenToChildren_.find(destination);
    351313        if (it != this->grandchildrenToChildren_.end())
    352314        {
    353315            // child state. Don't use 'state', might be a grandchild!
    354             it->second->activate();
    355             it->second->makeTransition(state);
     316            this->activeChild_ = it->second;
     317            it->second->makeTransition(this, destination);
    356318        }
    357319        else
    358320        {
    359321            // parent. We can be sure of this.
    360             assert(this->parent_ != 0);
    361 
    362             // only do the transition if we're not currently running
    363             if (this->operation_.running)
    364             {
    365                 //this->bDeactivationScheduled_ = true;
    366                 this->scheduledTransition_ = state;
    367             }
    368             else
    369             {
    370                 this->deactivate();
    371                 this->parent_->makeTransition(state);
    372             }
    373 
     322            assert(this->getParent() != 0);
     323
     324            this->deactivate();
     325            this->getParent()->makeTransition(this, destination);
    374326        }
    375327    }
     
    381333    void GameState::activate()
    382334    {
    383         if (this->parent_)
    384             this->parent_->activeChild_ = this;
    385335        this->operation_.active = true;
    386336        this->operation_.entering = true;
     
    398348        this->operation_.leaving = false;
    399349        this->operation_.active = false;
    400         if (this->parent_)
    401             this->parent_->activeChild_ = 0;
    402350    }
    403351
     
    411359        This method is not virtual! You cannot override it therefore.
    412360    */
    413     void GameState::tick(float dt)
     361    void GameState::tick(float dt, uint64_t time)
    414362    {
    415363        this->operation_.running = true;
    416         this->ticked(dt);
     364        this->ticked(dt, time);
    417365        this->operation_.running = false;
    418 
    419         if (this->scheduledTransition_)
    420         {
    421             // state was requested to be deactivated when ticked.
    422             this->makeTransition(this->scheduledTransition_);
    423             this->scheduledTransition_ = 0;
    424             this->deactivate();
    425         }
    426     }
    427 
     366    }
    428367}
  • code/branches/gui/src/core/GameState.h

    r1670 r1672  
    4141#include <vector>
    4242#include <map>
     43#include "util/Integers.h"
    4344
    4445namespace orxonox
     
    6061    class _CoreExport GameState
    6162    {
     63        friend class RootGameState;
     64
    6265    public:
     66        /**
     67        @brief
     68            Gives information about what the GameState is currently doing
     69        */
    6370        struct Operations
    6471        {
     
    7077        };
    7178
     79    public:
    7280        GameState(const std::string& name);
    7381        virtual ~GameState();
    7482
    7583        const std::string& getName() const { return name_; }
     84        const Operations getOperation() const { return this->operation_; }
     85        bool isInSubtree(GameState* state) const;
     86
     87        GameState* getState(const std::string& name);
     88        GameState* getRoot();
     89        GameState* getParent() const { return this->parent_; }
     90        //! Returns the currently active game state
     91        virtual GameState* getCurrentState();
     92
     93        virtual void requestState(const std::string& name);
    7694
    7795        void addChild(GameState* state);
    7896        void removeChild(GameState* state);
    7997        void removeChild(const std::string& name);
    80         void requestState(const std::string& name);
    81 
    82         ////! Determines whether the state is active.
    83         //bool isActive()       { return this->bActive_; }
    84         ////! Determines whether the state is suspended.
    85         //bool isSuspended()    { return this->bSuspended_; }
    86         ////! Determines whether the state is the current
    87         //bool isCurrentState() { return this->bActive_ && !this->activeChild_; }
    88         const Operations getOperation() { return this->operation_; }
    89 
    90         void tick(float dt);
    91         void tickChild(float dt) { if (this->activeChild_) this->activeChild_->tick(dt); }
    9298
    9399    protected:
    94100        virtual void enter() = 0;
    95101        virtual void leave() = 0;
    96         virtual void ticked(float dt) = 0;
    97         //virtual void enter() { }
    98         //virtual void leave() { }
    99         //virtual void ticked(float dt) { }
     102        virtual void ticked(float dt, uint64_t time) = 0;
    100103
    101104        GameState* getActiveChild() { return this->activeChild_; }
    102         bool hasScheduledTransition() { return this->scheduledTransition_; }
     105
     106        void tickChild(float dt, uint64_t time) { if (this->getActiveChild()) this->getActiveChild()->tick(dt, time); }
    103107
    104108    private:
    105         GameState* checkState(const std::string& name);
    106         GameState* getCurrentState();
    107         GameState* getRootNode();
     109        //! Performs a transition to 'destination'
     110        virtual void makeTransition(GameState* source, GameState* destination);
     111
    108112        void grandchildAdded(GameState* child, GameState* grandchild);
    109113        void grandchildRemoved(GameState* grandchild);
    110         void makeTransition(GameState* state);
     114
     115        void tick(float dt, uint64_t time);
    111116        void activate();
    112117        void deactivate();
    113118
    114         const std::string                    name_;
    115         bool                                 bPauseParent_;
    116 
    117         Operations                           operation_;
    118 
    119         GameState*                           parent_;
    120         GameState*                           activeChild_;
    121         GameState*                           scheduledTransition_;
    122         std::map<std::string, GameState*>    allChildren_;
    123         std::map<GameState*, GameState*>     grandchildrenToChildren_;
     119        const std::string                          name_;
     120        Operations                                 operation_;
     121        GameState*                             parent_;
     122        GameState*                                 activeChild_;
     123        //bool                                       bPauseParent_;
     124        std::map<std::string, GameState*>      allChildren_;
     125        std::map<GameState*, GameState*>   grandchildrenToChildren_;
    124126    };
    125127}
  • code/branches/gui/src/core/input/InputManager.cc

    r1670 r1672  
    640640
    641641        // check for states to leave
    642         for (std::set<InputState*>::reverse_iterator it = stateLeaveRequests_.rbegin();
    643             it != stateLeaveRequests_.rend(); ++it)
    644         {
    645             (*it)->onLeave();
     642        for (std::set<InputState*>::reverse_iterator rit = stateLeaveRequests_.rbegin();
     643            rit != stateLeaveRequests_.rend(); ++rit)
     644        {
     645            (*rit)->onLeave();
    646646            // just to be sure that the state actually is registered
    647             assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
    648 
    649             activeStates_.erase((*it)->getPriority());
     647            assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
     648
     649            activeStates_.erase((*rit)->getPriority());
    650650            _updateActiveStates();
    651651        }
     
    653653
    654654        // check for states to enter
    655         for (std::set<InputState*>::reverse_iterator it = stateEnterRequests_.rbegin();
    656             it != stateEnterRequests_.rend(); ++it)
     655        for (std::set<InputState*>::reverse_iterator rit = stateEnterRequests_.rbegin();
     656            rit != stateEnterRequests_.rend(); ++rit)
    657657        {
    658658            // just to be sure that the state actually is registered
    659             assert(inputStatesByName_.find((*it)->getName()) != inputStatesByName_.end());
    660 
    661             activeStates_[(*it)->getPriority()] = (*it);
     659            assert(inputStatesByName_.find((*rit)->getName()) != inputStatesByName_.end());
     660
     661            activeStates_[(*rit)->getPriority()] = (*rit);
    662662            _updateActiveStates();
    663             (*it)->onEnter();
     663            (*rit)->onEnter();
    664664        }
    665665        stateEnterRequests_.clear();
    666666
    667667        // check for states to destroy
    668         for (std::set<InputState*>::reverse_iterator it = stateDestroyRequests_.rbegin();
    669             it != stateDestroyRequests_.rend(); ++it)
    670         {
    671             _destroyState((*it));
     668        for (std::set<InputState*>::reverse_iterator rit = stateDestroyRequests_.rbegin();
     669            rit != stateDestroyRequests_.rend(); ++rit)
     670        {
     671            _destroyState((*rit));
    672672        }
    673673
Note: See TracChangeset for help on using the changeset viewer.