public void changeState(BaseGameState state, Transition out, Transition in) {
    if (state == null) {
      throw new IllegalArgumentException("State must not be null!");
    }

    if (isTransitioning()) {
      if (leaving != null) {
        completeLeave();
      }
      if (entering != null) {
        completeEnter();
      }
    }

    leaving = out;
    entering = in;

    nextState = state;

    currentState.onLeave(nextState);
    nextState.onEnter(currentState);

    if (leaving == null) {
      completeLeave();
    }
  }
 private void completeEnter() {
   if (!persistentStates.containsValue(prevState)) {
     prevState.dispose();
   }
   currentState.onEnterComplete();
   prevState = null;
   entering = null;
 }
 public void addPersistentState(BaseGameState state) {
   if (state == null) {
     throw new IllegalArgumentException("State must not be null!");
   }
   if (persistentStates.containsKey(state.getClass())) {
     throw new IllegalStateException("A state of that class has already been added!");
   }
   persistentStates.put(state.getClass(), state);
 }
  @Override
  public final void render() {
    long time = System.currentTimeMillis();
    float delta = (time - lastTime) * 0.001f;
    lastTime = time;

    preUpdate(delta);

    updateTransitions(delta);

    if (leaving != null) {
      if (leaving.isReverse()) {
        leaving.render(delta, screenCamera, nextState, currentState);
      } else {
        leaving.render(delta, screenCamera, currentState, nextState);
      }
    } else if (entering != null) {
      if (entering.isReverse()) {
        entering.render(delta, screenCamera, prevState, currentState);
      } else {
        entering.render(delta, screenCamera, currentState, prevState);
      }
    } else {
      currentState.update(delta);
    }

    postUpdate(delta);
  }
  private void completeLeave() {
    currentState.onLeaveComplete();
    prevState = currentState;
    currentState = nextState;
    nextState = null;
    leaving = null;

    if (entering == null) {
      completeEnter();
    }
  }