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)); }
/// <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<TState, TEvent>"/> 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> > >(); }
public TransitionContextBuilder WithState(IStateDefinition <TState, TEvent> state) { A.CallTo(() => this.transitionContext.StateDefinition).Returns(state); return(this); }
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)); }
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); }
public virtual void EnteringState( IStateMachineInformation <TState, TEvent> stateMachine, IStateDefinition <TState, TEvent> state, ITransitionContext <TState, TEvent> context) { }
/// <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) { }
/// <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) { }
/// <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); }
/// <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); }
public virtual StateMachineInitializer <TState, TEvent> CreateStateMachineInitializer(IStateDefinition <TState, TEvent> initialState, ITransitionContext <TState, TEvent> context) { return(new StateMachineInitializer <TState, TEvent>(initialState, context)); }
public StateMachineInitializer(IStateDefinition <TState, TEvent> initialState, ITransitionContext <TState, TEvent> context) { this.initialState = initialState; this.context = context; }