Exemple #1
0
        private IEnumerator ChangeToNewStateRoutine(StateMapping newState)
        {
            _destinationState = newState; //Chache this so that we can overwrite it and hijack a transition

            if (CurrentStateMap != null)
            {
                if (CurrentStateMap.HasExitRoutine)
                {
                    _exitRoutine = CurrentStateMap.ExitRoutine();

                    if (_exitRoutine != null) //Don't wait for exit if we are overwriting
                    {
                        yield return(_engine.StartCoroutine(_exitRoutine));
                    }

                    _exitRoutine = null;
                }
                else
                {
                    CurrentStateMap.ExitCall();
                }

                CurrentStateMap.Finally();
            }

            _lastState      = CurrentStateMap;
            CurrentStateMap = _destinationState;

            if (CurrentStateMap != null)
            {
                if (CurrentStateMap.HasEnterRoutine)
                {
                    _enterRoutine = CurrentStateMap.EnterRoutine();

                    if (_enterRoutine != null)
                    {
                        yield return(_engine.StartCoroutine(_enterRoutine));
                    }

                    _enterRoutine = null;
                }
                else
                {
                    CurrentStateMap.EnterCall();
                }

                //Broadcast change only after enter transition has begun.
                if (Changed != null)
                {
                    Changed((T)CurrentStateMap.State);
                }
            }

            _isInTransition = false;
        }
Exemple #2
0
        public void ChangeState(T newState)
        {
            if (_stateLookup == null)
            {
                throw new Exception(
                          "States have not been configured, please call initialized before trying to set state");
            }
            if (!_stateLookup.ContainsKey(newState))
            {
                throw new Exception("No state with the name " + newState +
                                    " can be found. Please make sure you are called the correct type the statemachine was initialized with");
            }

            var nextState = _stateLookup[newState];

            if (CurrentStateMap == nextState)
            {
                return;
            }

            //Cancel any queued changes.
            if (_queuedChange != null)
            {
                _engine.StopCoroutine(_queuedChange);
                _queuedChange = null;
            }

            if (_isInTransition)
            {
                if (_exitRoutine != null) //We are already exiting current state on our way to our previous target state
                {
                    //Overwrite with our new target
                    _destinationState = nextState;
                    return;
                }
                if (_enterRoutine != null)
                //We are already entering our previous target state. Need to wait for that to finish and call the exit routine.
                {
                    //Damn, I need to test this hard
                    _queuedChange = WaitForPreviousTransition(nextState);
                    _engine.StartCoroutine(_queuedChange);
                    return;
                }
            }

            if ((CurrentStateMap != null && CurrentStateMap.HasExitRoutine) || nextState.HasEnterRoutine)
            {
                _isInTransition    = true;
                _currentTransition = ChangeToNewStateRoutine(nextState);
                _engine.StartCoroutine(_currentTransition);
            }
            else
            {
                if (CurrentStateMap != null)
                {
                    CurrentStateMap.ExitCall();
                    CurrentStateMap.Finally();
                }

                _lastState      = CurrentStateMap;
                CurrentStateMap = nextState;
                if (CurrentStateMap != null)
                {
                    CurrentStateMap.EnterCall();
                    if (Changed != null)
                    {
                        Changed((T)CurrentStateMap.State);
                    }
                }
                _isInTransition = false;
            }
        }