/// <summary>Pushes the specified state onto the state stack</summary> /// <param name="state">State that will be pushed onto the stack</param> /// <param name="modality"> /// Behavior of the game state in relation to the state(s) below it on the stack /// </param> public void Push(IGameState state, GameStateModality modality) { Pause(); // If this game state is modal, take all game states that came before it // from the draw and update lists if (modality == GameStateModality.Exclusive) { this.drawableStates.Clear(); this.updateableStates.Clear(); } // Add the new state to the update and draw lists if it implements // the required interfaces this.gameStates.Add(new KeyValuePair <IGameState, GameStateModality>(state, modality)); appendToUpdateableAndDrawableList(state); // State is set, now try to enter it try { state.Enter(); } catch (Exception) { Pop(); throw; } }
/// <summary>Switches the game to the specified state</summary> /// <param name="state">State the game will be switched to</param> /// <param name="modality"> /// Behavior of the game state in relation to the state(s) below it on the stack /// </param> /// <returns>The game state that was replaced on the stack</returns> /// <remarks> /// This replaces the running game state on the stack with the specified state. /// </remarks> public IGameState Switch(IGameState state, GameStateModality modality) { int stateCount = this.gameStates.Count; if (stateCount == 0) { Push(state, modality); return(null); } int lastStateIndex = stateCount - 1; KeyValuePair <IGameState, GameStateModality> old = this.gameStates[lastStateIndex]; IGameState previousState = old.Key; // Notify the previous state that it's being left and kill it if desired previousState.Leave(); disposeIfSupportedAndDesired(previousState); // If the switched-to state is exclusive, we need to clear the update // and draw lists. If not, depending on whether the previous state was // a popup state, we might have to if (old.Value == GameStateModality.Popup) { removeFromUpdateableAndDrawableList(previousState); } else { this.updateableStates.Clear(); this.drawableStates.Clear(); } // Now swap out the state and put it in the update and draw lists. If we're // switching from an exclusive to a pop-up state, the draw and update lists need // to be rebuilt. var newState = new KeyValuePair <IGameState, GameStateModality>(state, modality); this.gameStates[lastStateIndex] = newState; if (old.Value == GameStateModality.Exclusive && modality == GameStateModality.Popup) { rebuildUpdateableAndDrawableListRecursively(lastStateIndex); } else { appendToUpdateableAndDrawableList(state); } // Let the state know that it has been entered state.Enter(); return(previousState); }
public void TestPushModality(GameStateModality modality) { var alwaysObscured = new TestGameState(); var potentiallyObscured = new TestGameState(); var active = new TestGameState(); using (var manager = new GameStateManager()) { manager.Push(alwaysObscured); manager.Push(potentiallyObscured); manager.Push(active, modality); Assert.AreEqual(0, alwaysObscured.UpdateCallCount); Assert.AreEqual(0, alwaysObscured.DrawCallCount); Assert.AreEqual(0, potentiallyObscured.UpdateCallCount); Assert.AreEqual(0, potentiallyObscured.DrawCallCount); Assert.AreEqual(0, active.UpdateCallCount); Assert.AreEqual(0, active.DrawCallCount); manager.Update(new GameTime()); manager.Draw(new GameTime()); Assert.AreEqual(0, alwaysObscured.UpdateCallCount); Assert.AreEqual(0, alwaysObscured.DrawCallCount); if (modality == GameStateModality.Exclusive) { Assert.AreEqual(0, potentiallyObscured.UpdateCallCount); Assert.AreEqual(0, potentiallyObscured.DrawCallCount); } else { Assert.AreEqual(1, potentiallyObscured.UpdateCallCount); Assert.AreEqual(1, potentiallyObscured.DrawCallCount); } Assert.AreEqual(1, active.UpdateCallCount); Assert.AreEqual(1, active.DrawCallCount); } }