예제 #1
0
 public virtual ITransitionContext <TState, TEvent> CreateTransitionContext(IStateDefinition <TState, TEvent> stateDefinition, Missable <TEvent> eventId, object eventArgument, INotifier <TState, TEvent> notifier)
 {
     return(new TransitionContext <TState, TEvent>(stateDefinition, eventId, eventArgument, notifier));
 }
예제 #2
0
        /// <summary>
        /// Recursively traverses the state hierarchy, exiting states along
        /// the way, performing the action, and entering states to the target.
        /// </summary>
        /// <remarks>
        /// There exist the following transition scenarios:
        /// 0. there is no target state (internal transition)
        ///    --> handled outside this method.
        /// 1. The source and target state are the same (self transition)
        ///    --> perform the transition directly:
        ///        Exit source state, perform transition actions and enter target state
        /// 2. The target state is a direct or indirect sub-state of the source state
        ///    --> perform the transition actions, then traverse the hierarchy
        ///        from the source state down to the target state,
        ///        entering each state along the way.
        ///        No state is exited.
        /// 3. The source state is a sub-state of the target state
        ///    --> traverse the hierarchy from the source up to the target,
        ///        exiting each state along the way.
        ///        Then perform transition actions.
        ///        Finally enter the target state.
        /// 4. The source and target state share the same super-state
        /// 5. All other scenarios:
        ///    a. The source and target states reside at the same level in the hierarchy
        ///       but do not share the same direct super-state
        ///    --> exit the source state, move up the hierarchy on both sides and enter the target state
        ///    b. The source state is lower in the hierarchy than the target state
        ///    --> exit the source state and move up the hierarchy on the source state side
        ///    c. The target state is lower in the hierarchy than the source state
        ///    --> move up the hierarchy on the target state side, afterward enter target state.
        /// </remarks>
        /// <param name="transitionDefinition">The transition definition.</param>
        /// <param name="source">The source state.</param>
        /// <param name="target">The target state.</param>
        /// <param name="context">The event context.</param>
        /// <param name="lastActiveStateModifier">The last active state modifier.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        private async Task Fire(
            ITransitionDefinition <TState, TEvent> transitionDefinition,
            IStateDefinition <TState, TEvent> source,
            IStateDefinition <TState, TEvent> target,
            ITransitionContext <TState, TEvent> context,
            ILastActiveStateModifier <TState, TEvent> lastActiveStateModifier)
        {
            if (source == transitionDefinition.Target)
            {
                // Handles 1.
                // Handles 3. after traversing from the source to the target.
                await this.stateLogic.Exit(source, context, lastActiveStateModifier).ConfigureAwait(false);

                await this.PerformActions(transitionDefinition, context).ConfigureAwait(false);

                await this.stateLogic.Entry(transitionDefinition.Target, context).ConfigureAwait(false);
            }
            else if (source == target)
            {
                // Handles 2. after traversing from the target to the source.
                await this.PerformActions(transitionDefinition, context).ConfigureAwait(false);
            }
            else if (source.SuperState == target.SuperState)
            {
                //// Handles 4.
                //// Handles 5a. after traversing the hierarchy until a common ancestor if found.
                await this.stateLogic.Exit(source, context, lastActiveStateModifier).ConfigureAwait(false);

                await this.PerformActions(transitionDefinition, context).ConfigureAwait(false);

                await this.stateLogic.Entry(target, context).ConfigureAwait(false);
            }
            else
            {
                // traverses the hierarchy until one of the above scenarios is met.

                // Handles 3.
                // Handles 5b.
                if (source.Level > target.Level)
                {
                    await this.stateLogic.Exit(source, context, lastActiveStateModifier).ConfigureAwait(false);

                    await this.Fire(transitionDefinition, source.SuperState, target, context, lastActiveStateModifier).ConfigureAwait(false);
                }
                else if (source.Level < target.Level)
                {
                    // Handles 2.
                    // Handles 5c.
                    await this.Fire(transitionDefinition, source, target.SuperState, context, lastActiveStateModifier).ConfigureAwait(false);

                    await this.stateLogic.Entry(target, context).ConfigureAwait(false);
                }
                else
                {
                    // Handles 5a.
                    await this.stateLogic.Exit(source, context, lastActiveStateModifier).ConfigureAwait(false);

                    await this.Fire(transitionDefinition, source.SuperState, target.SuperState, context, lastActiveStateModifier).ConfigureAwait(false);

                    await this.stateLogic.Entry(target, context).ConfigureAwait(false);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="TransitionDictionary&lt;TState, TEvent&gt;"/> class.
 /// </summary>
 /// <param name="state">The state.</param>
 public TransitionDictionary(IStateDefinition <TState, TEvent> state)
 {
     this.state       = state;
     this.transitions = new Dictionary <TEvent, List <TransitionDefinition <TState, TEvent> > >();
 }
예제 #4
0
            public TransitionContextBuilder WithState(IStateDefinition <TState, TEvent> state)
            {
                A.CallTo(() => this.transitionContext.StateDefinition).Returns(state);

                return(this);
            }
예제 #5
0
 public StateBuilder()
 {
     this.stateDefinition = A.Fake <IStateDefinition <TState, TEvent> >();
 }
 private bool DetermineWhetherThisIsAnInitialState(IStateDefinition <TState, TEvent> state)
 {
     return(state.Id.ToString() == this.initialState.ToString() ||
            (state.SuperState != null && state.SuperState.InitialState == state));
 }
예제 #7
0
        public override Task SwitchedState(IStateMachineInformation <int, int> stateMachine, IStateDefinition <int, int> oldState, IStateDefinition <int, int> newState)
        {
            this.CurrentState = newState.Id;

            return(Task.CompletedTask);
        }
 public override void SwitchedState(IStateMachineInformation <int, int> stateMachine, IStateDefinition <int, int> oldState, IStateDefinition <int, int> newState)
 {
     this.CurrentState = newState.Id;
 }
 private static string CreateEntryActionDescription(IStateDefinition <TState, TEvent> state)
 {
     return(state.EntryActions.Any()
                ? (state.EntryActions.Aggregate("(", (aggregate, action) => (aggregate.Length > 1 ? aggregate + ", " : aggregate) + action.Describe()) + ")" + Environment.NewLine)
                : string.Empty);
 }
예제 #10
0
 public virtual void EnteringState(
     IStateMachineInformation <TState, TEvent> stateMachine,
     IStateDefinition <TState, TEvent> state,
     ITransitionContext <TState, TEvent> context)
 {
 }
예제 #11
0
 /// <summary>
 /// Called after the state machine switched states.
 /// </summary>
 /// <param name="stateMachine">The state machine.</param>
 /// <param name="oldState">The old state.</param>
 /// <param name="newState">The new state.</param>
 public virtual void SwitchedState(IStateMachineInformation <TState, TEvent> stateMachine, IStateDefinition <TState, TEvent> oldState, IStateDefinition <TState, TEvent> newState)
 {
 }
예제 #12
0
 /// <summary>
 /// Called after an exit action exception was handled.
 /// </summary>
 /// <param name="stateMachine">The state machine.</param>
 /// <param name="stateDefinition">The state definition.</param>
 /// <param name="context">The context.</param>
 /// <param name="exception">The exception.</param>
 public virtual void HandledExitActionException(IStateMachineInformation <TState, TEvent> stateMachine, IStateDefinition <TState, TEvent> stateDefinition, ITransitionContext <TState, TEvent> context, Exception exception)
 {
 }
예제 #13
0
 /// <summary>
 /// Called after the state machine switched states.
 /// </summary>
 /// <param name="stateMachine">The state machine.</param>
 /// <param name="oldState">The old state.</param>
 /// <param name="newState">The new state.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public virtual Task SwitchedState(IStateMachineInformation <TState, TEvent> stateMachine, IStateDefinition <TState, TEvent> oldState, IStateDefinition <TState, TEvent> newState)
 {
     return(TaskEx.Completed);
 }
예제 #14
0
 /// <summary>
 /// Called after an exit action exception was handled.
 /// </summary>
 /// <param name="stateMachine">The state machine.</param>
 /// <param name="stateDefinition">The state.</param>
 /// <param name="context">The context.</param>
 /// <param name="exception">The exception.</param>
 /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
 public virtual Task HandledExitActionException(IStateMachineInformation <TState, TEvent> stateMachine, IStateDefinition <TState, TEvent> stateDefinition, ITransitionContext <TState, TEvent> context, Exception exception)
 {
     return(TaskEx.Completed);
 }
예제 #15
0
 public virtual StateMachineInitializer <TState, TEvent> CreateStateMachineInitializer(IStateDefinition <TState, TEvent> initialState, ITransitionContext <TState, TEvent> context)
 {
     return(new StateMachineInitializer <TState, TEvent>(initialState, context));
 }
예제 #16
0
 public StateMachineInitializer(IStateDefinition <TState, TEvent> initialState, ITransitionContext <TState, TEvent> context)
 {
     this.initialState = initialState;
     this.context      = context;
 }