Android Open Source - droidengine2d Game State Manager






From Project

Back to project page droidengine2d.

License

The source code is released under:

Apache License

If you think the Android project droidengine2d listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*   Copyright 2013-2014 Miguel Vicente Linares
 */*from  www.j  a  v  a2 s.  c  o  m*/
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.miviclin.droidengine2d.gamestate;

import java.util.ArrayList;
import java.util.Stack;

import android.util.SparseArray;

import com.miviclin.droidengine2d.AbstractGame;
import com.miviclin.droidengine2d.graphics.Graphics;

/**
 * GameStateManager.
 * 
 * @author Miguel Vicente Linares
 * 
 */
public class GameStateManager {

  private SparseArray<GameState> gameStatesRegistry;
  private Stack<GameState> activeGameStates;
  private ArrayList<OnGameStateChangeListener> onGameStateChangeListeners;

  /**
   * Constructor.
   */
  public GameStateManager() {
    this(16);
  }

  /**
   * Constructor.
   * 
   * @param initialCapacity Initial capacity for GameStates. If this capacity is reached, the data structure that
   *            holds the GameStates will be resized automatically.
   */
  public GameStateManager(int initialCapacity) {
    this.gameStatesRegistry = new SparseArray<GameState>(initialCapacity);
    this.activeGameStates = new Stack<GameState>();
    this.onGameStateChangeListeners = new ArrayList<OnGameStateChangeListener>();
  }

  /**
   * Registers a GameState in this GameStateManager using the specified gameStateId.<br>
   * If a GameState with the specified gameStateId was previously registered in this GameStateManager, it will be
   * replaced by the new one.
   * 
   * @param gameStateId Identifier of the GameState. It can be used to get the GameState from this GameStateManager
   *            later.
   * @param gameState GameState (can not be null).
   */
  public void registerGameState(int gameStateId, GameState gameState) {
    registerGameState(gameStateId, gameState, false);
  }

  /**
   * Registers a GameState in this GameStateManager using the specified gameStateId.<br>
   * If a GameState with the specified gameStateId was previously registered in this GameStateManager, it will be
   * replaced by the new one.
   * 
   * @param gameStateId Identifier of the GameState. It can be used to get the GameState from this GameStateManager
   *            later.
   * @param gameState GameState (can not be null).
   * @param push true to push the GameState onto the stack of active GameStates of this GameStateManager.
   */
  public void registerGameState(int gameStateId, GameState gameState, boolean push) {
    if (gameState == null) {
      throw new IllegalArgumentException("The GameState can not be null");
    }
    gameStatesRegistry.put(gameStateId, gameState);
    gameState.onRegister();
    if (push) {
      pushActiveGameState(gameStateId);
    }
  }

  /**
   * Unregisters the specified GameState from this GameStateManager.<br>
   * If a GameState was registered with the specified gameStateId, {@link GameState#dispose()} is called on the
   * GameState before it is removed from this GameStateManager.<br>
   * If the specified GameState is in the stack of active GameStates it should be removed from the stack first,
   * otherwise an exception will be thrown.
   * 
   * @param gameStateId Identifier of the GameState.
   * @return Removed GameState or null
   */
  public GameState unregisterGameState(int gameStateId) {
    GameState gameState = gameStatesRegistry.get(gameStateId);
    if (gameState == null) {
      return null;
    }
    int indexInStack = activeGameStates.search(gameState);
    if (indexInStack >= 0) {
      throw new IllegalStateException("The GameState registered with the gameStateId " + gameStateId + " is " +
          "currently in the stack of active GameStates. It should be removed from the stack of active " +
          "GameStates before unregistering it from this GameStateManager.");
    }
    gameState.dispose();
    gameStatesRegistry.remove(gameStateId);
    return gameState;
  }

  /**
   * Returns the GameState registered with the specified gameStateId.
   * 
   * @param gameStateId Identifier of the GameState.
   * @return GameState or null
   */
  public GameState getGameState(int gameStateId) {
    return gameStatesRegistry.get(gameStateId);
  }

  /**
   * Replaces the GameState at the top of the stack of active GameStates of this GameStateManager with the specified
   * GameState.<br>
   * The GameState must have been previously registered with the specified gameStateId.<br>
   * This method notifies every {@link OnGameStateChangeListener} registered in this GameStateManager that the
   * GameState at the top of the stack of active GameStates has changed.
   * 
   * @param gameStateId Identifier of the GameState we want to set as the active GameState.
   */
  public void switchActiveGameState(int gameStateId) {
    GameState previousTopGameState = popActiveGameStateOffStack();
    GameState currentTopGameState = pushActiveGameStateOntoStack(gameStateId);
    dispatchOnGameStateChangeEvent(previousTopGameState, currentTopGameState);
  }

  /**
   * Returns the GameState at the top of the stack of active GameStates of this GameStateManager.
   * 
   * @return GameState or null
   */
  public GameState peekActiveGameState() {
    if (activeGameStates.empty()) {
      return null;
    }
    return activeGameStates.peek();
  }

  /**
   * Pushes the GameState onto the stack of active GameStates of this GameStateManager.<br>
   * The GameState must have been previously registered with the specified gameStateId.<br>
   * This method notifies every {@link OnGameStateChangeListener} registered in this GameStateManager that the
   * GameState at the top of the stack of active GameStates has changed.
   * 
   * @param gameStateId Identifier of the GameState we want to set as the active GameState.
   */
  public void pushActiveGameState(int gameStateId) {
    GameState previousTopGameState = peekActiveGameState();
    GameState currentTopGameState = pushActiveGameStateOntoStack(gameStateId);
    dispatchOnGameStateChangeEvent(previousTopGameState, currentTopGameState);
  }

  /**
   * Pushes the GameState onto the stack of active GameStates of this GameStateManager.<br>
   * The GameState must have been previously registered with the specified gameStateId.<br>
   * This method does not call {@link #dispatchOnGameStateChangeEvent(GameState, GameState)}.
   * 
   * @param gameStateId Identifier of the GameState we want to set as the active GameState.
   * @return The GameState pushed onto the stack of active GameStates
   */
  private GameState pushActiveGameStateOntoStack(int gameStateId) {
    GameState gameState = gameStatesRegistry.get(gameStateId);
    if (gameState == null) {
      throw new GameStateNotRegisteredException(gameStateId);
    }
    activeGameStates.push(gameState);
    gameState.onActivation();
    return gameState;
  }

  /**
   * Pops 1 GameState off the stack of active GameStates of this GameStateManager. Also calls
   * {@link GameState#onDeactivation()} on the GameState popped off the stack.<br>
   * This method notifies every {@link OnGameStateChangeListener} registered in this GameStateManager that the
   * GameState at the top of the stack of active GameStates has changed.
   */
  public void popActiveGameState() {
    popActiveGameStates(1);
  }

  /**
   * Pops the specified number of GameStates off the stack of active GameStates of this GameStateManager. Also calls
   * {@link GameState#onDeactivation()} on all the GameStates popped off the stack.<br>
   * This method notifies every {@link OnGameStateChangeListener} registered in this GameStateManager that the
   * GameState at the top of the stack of active GameStates has changed.
   * 
   * @param numGameStatesToPop Number of GameStates that will be popped off the stack of active GameStates.
   */
  public void popActiveGameStates(int numGameStatesToPop) {
    for (int i = 0; ((i < numGameStatesToPop) && !activeGameStates.empty()); i++) {
      GameState previousGameState = popActiveGameStateOffStack();
      GameState currentGameState = peekActiveGameState();
      dispatchOnGameStateChangeEvent(previousGameState, currentGameState);
    }
  }

  /**
   * Pops all GameStates off the stack of active GameStates of this GameStateManager.<br>
   * This method notifies every {@link OnGameStateChangeListener} registered in this GameStateManager that the
   * GameState at the top of the stack of active GameStates has changed.
   * 
   * @see #popActiveGameStates(int)
   */
  public void popAllActiveGameStates() {
    int numGameStatesToPop = activeGameStates.size();
    popActiveGameStates(numGameStatesToPop);
  }

  /**
   * Pops 1 GameState off the stack of active GameStates of this GameStateManager. Also calls
   * {@link GameState#onDeactivation()} on the GameState popped off the stack.<br>
   * This method does not call {@link #dispatchOnGameStateChangeEvent(GameState, GameState)}.
   * 
   * @return The removed GameState or null
   */
  private GameState popActiveGameStateOffStack() {
    GameState gameState = null;
    if (!activeGameStates.empty()) {
      gameState = activeGameStates.pop();
      gameState.onDeactivation();
    }
    return gameState;
  }

  /**
   * Notifies all listeners that the GameState at the top of the stack of active GameStates has changed.
   * 
   * @param previousGameState Previous GameState at the top of the stack or null if the stack was empty.
   * @param currentGameState Current GameState at the top of the stack or null if the stack is empty.
   */
  private void dispatchOnGameStateChangeEvent(GameState previousTopGameState, GameState currentTopGameState) {
    for (int i = 0; i < onGameStateChangeListeners.size(); i++) {
      onGameStateChangeListeners.get(i).onGameStateChange(previousTopGameState, currentTopGameState);
    }
  }

  /**
   * Adds an OnGameStateChangeListener that will be notified when the active GameState of this GameStateManager
   * changes.
   * 
   * @param listener Listener to be added.
   */
  public void addOnGameStateChangeListener(OnGameStateChangeListener listener) {
    onGameStateChangeListeners.add(listener);
  }

  /**
   * Removes an OnGameStateChangeListener from the list of listeners. The removed listener will not be notified
   * anymore when the active GameState of this GameStateManager changes.
   * 
   * @param listener Listener to be removed.
   */
  public void removeOnGameStateChangeListener(OnGameStateChangeListener listener) {
    onGameStateChangeListeners.remove(listener);
  }

  /**
   * This method is called when the engine is paused, usually when the activity goes to background.<br>
   * Calls {@link GameState#onPause()} on all the active GameStates.
   */
  public void pause() {
    for (int i = 0; i < activeGameStates.size(); i++) {
      activeGameStates.get(i).onPause();
    }
  }

  /**
   * This method is called when the engine is resumed, usually when the activity comes to foreground.<br>
   * Calls {@link GameState#onResume()} on the active GameState.
   */
  public void resume() {
    for (int i = 0; i < activeGameStates.size(); i++) {
      activeGameStates.get(i).onResume();
    }
  }

  /**
   * Clears the stack of active GameStates calling {@link #popAllActiveGameStates()} and calls
   * {@link GameState#dispose()} on all GameStates registered in this GameStateManager and removes them from the
   * GameStateManager.<br>
   * This GameStateManager will be left empty.
   */
  public void dispose() {
    popAllActiveGameStates();
    int numGameStates = gameStatesRegistry.size();
    for (int i = 0; i < numGameStates; i++) {
      GameState gameState = gameStatesRegistry.valueAt(i);
      if (gameState != null) {
        gameState.dispose();
      }
    }
    gameStatesRegistry.clear();
  }

  /**
   * Calls {@link GameState#update(float)} on the GameState at the top of the stack of active GameStates.<br>
   * This method is called from {@link AbstractGame#update(float)}.
   * 
   * @param delta Elapsed time, in milliseconds, since the last update.
   */
  public void update(float delta) {
    GameState gameState = peekActiveGameState();
    if (gameState != null) {
      gameState.getGameStateInputManager().processInput();
      gameState.update(delta);
    }
  }

  /**
   * Calls {@link GameState#draw(Graphics)} on all the GameStates in the stack of active GameStates.<br>
   * This method is called from {@link AbstractGame#draw(Graphics)}.<br>
   * This method is called from the redering thread after {@link GameStateManager#update(float)} has been executed in
   * the game thread.
   */
  public void draw(Graphics graphics) {
    for (int i = 0; i < activeGameStates.size(); i++) {
      GameState gameState = activeGameStates.get(i);
      gameState.draw(graphics);
    }
  }

}




Java Source Code List

com.miviclin.droidengine2d.AbstractGame.java
com.miviclin.droidengine2d.EngineActivity.java
com.miviclin.droidengine2d.EngineLock.java
com.miviclin.droidengine2d.Engine.java
com.miviclin.droidengine2d.GameThread.java
com.miviclin.droidengine2d.Game.java
com.miviclin.droidengine2d.audio.MusicPlayer.java
com.miviclin.droidengine2d.audio.SoundManager.java
com.miviclin.droidengine2d.gamestate.GameStateAdapter.java
com.miviclin.droidengine2d.gamestate.GameStateManager.java
com.miviclin.droidengine2d.gamestate.GameStateNotRegisteredException.java
com.miviclin.droidengine2d.gamestate.GameState.java
com.miviclin.droidengine2d.gamestate.OnGameStateChangeListener.java
com.miviclin.droidengine2d.graphics.Color.java
com.miviclin.droidengine2d.graphics.DefaultRenderer.java
com.miviclin.droidengine2d.graphics.EngineRenderer.java
com.miviclin.droidengine2d.graphics.GLDebugger.java
com.miviclin.droidengine2d.graphics.GLRenderer.java
com.miviclin.droidengine2d.graphics.GLView.java
com.miviclin.droidengine2d.graphics.Graphics.java
com.miviclin.droidengine2d.graphics.animation.AnimationFrame.java
com.miviclin.droidengine2d.graphics.animation.AnimationStateAdapter.java
com.miviclin.droidengine2d.graphics.animation.AnimationStateListener.java
com.miviclin.droidengine2d.graphics.animation.Animation.java
com.miviclin.droidengine2d.graphics.cameras.Camera.java
com.miviclin.droidengine2d.graphics.cameras.OrthographicCamera.java
com.miviclin.droidengine2d.graphics.material.BlendingOptions.java
com.miviclin.droidengine2d.graphics.material.ColorMaterial.java
com.miviclin.droidengine2d.graphics.material.Material.java
com.miviclin.droidengine2d.graphics.material.TextureColorMaterial.java
com.miviclin.droidengine2d.graphics.material.TextureHsvMaterial.java
com.miviclin.droidengine2d.graphics.material.TextureMaterial.java
com.miviclin.droidengine2d.graphics.material.TransparentTextureMaterial.java
com.miviclin.droidengine2d.graphics.material.UnsupportedMaterialException.java
com.miviclin.droidengine2d.graphics.mesh.ColorMaterialBatchRenderer.java
com.miviclin.droidengine2d.graphics.mesh.Geometry.java
com.miviclin.droidengine2d.graphics.mesh.GraphicsBatchRenderer.java
com.miviclin.droidengine2d.graphics.mesh.RectangleBatchGeometry.java
com.miviclin.droidengine2d.graphics.mesh.RectangleBatchRenderer.java
com.miviclin.droidengine2d.graphics.mesh.TextureColorMaterialBatchRenderer.java
com.miviclin.droidengine2d.graphics.mesh.TextureHsvMaterialBatchRenderer.java
com.miviclin.droidengine2d.graphics.mesh.TextureMaterialBatchRendererBase.java
com.miviclin.droidengine2d.graphics.mesh.TextureMaterialBatchRenderer.java
com.miviclin.droidengine2d.graphics.mesh.TransparentTextureMaterialBatchRenderer.java
com.miviclin.droidengine2d.graphics.shader.ShaderProgramException.java
com.miviclin.droidengine2d.graphics.shader.ShaderProgram.java
com.miviclin.droidengine2d.graphics.shader.ShaderVars.java
com.miviclin.droidengine2d.graphics.text.BitmapFont.java
com.miviclin.droidengine2d.graphics.text.FontChar.java
com.miviclin.droidengine2d.graphics.text.Font.java
com.miviclin.droidengine2d.graphics.text.UndefinedCharacterException.java
com.miviclin.droidengine2d.graphics.texture.TextureAtlas.java
com.miviclin.droidengine2d.graphics.texture.TextureManager.java
com.miviclin.droidengine2d.graphics.texture.TexturePackerAtlas.java
com.miviclin.droidengine2d.graphics.texture.TextureRegion.java
com.miviclin.droidengine2d.graphics.texture.Texture.java
com.miviclin.droidengine2d.input.DefaultKeyEventProcessor.java
com.miviclin.droidengine2d.input.GameInputManager.java
com.miviclin.droidengine2d.input.GameStateInputManager.java
com.miviclin.droidengine2d.input.KeyEventInfo.java
com.miviclin.droidengine2d.input.KeyEventProcessor.java
com.miviclin.droidengine2d.input.KeyProcessor.java
com.miviclin.droidengine2d.input.MotionEventProcessor.java
com.miviclin.droidengine2d.input.TouchProcessor.java
com.miviclin.droidengine2d.input.sensor.AccelerometerValuesListener.java
com.miviclin.droidengine2d.input.sensor.Accelerometer.java
com.miviclin.droidengine2d.input.sensor.SensorUtilities.java
com.miviclin.droidengine2d.resources.AssetsLoader.java
com.miviclin.droidengine2d.util.ActivityUtilities.java
com.miviclin.droidengine2d.util.MutexLock.java
com.miviclin.droidengine2d.util.PrimitiveTypeSize.java
com.miviclin.droidengine2d.util.TransformUtilities.java
com.miviclin.droidengine2d.util.Transform.java
com.miviclin.droidengine2d.util.math.Matrix4.java
com.miviclin.droidengine2d.util.math.MatrixFix.java
com.miviclin.droidengine2d.util.math.Vector2.java
com.miviclin.droidengine2d.util.math.Vector3.java
com.miviclin.droidengine2d.util.time.TimeConstants.java
com.miviclin.droidengine2d.util.time.TimeCounter.java