private StateTransitionResult <TState, TTrigger> executeExitAndEntryActions(ExecutionParameters <T, TTrigger> parameters
                                                                                    , StateTransitionResult <TState, TTrigger> currentResult)
        {
            if (currentResult.WasTransitioned &&
                !(currentResult.StartingState.CompareTo(currentResult.PreviousState) == 0 &&
                  currentResult.PreviousState.CompareTo(currentResult.CurrentState) == 0))
            {
                _stateConfigurations.TryGetValue(currentResult.PreviousState, out var previousState);

                //OnExit? ...don't execute if moving to substate
                if (!IsInState(parameters.Context, currentResult.PreviousState))
                {
                    previousState.ExecuteExitAction(parameters.Context, currentResult);
                }

                if (_stateConfigurations.TryGetValue(currentResult.CurrentState, out var newState))
                {
                    //OnEntry? ...don't execute if moving to superstate
                    if (!previousState.IsInState(currentResult.CurrentState))
                    {
                        newState.ExecuteEntryAction(parameters.Context, currentResult);
                    }

                    //Auto transitions?
                    var preAutoForwardState  = currentResult.CurrentState;
                    var autoTransitionResult = newState.ExecuteAutoTransition(parameters, currentResult);
                    if (autoTransitionResult.WasTransitioned)
                    {
                        //Merge the results
                        currentResult.PreviousState      = currentResult.CurrentState;
                        currentResult.CurrentState       = autoTransitionResult.CurrentState;
                        currentResult.LastTransitionName = autoTransitionResult.LastTransitionName;
                    }

                    //See if we have more actions from the auto transition
                    if (currentResult.CurrentState.CompareTo(preAutoForwardState) != 0)
                    {
                        currentResult = executeExitAndEntryActions(parameters, currentResult);
                    }
                }
            }
            //Reentry?
            else if (_stateConfigurations.TryGetValue(currentResult.CurrentState, out var reenteredState))
            {
                reenteredState.ExecuteReentryAction(parameters.Context, currentResult);
            }

            //Send notifications
            var transitionEventArgs = new TransitionEventArgs <T, TState, TTrigger>(parameters, currentResult);

            if (!currentResult.WasTransitioned)
            {
                if (!currentResult.TransitionDefined)
                {
                    OnTriggerNotConfigured?.Invoke(this, transitionEventArgs);
                }

                OnNoTransition?.Invoke(this, transitionEventArgs);
            }

            return(currentResult);
        }
Beispiel #2
0
        private async Task <StateTransitionResult <TState, TTrigger> > executeExitAndEntryActionsAsync(ExecutionParameters <T, TTrigger> parameters, StateTransitionResult <TState, TTrigger> currentResult)
        {
            var currentState = StateAccessor(parameters.Context);

            if (currentResult.WasTransitioned && !currentState.Equals(currentResult.StartingState))
            {
                _stateConfigurations.TryGetValue(currentResult.PreviousState, out var previousState);

                //OnExit? ...don't execute if moving to substate
                if (!IsInState(parameters.Context, currentResult.PreviousState))
                {
                    await previousState.ExecuteExitActionAsync(parameters, currentResult)
                    .ConfigureAwait(continueOnCapturedContext: false);
                }

                if (_stateConfigurations.TryGetValue(currentResult.CurrentState, out var newState))
                {
                    //OnEntry? ...don't execute if moving to superstate
                    if (!previousState.IsInState(currentResult.CurrentState))
                    {
                        await newState.ExecuteEntryActionAsync(parameters, currentResult)
                        .ConfigureAwait(continueOnCapturedContext: false);
                    }

                    //AutoForward?
                    var preAutoForwardState  = currentResult.CurrentState;
                    var autoTransitionResult = await newState.ExecuteAutoTransitionAsync(parameters, currentResult)
                                               .ConfigureAwait(continueOnCapturedContext: false);

                    if (autoTransitionResult.WasTransitioned)
                    {
                        //Merge the results
                        currentResult.PreviousState      = currentResult.CurrentState;
                        currentResult.CurrentState       = autoTransitionResult.CurrentState;
                        currentResult.LastTransitionName = autoTransitionResult.LastTransitionName;
                    }

                    //See if we have more actions from the auto transition
                    if (preAutoForwardState.CompareTo(currentResult.CurrentState) != 0)
                    {
                        await executeExitAndEntryActionsAsync(parameters, currentResult)
                        .ConfigureAwait(continueOnCapturedContext: false);
                    }
                }
            }
            //Reentry?
            else if (_stateConfigurations.TryGetValue(currentResult.CurrentState, out var reenteredState))
            {
                await reenteredState.ExecuteReentryActionAsync(parameters, currentResult)
                .ConfigureAwait(continueOnCapturedContext: false);
            }

            //Send notifications
            var transitionEventArgs = new TransitionEventArgs <T, TState, TTrigger>(parameters, currentResult);

            if (!currentResult.WasTransitioned)
            {
                if (!currentResult.TransitionDefined)
                {
                    OnTriggerNotConfigured?.Invoke(this, transitionEventArgs);
                }

                OnNoTransition?.Invoke(this, transitionEventArgs);
            }

            return(currentResult);
        }