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); }
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); }