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
File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.