Index: code/branches/gui/src/core/GameState.cc
===================================================================
--- code/branches/gui/src/core/GameState.cc	(revision 1670)
+++ code/branches/gui/src/core/GameState.cc	(revision 1672)
@@ -46,11 +46,7 @@
     GameState::GameState(const std::string& name)
         : name_(name)
-        , bPauseParent_(false)
-        //, bActive_(false)
-        //, bSuspended_(false)
-        //, bRunning_(false)
-        , scheduledTransition_(0)
         , parent_(0)
         , activeChild_(0)
+        //, bPauseParent_(false)
     {
         Operations temp = {false, false, false, false, false};
@@ -64,11 +60,5 @@
     GameState::~GameState()
     {
-        if (this->operation_.active)
-        {
-            if (this->parent_)
-                this->requestState(this->parent_->getName());
-            else
-                this->requestState("");
-        }
+        OrxAssert(!isInSubtree(getCurrentState()), "Deleting an active GameState is a very bad idea..");
     }
 
@@ -88,5 +78,5 @@
             it != state->allChildren_.end(); ++it)
         {
-            if (this->checkState(it->second->getName()))
+            if (this->getState(it->second->getName()))
             {
                 ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
@@ -94,5 +84,5 @@
             }
         }
-        if (this->checkState(state->name_))
+        if (this->getState(state->name_))
         {
             ThrowException(GameState, "Cannot add a GameState to the hierarchy twice.");
@@ -109,15 +99,7 @@
         for (std::map<std::string, GameState*>::const_iterator it = state->allChildren_.begin();
             it != state->allChildren_.end(); ++it)
-        {
-            this->allChildren_[it->second->getName()] = it->second;
-            this->grandchildrenToChildren_[it->second] = state;
-            if (this->parent_)
-                this->parent_->grandchildAdded(this, it->second);
-        }
+            this->grandchildAdded(state, it->second);
         // merge 'state' into this tree
-        this->allChildren_[state->name_] = state;
-        this->grandchildrenToChildren_[state] = state;
-        if (this->parent_)
-            this->parent_->grandchildAdded(this, state);
+        this->grandchildAdded(state, state);
 
         // mark us as parent
@@ -137,9 +119,9 @@
         if (it != this->grandchildrenToChildren_.end())
         {
-            if (state->getOperation().active)
+            if (state->isInSubtree(getCurrentState()))
             {
-                ThrowException(GameState, "Cannot remove active game state child '"
+                ThrowException(GameState, "Cannot remove an active game state child '"
                     + state->getName() + "' from '" + name_ + "'.");
-                //COUT(2) << "Warning: Cannot remove active game state child '" << state->getName()
+                //COUT(2) << "Warning: Cannot remove an active game state child '" << state->getName()
                 //    << "' from '" << name_ << "'." << std::endl;
             }
@@ -148,7 +130,5 @@
                 for (std::map<GameState*, GameState*>::const_iterator it = state->grandchildrenToChildren_.begin();
                     it != state->grandchildrenToChildren_.end(); ++it)
-                {
                     this->grandchildRemoved(it->first);
-                }
                 this->grandchildRemoved(state);
             }
@@ -157,5 +137,5 @@
         {
             ThrowException(GameState, "Game state '" + name_ + "' doesn't have a child named '"
-                + state->getName() + "'. Removal skipped.");
+                + state->getName() + "'.");
             //COUT(2) << "Warning: Game state '" << name_ << "' doesn't have a child named '"
             //    << state->getName() << "'. Removal skipped." << std::endl;
@@ -173,5 +153,5 @@
     void GameState::removeChild(const std::string& name)
     {
-        GameState* state = checkState(name);
+        GameState* state = getState(name);
         if (state)
         {
@@ -194,5 +174,5 @@
         The child that has been added.
     */
-    void GameState::grandchildAdded(GameState* child, GameState* grandchild)
+    inline void GameState::grandchildAdded(GameState* child, GameState* grandchild)
     {
         // fill the two maps correctly.
@@ -212,5 +192,5 @@
         The child that has been removed.
     */
-    void GameState::grandchildRemoved(GameState* grandchild)
+    inline void GameState::grandchildRemoved(GameState* grandchild)
     {
         // adjust the two maps correctly.
@@ -227,8 +207,8 @@
         Remember that the every node has a map with all its child nodes.
     */
-    GameState* GameState::checkState(const std::string& name)
+    GameState* GameState::getState(const std::string& name)
     {
         if (this->parent_)
-            return this->parent_->checkState(name);
+            return this->parent_->getState(name);
         else
         {
@@ -244,4 +224,16 @@
     /**
     @brief
+        Returns the root node of the tree.
+    */
+    GameState* GameState::getRoot()
+    {
+        if (this->parent_)
+            return this->parent_->getRoot();
+        else
+            return this;
+    }
+
+    /**
+    @brief
         Returns the current active state.
     @remarks
@@ -260,6 +252,6 @@
         else
         {
-            if (this->parent_)
-                return this->parent_->getCurrentState();
+            if (this->getParent())
+                return this->getParent()->getCurrentState();
             else
                 return 0;
@@ -269,12 +261,10 @@
     /**
     @brief
-        Returns the root node of the tree.
-    */
-    GameState* GameState::getRootNode()
-    {
-        if (this->parent_)
-            return this->parent_->getRootNode();
-        else
-            return this;
+        Determines whether 'state' is in this subtree, including this node.
+    */
+    bool GameState::isInSubtree(GameState* state) const
+    {
+        return (grandchildrenToChildren_.find(state) != grandchildrenToChildren_.end()
+                || state == this);
     }
 
@@ -288,48 +278,6 @@
     void GameState::requestState(const std::string& name)
     {
-        GameState* current = getCurrentState();
-        if (current != 0 && (current->getOperation().entering || current->getOperation().leaving))
-        {
-            ThrowException(GameState, "Making state transitions during enter()/leave() is forbidden.");
-        }
-        //if (name == "")
-        //{
-        //    // user would like to leave every state.
-        //    if (current)
-        //    {
-        //        // Deactivate all states but root
-        //        GameState* root = getRootNode();
-        //        current->makeTransition(root);
-        //        //// Kick root too
-        //        //assert(!(root->getOperation().entering || root->getOperation().leaving));
-        //        //if (root->operation_.running)
-        //        //    root->scheduledTransition_ = 0;
-        //        //else
-        //        //    root->deactivate();
-        //    }
-        //}
-        else
-        {
-            GameState* request = checkState(name);
-            if (request)
-            {
-                if (current)
-                {
-                    // There is already an active state
-                    current->makeTransition(request);
-                }
-                else
-                {
-                    // no active state --> we have to activate the root node first.
-                    GameState* root = getRootNode();
-                    root->activate();
-                    root->makeTransition(request);
-                }
-            }
-            else
-            {
-                COUT(2) << "Warning: GameState '" << name << "' doesn't exist." << std::endl;
-            }
-        }
+        assert(getRoot());
+        getRoot()->requestState(name);
     }
 
@@ -339,37 +287,41 @@
         the method can assume certain things to be granted (like 'this' is always active).
     */
-    void GameState::makeTransition(GameState* state)
-    {
-        // we're always already active
-        assert(this->operation_.active);
-
-        if (state == this)
+    void GameState::makeTransition(GameState* source, GameState* destination)
+    {
+        if (source == this->getParent())
+        {
+            // call is from the parent
+            this->activate();
+        }
+        else if (source == 0)
+        {
+            // call was just started by root
+            // don't do anyting yet
+        }
+        else
+        {
+            // call is from a child
+            this->activeChild_ = 0;
+        }
+
+        if (destination == this)
             return;
 
-        // Check for 'state' in the children map first
-        std::map<GameState*, GameState*>::const_iterator it = this->grandchildrenToChildren_.find(state);
+        // Check for 'destination' in the children map first
+        std::map<GameState*, GameState*>::const_iterator it
+            = this->grandchildrenToChildren_.find(destination);
         if (it != this->grandchildrenToChildren_.end())
         {
             // child state. Don't use 'state', might be a grandchild!
-            it->second->activate();
-            it->second->makeTransition(state);
+            this->activeChild_ = it->second;
+            it->second->makeTransition(this, destination);
         }
         else
         {
             // parent. We can be sure of this.
-            assert(this->parent_ != 0);
-
-            // only do the transition if we're not currently running
-            if (this->operation_.running)
-            {
-                //this->bDeactivationScheduled_ = true;
-                this->scheduledTransition_ = state;
-            }
-            else
-            {
-                this->deactivate();
-                this->parent_->makeTransition(state);
-            }
-
+            assert(this->getParent() != 0);
+
+            this->deactivate();
+            this->getParent()->makeTransition(this, destination);
         }
     }
@@ -381,6 +333,4 @@
     void GameState::activate()
     {
-        if (this->parent_)
-            this->parent_->activeChild_ = this;
         this->operation_.active = true;
         this->operation_.entering = true;
@@ -398,6 +348,4 @@
         this->operation_.leaving = false;
         this->operation_.active = false;
-        if (this->parent_)
-            this->parent_->activeChild_ = 0;
     }
 
@@ -411,18 +359,9 @@
         This method is not virtual! You cannot override it therefore.
     */
-    void GameState::tick(float dt)
+    void GameState::tick(float dt, uint64_t time)
     {
         this->operation_.running = true;
-        this->ticked(dt);
+        this->ticked(dt, time);
         this->operation_.running = false;
-
-        if (this->scheduledTransition_)
-        {
-            // state was requested to be deactivated when ticked.
-            this->makeTransition(this->scheduledTransition_);
-            this->scheduledTransition_ = 0;
-            this->deactivate();
-        }
-    }
-
+    }
 }
