public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters, StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (!(parameters.Request is TParam typeSafeParam))
            {
                throw new ArgumentException($"Expected a {typeof(TParam).Name} parameter, but received a {parameters.Request?.GetType().Name ?? "null"}.");
            }

            var startState = currentResult != null ? currentResult.StartingState : StateAccessor(parameters.Context);
            var toState    = StateFunc(parameters.Context, typeSafeParam);

            var transitioned = !toState.IsEqual(startState);

            if (transitioned)
            {
                StateMutator(parameters.Context, toState);
            }

            var transitionResult = GetFreshResult(parameters, currentResult, startState, transitionDefined: true, wasCancelled: false, conditionMet: transitioned);

            if (transitioned)
            {
                NotifyOfTransition(parameters.Context, transitionResult);
            }

            return(transitionResult);
        }
Esempio n. 2
0
        public StateTransitionResult <TState, TTrigger> ExecuteAutoTransition(ExecutionParameters <T, TTrigger> parameters
                                                                              , StateTransitionResult <TState, TTrigger> currentResult)
        {
            if (AutoTransitions.TryGetValue(parameters.Trigger, out var autoTransitions))
            {
                foreach (var transition in autoTransitions.OrderBy(t => t.Priority))
                {
                    var localResult = transition.Execute(parameters, currentResult);
                    if (localResult.WasTransitioned)
                    {
                        return(localResult);
                    }
                }
            }

            //Check for a super state and just return the incoming currentResult if no successful auto transitions
            return(_superState != null
                ? _superState.ExecuteAutoTransition(parameters, currentResult)
                : new StateTransitionResult <TState, TTrigger>(parameters.Trigger
                                                               , currentResult.CurrentState
                                                               , currentResult.CurrentState
                                                               , currentResult.CurrentState
                                                               , string.Empty
                                                               , transitionDefined: false
                                                               , conditionMet: false));
        }
Esempio n. 3
0
        public async Task ExecuteExitActionAsync(ExecutionParameters <T, TTrigger> parameters
                                                 , StateTransitionResult <TState, TTrigger> currentResult)
        {
            //Is there an action based on the new state?
            if (_nextStateExitActions.TryGetValue(currentResult.CurrentState, out var action))
            {
                if (parameters.CancellationToken.IsCancellationRequested)
                {
                    return;
                }

                await action.Invoke(parameters.Context, parameters.CancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false);
            }

            //Is there an action for any exit?
            if (_defaultExitAction != null)
            {
                if (parameters.CancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (_defaultExitAction != null)
                {
                    await _defaultExitAction.Invoke(parameters.Context, parameters.CancellationToken)
                    .ConfigureAwait(continueOnCapturedContext: false);
                }
            }
        }
Esempio n. 4
0
        public StateTransitionResult <TState, TTrigger> FireTrigger(ExecutionParameters <T, TTrigger> parameters)
        {
            if (_triggerActions.TryGetValue(parameters.Trigger, out var triggerAction))
            {
                triggerAction.Execute(parameters);
            }

            var result = FireTriggerPrim(parameters);

            if (!(result?.WasTransitioned ?? false) && _superState != null)
            {
                result = _superState.FireTrigger(parameters);
            }
            else
            {
                var startState = StateAccessor(parameters.Context);
                result = result ??
                         new StateTransitionResult <TState, TTrigger>(parameters.Trigger
                                                                      , startState
                                                                      , startState
                                                                      , startState
                                                                      , string.Empty
                                                                      , transitionDefined: false);
            }

            return(result);
        }
Esempio n. 5
0
        /// <summary>
        /// Executes trigger asynchronously with a <see cref="TRequest"/> parameter.
        /// </summary>
        /// <param name="context">The items whose state is being managed.</param>
        /// <param name="trigger">The event that has occured that may affect the state.</param>
        /// <param name="request">The details of the event that's occurring.</param>
        /// <param name="cancellationToken"><see cref="CancellationToken"/>Provides the ability to cancel an asynchronous operation.</param>
        /// <returns></returns>
        public async Task <StateTransitionResult <TState, TTrigger> > FireTriggerAsync <TRequest>(T context
                                                                                                  , TTrigger trigger
                                                                                                  , TRequest request
                                                                                                  , CancellationToken cancellationToken = default(CancellationToken))
            where TRequest : class
        {
            var startState = StateAccessor(context);

            if (_triggerActions.TryGetValue(trigger, out var triggerAction))
            {
                await triggerAction.ExecuteAsync(context, cancellationToken, request).ConfigureAwait(continueOnCapturedContext: false);
            }

            var executionParameters = new ExecutionParameters <T, TTrigger>(trigger, context, cancellationToken, request);

            StateTransitionResult <TState, TTrigger> result;

            if (!_stateConfigurations.TryGetValue(startState, out var stateConfiguration))
            {
                result = new StateTransitionResult <TState, TTrigger>(trigger
                                                                      , startState
                                                                      , startState
                                                                      , startState
                                                                      , lastTransitionName: string.Empty
                                                                      , transitionDefined: false);
            }
            else
            {
                result = await stateConfiguration.FireTriggerAsync(executionParameters).ConfigureAwait(continueOnCapturedContext: false);
            }

            return(await executeExitAndEntryActionsAsync(executionParameters, result).ConfigureAwait(continueOnCapturedContext: false));
        }
        public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters
                                                                         , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (currentResult != null &&
                _startState.IsEqual(currentResult.PreviousState) &&
                (_triggerState.IsEqual(currentResult.CurrentState) ||
                 _stateMachine.IsInState(parameters.Context, _triggerState)))
            {
                StateMutator(parameters.Context, _stateFunction.Invoke(parameters.Context));

                var transitioned = !StateAccessor(parameters.Context).IsEqual(_triggerState);
                var result       = GetFreshResult(parameters
                                                  , currentResult
                                                  , currentResult.StartingState
                                                  , wasCancelled: false
                                                  , transitionDefined: true
                                                  , conditionMet: transitioned);
                if (transitioned)
                {
                    NotifyOfTransition(parameters.Context, result);
                }

                return(result);
            }

            return(GetFreshResult(parameters
                                  , currentResult
                                  , StateAccessor(parameters.Context)
                                  , wasCancelled: false
                                  , conditionMet: false
                                  , transitionDefined: true));
        }
Esempio n. 7
0
        public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters
                                                                         , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (!(parameters.Request is TParam typeSafeParam))
            {
                throw new ArgumentException($"Expected a {typeof(TParam).Name} parameter, but received a {parameters.Request?.GetType().Name ?? "null"}.");
            }

            return(ExecutePrim(parameters, currentResult, Condition(parameters.Context, typeSafeParam)));
        }
Esempio n. 8
0
        public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters, StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            var startState = currentResult != null ? currentResult.StartingState : StateAccessor(parameters.Context);
            var toState    = StateFunc(parameters.Context);

            StateMutator(parameters.Context, toState);

            var transitioned     = !StateAccessor(parameters.Context).IsEqual(startState);
            var transitionResult = GetFreshResult(parameters, currentResult, startState, wasCancelled: false, transitionDefined: true, conditionMet: transitioned);

            return(transitionResult);
        }
        internal override void Execute(ExecutionParameters <T, TTrigger> parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            if (!(parameters.Request is TRequest typedRequestType))
            {
                throw new ArgumentException($"{nameof(parameters.Request)} must be of type {typeof(TRequest).Name}.");
            }

            Action.Invoke(parameters.Context, typedRequestType);
        }
Esempio n. 10
0
        public async Task ExecuteReentryActionAsync(ExecutionParameters <T, TTrigger> parameters, StateTransitionResult <TState, TTrigger> currentResult)
        {
            if (_superState != null)
            {
                await _superState.ExecuteReentryActionAsync(parameters, currentResult)
                .ConfigureAwait(continueOnCapturedContext: false);
            }

            if (_reentryAction != null && !parameters.CancellationToken.IsCancellationRequested)
            {
                await _reentryAction.Invoke(parameters.Context, parameters.CancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false);
            }
        }
        protected StateTransitionResult <TState, TTrigger> ExecutePrim(ExecutionParameters <T, TTrigger> parameters
                                                                       , StateTransitionResult <TState, TTrigger> currentResult
                                                                       , bool conditionMet)
        {
            var startState = currentResult != null ? currentResult.StartingState : StateAccessor(parameters.Context);

            if (!conditionMet)
            {
                return(GetFreshResult(parameters, currentResult, startState, wasCancelled: false, conditionMet: false, transitionDefined: true));
            }

            StateMutator(parameters.Context, ToState);
            var transitionResult = GetFreshResult(parameters, currentResult, startState, wasCancelled: false, conditionMet: true, transitionDefined: true);

            return(transitionResult);
        }
Esempio n. 12
0
        public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters
                                                                         , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (currentResult != null &&
                (_triggerState.IsEqual(currentResult.CurrentState) ||
                 _stateMachine.IsInState(parameters.Context, _triggerState)))
            {
                return(base.Execute(parameters, currentResult));
            }

            return(GetFreshResult(parameters
                                  , currentResult
                                  , StateAccessor(parameters.Context)
                                  , wasCancelled: false
                                  , transitionDefined: true
                                  , conditionMet: false));
        }
        protected StateTransitionResult <TState, TTrigger> FireTriggerPrim(ExecutionParameters <T, TTrigger> parameters)
        {
            StateTransitionResult <TState, TTrigger> result = null;

            if (Transitions.TryGetValue(parameters.Trigger, out var transitions))
            {
                foreach (var transition in transitions.OrderBy(t => t.Priority))
                {
                    result = transition.Execute(parameters);
                    if (result.WasTransitioned)
                    {
                        return(result);
                    }
                }
            }

            return(result);
        }
Esempio n. 14
0
        protected StateTransitionResult <TState, TTrigger> GetFreshResult(ExecutionParameters <T, TTrigger> parameters
                                                                          , StateTransitionResult <TState, TTrigger> previousResult
                                                                          , TState startState
                                                                          , bool transitionDefined
                                                                          , bool conditionMet
                                                                          , bool wasCancelled)
        {
            bool wasSuccessful = (transitionDefined && conditionMet && !wasCancelled);

            return(new StateTransitionResult <TState, TTrigger>(parameters.Trigger
                                                                , startState
                                                                , (!wasSuccessful || previousResult == null) ? startState : previousResult.CurrentState
                                                                , wasSuccessful ? StateAccessor(parameters.Context) : previousResult == null ? startState : previousResult.CurrentState
                                                                , wasSuccessful ? Name : string.Empty
                                                                , wasCancelled: wasCancelled
                                                                , conditionMet: conditionMet
                                                                , transitionDefined: transitionDefined));
        }
Esempio n. 15
0
        /// <summary>
        /// Executes trigger.
        /// </summary>
        /// <param name="context">The items whose state is being managed.</param>
        /// <param name="trigger">The event that has occured that may affect the state.</param>
        /// <returns></returns>
        public StateTransitionResult <TState, TTrigger> FireTrigger(T context, TTrigger trigger)
        {
            var startState          = StateAccessor(context);
            var executionParameters = new ExecutionParameters <T, TTrigger>(trigger, context);

            if (_triggerActions.TryGetValue(trigger, out var triggerAction))
            {
                triggerAction.Execute(executionParameters);
            }

            var result = !_stateConfigurations.TryGetValue(startState, out var stateConfiguration)
                ? new StateTransitionResult <TState, TTrigger>(trigger
                                                               , startState
                                                               , startState
                                                               , startState
                                                               , lastTransitionName: String.Empty
                                                               , transitionDefined: false)
                : stateConfiguration.FireTrigger(executionParameters);

            return(executeExitAndEntryActions(executionParameters, result));
        }
        public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters
                                                                         , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (!(parameters.Request is TParam))
            {
                throw new ArgumentException($"Expected a {typeof(TParam).Name} parameter, but received a {parameters.Request?.GetType().Name ?? "null"}.");
            }

            if (currentResult != null &&
                (_triggerState.IsEqual(currentResult.CurrentState) ||
                 _stateMachine.IsInState(parameters.Context, _triggerState)))
            {
                return(base.Execute(parameters, currentResult));
            }

            return(GetFreshResult(parameters
                                  , currentResult
                                  , StateAccessor(parameters.Context)
                                  , wasCancelled: false
                                  , transitionDefined: true
                                  , conditionMet: false));
        }
Esempio n. 17
0
        public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters
                                                                         , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (!(parameters.Request is TRequest typeSafeParam))
            {
                throw new ArgumentException($"Expected a {typeof(TRequest).Name} parameter, but received a {parameters.Request?.GetType().Name ?? "null"}.");
            }

            if (currentResult != null &&
                !parameters.CancellationToken.IsCancellationRequested &&
                _startState.IsEqual(currentResult.PreviousState) &&
                (_triggerState.IsEqual(currentResult.CurrentState) ||
                 _stateMachine.IsInState(parameters.Context, _triggerState)))
            {
                StateMutator(parameters.Context, _stateFunction(parameters.Context, typeSafeParam));

                var transitioned = !StateAccessor(parameters.Context).IsEqual(_triggerState);
                var result       = GetFreshResult(parameters
                                                  , currentResult
                                                  , currentResult.StartingState
                                                  , wasCancelled: false
                                                  , transitionDefined: true
                                                  , conditionMet: transitioned);
                if (transitioned)
                {
                    NotifyOfTransition(parameters.Context, result);
                }

                return(result);
            }

            return(GetFreshResult(parameters
                                  , currentResult
                                  , StateAccessor(parameters.Context)
                                  , wasCancelled: parameters.CancellationToken.IsCancellationRequested
                                  , transitionDefined: true
                                  , conditionMet: false));
        }
Esempio n. 18
0
        public override async Task <StateTransitionResult <TState, TTrigger> > ExecuteAsync(ExecutionParameters <T, TTrigger> parameters
                                                                                            , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            var startState = currentResult != null ? currentResult.StartingState : StateAccessor(parameters.Context);

            if (parameters.CancellationToken.IsCancellationRequested)
            {
                return(GetFreshResult(parameters, currentResult, startState, wasCancelled: true, transitionDefined: true, conditionMet: false));
            }

            if (!await ConditionAsync(parameters.Context, parameters.CancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false))
            {
                return(GetFreshResult(parameters, currentResult, startState, wasCancelled: parameters.CancellationToken.IsCancellationRequested, transitionDefined: true, conditionMet: false));
            }

            StateMutator(parameters.Context, ToState);
            var transitionResult = GetFreshResult(parameters, currentResult, startState, wasCancelled: false, conditionMet: true, transitionDefined: true);

            NotifyOfTransition(parameters.Context, transitionResult);

            return(transitionResult);
        }
Esempio n. 19
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);
        }
Esempio n. 20
0
 public override StateTransitionResult <TState, TTrigger> Execute(ExecutionParameters <T, TTrigger> parameters
                                                                  , StateTransitionResult <TState, TTrigger> currentResult = null)
 {
     return(ExecutePrim(parameters, currentResult, Condition(parameters.Context)));
 }
Esempio n. 21
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="parameters">Parameters used for the call to FireTrigger.</param>
 /// <param name="transitionResult">Details of transitions that occurred during FireTrigger.</param>
 public TransitionEventArgs(ExecutionParameters <T, TTrigger> parameters, StateTransitionResult <TState, TTrigger> transitionResult)
 {
     Parameters       = parameters ?? throw new ArgumentNullException(nameof(parameters));
     TransitionResult = transitionResult ?? throw new ArgumentNullException(nameof(transitionResult));
 }
Esempio n. 22
0
        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);
        }
Esempio n. 23
0
        public async Task <StateTransitionResult <TState, TTrigger> > ExecuteAutoTransitionAsync(ExecutionParameters <T, TTrigger> parameters
                                                                                                 , StateTransitionResult <TState, TTrigger> currentResult)
        {
            if (AutoTransitions.TryGetValue(parameters.Trigger, out var triggerTransitions))
            {
                foreach (var transition in triggerTransitions.OrderBy(t => t.Priority))
                {
                    var localResult = await transition.ExecuteAsync(parameters, currentResult)
                                      .ConfigureAwait(continueOnCapturedContext: false);

                    if (localResult.WasTransitioned)
                    {
                        return(localResult);
                    }
                }
            }

            //Check for a super state and just return the incoming currentResult if no successful auto transitions
            return(_superState != null
                ? await _superState.ExecuteAutoTransitionAsync(parameters, currentResult).ConfigureAwait(continueOnCapturedContext: false)
                : new StateTransitionResult <TState, TTrigger>(parameters.Trigger
                                                               , currentResult.StartingState
                                                               , currentResult.PreviousState
                                                               , currentResult.CurrentState
                                                               , currentResult.LastTransitionName
                                                               , transitionDefined: true
                                                               , wasCancelled: parameters.CancellationToken.IsCancellationRequested
                                                               , conditionMet: false));
        }
        public override async Task <StateTransitionResult <TState, TTrigger> > ExecuteAsync(ExecutionParameters <T, TTrigger> parameters
                                                                                            , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (currentResult != null &&
                !parameters.CancellationToken.IsCancellationRequested &&
                _startState.IsEqual(currentResult.PreviousState) &&
                (_triggerState.IsEqual(currentResult.CurrentState) ||
                 _stateMachine.IsInState(parameters.Context, _triggerState)))
            {
                return(await base.ExecuteAsync(parameters, currentResult));
            }

            return(GetFreshResult(parameters
                                  , currentResult
                                  , StateAccessor(parameters.Context)
                                  , wasCancelled: parameters.CancellationToken.IsCancellationRequested
                                  , transitionDefined: true
                                  , conditionMet: false));
        }
Esempio n. 25
0
        public override async Task <StateTransitionResult <TState, TTrigger> > ExecuteAsync(ExecutionParameters <T, TTrigger> parameters
                                                                                            , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (!(parameters.Request is TParam typeSafeParam))
            {
                throw new ArgumentException($"Expected a {typeof(TParam).Name} parameter, but received a {parameters.Request?.GetType().Name ?? "null"}.");
            }

            var startState = currentResult != null ? currentResult.StartingState : StateAccessor(parameters.Context);

            if (parameters.CancellationToken.IsCancellationRequested)
            {
                if (currentResult != null)
                {
                    return(currentResult);
                }

                return(new StateTransitionResult <TState, TTrigger>(parameters.Trigger
                                                                    , startState
                                                                    , startState
                                                                    , startState
                                                                    , lastTransitionName: string.Empty
                                                                    , wasCancelled: true));
            }

            var toState = await StateFuncAsync(parameters.Context, typeSafeParam, parameters.CancellationToken)
                          .ConfigureAwait(continueOnCapturedContext: false);

            return(ExecuteFinalizeAsync(parameters, currentResult, startState, toState));
        }
Esempio n. 26
0
 public virtual Task <StateTransitionResult <TState, TTrigger> > ExecuteAsync(ExecutionParameters <T, TTrigger> parameters
                                                                              , StateTransitionResult <TState, TTrigger> currentResult = null)
 {
     throw new NotImplementedException("Inheritted classes must override this method. Ensure you're calling the correct overloaded version.");
 }
Esempio n. 27
0
 internal override void Execute(ExecutionParameters <T, TTrigger> parameters)
 {
     Action.Invoke(parameters.Context);
 }
Esempio n. 28
0
        private async Task <StateTransitionResult <TState, TTrigger> > FireTriggerPrimAsync(ExecutionParameters <T, TTrigger> parameters)
        {
            StateTransitionResult <TState, TTrigger> result = null;

            if (Transitions.TryGetValue(parameters.Trigger, out var transitions))
            {
                foreach (var transition in transitions.OrderBy(t => t.Priority))
                {
                    result = await transition.ExecuteAsync(parameters).ConfigureAwait(continueOnCapturedContext: false);

                    if (result.WasTransitioned)
                    {
                        return(result);
                    }
                }
            }

            return(result);
        }
Esempio n. 29
0
        public async Task <StateTransitionResult <TState, TTrigger> > FireTriggerAsync(ExecutionParameters <T, TTrigger> parameters)
        {
            if (_triggerActions.TryGetValue(parameters.Trigger, out var triggerAction))
            {
                await triggerAction.ExecuteAsync(parameters.Context, request : parameters.Request, cancellationToken : parameters.CancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false);
            }

            var result = await FireTriggerPrimAsync(parameters).ConfigureAwait(continueOnCapturedContext: false);

            if (!(result?.WasTransitioned ?? false) && _superState != null)
            {
                result = await _superState.FireTriggerAsync(parameters).ConfigureAwait(continueOnCapturedContext: false);
            }
            else
            {
                var startState = StateAccessor(parameters.Context);
                result = result ?? new StateTransitionResult <TState, TTrigger>(parameters.Trigger
                                                                                , startState
                                                                                , startState
                                                                                , startState
                                                                                , lastTransitionName: string.Empty
                                                                                , transitionDefined: false);
            }

            return(result);
        }
Esempio n. 30
0
        public override async Task <StateTransitionResult <TState, TTrigger> > ExecuteAsync(ExecutionParameters <T, TTrigger> parameters
                                                                                            , StateTransitionResult <TState, TTrigger> currentResult = null)
        {
            if (!(parameters.Request is TParam typeSafeParam))
            {
                throw new ArgumentException($"Expected a {typeof(TParam).Name} parameter, but received a {parameters.Request?.GetType().Name ?? "null"}.");
            }

            var startState = currentResult != null ? currentResult.StartingState : StateAccessor(parameters.Context);

            if (parameters.CancellationToken.IsCancellationRequested)
            {
                return(GetFreshResult(parameters
                                      , currentResult
                                      , startState
                                      , transitionDefined: true
                                      , conditionMet: false
                                      , wasCancelled: true));
            }

            if (!await ConditionAsync(parameters.Context, typeSafeParam, parameters.CancellationToken)
                .ConfigureAwait(continueOnCapturedContext: false))
            {
                return(GetFreshResult(parameters, currentResult, startState, transitionDefined: true, conditionMet: false, wasCancelled: parameters.CancellationToken.IsCancellationRequested));
            }

            StateMutator(parameters.Context, ToState);
            var transitionResult = currentResult == null
                ? new StateTransitionResult <TState, TTrigger>(parameters.Trigger, startState, startState, ToState, Name)
                : new StateTransitionResult <TState, TTrigger>(parameters.Trigger, startState, currentResult.CurrentState, ToState, Name);

            NotifyOfTransition(parameters.Context, transitionResult);

            return(transitionResult);
        }