private static void CheckThatStateMachineHasEnteredInitialState(StateContainer <TState, TEvent> stateContainer) { if (!stateContainer.CurrentState.IsInitialized) { throw new InvalidOperationException(ExceptionMessages.StateMachineHasNotYetEnteredInitialState); } }
/// <summary> /// Fires the specified event. /// </summary> /// <param name="eventId">The event.</param> /// <param name="eventArgument">The event argument.</param> /// <param name="stateContainer">Contains all mutable state of of the state machine.</param> /// <param name="stateMachineInformation">The state machine information.</param> /// <param name="stateDefinitions">The definitions for all states of this state Machine.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task Fire( TEvent eventId, object eventArgument, StateContainer <TState, TEvent> stateContainer, IStateMachineInformation <TState, TEvent> stateMachineInformation, IStateDefinitionDictionary <TState, TEvent> stateDefinitions) { CheckThatStateMachineHasEnteredInitialState(stateContainer); await stateContainer.ForEach(extension => extension.FiringEvent(stateMachineInformation, ref eventId, ref eventArgument)) .ConfigureAwait(false); var currentState = stateContainer.CurrentState.ExtractOrThrow(); var context = this.factory.CreateTransitionContext(currentState, new Missable <TEvent>(eventId), eventArgument, this); var result = await this.stateLogic.Fire(currentState, context, stateContainer) .ConfigureAwait(false); if (!result.Fired) { this.OnTransitionDeclined(context); return; } var newState = stateDefinitions[result.NewState]; await SwitchStateTo(newState, stateContainer, stateMachineInformation) .ConfigureAwait(false); await stateContainer.ForEach(extension => extension.FiredEvent(stateMachineInformation, context)) .ConfigureAwait(false); this.OnTransitionCompleted(context, stateMachineInformation); }
private static async Task SwitchStateTo( IStateDefinition <TState, TEvent> newState, StateContainer <TState, TEvent> stateContainer, IStateMachineInformation <TState, TEvent> stateMachineInformation) { var oldState = stateContainer.CurrentState.ExtractOr(null); stateContainer.CurrentState = Initializable <IStateDefinition <TState, TEvent> > .Initialized(newState); await stateContainer .ForEach(extension => extension.SwitchedState(stateMachineInformation, oldState, newState)) .ConfigureAwait(false); }
/// <summary> /// Enters the initial state as specified with <paramref name="initialState"/>. /// </summary> /// <param name="stateContainer">Contains all mutable state of of the state machine.</param> /// <param name="stateDefinitions">The definitions for all states of this state Machine.</param> /// <param name="initialState">The initial state the state machine should enter.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task EnterInitialState( StateContainer <TState, TEvent> stateContainer, IStateDefinitionDictionary <TState, TEvent> stateDefinitions, TState initialState) { await stateContainer.ForEach(extension => extension.EnteringInitialState(initialState)) .ConfigureAwait(false); var context = this.factory.CreateTransitionContext(null, new Missable <TEvent>(), Missing.Value, this); await this.EnterInitialState(context, stateContainer, stateDefinitions, initialState) .ConfigureAwait(false); await stateContainer.ForEach(extension => extension.EnteredInitialState(initialState, context)) .ConfigureAwait(false); }
private async Task EnterInitialState( ITransitionContext <TState, TEvent> context, StateContainer <TState, TEvent> stateContainer, IStateDefinitionDictionary <TState, TEvent> stateDefinitions, TState initialStateId) { var initialState = stateDefinitions[initialStateId]; var initializer = this.factory.CreateStateMachineInitializer(initialState, context); var newStateId = await initializer.EnterInitialState(this.stateLogic, stateContainer, stateDefinitions). ConfigureAwait(false); var newStateDefinition = stateDefinitions[newStateId]; await SwitchStateTo(newStateDefinition, stateContainer, stateDefinitions) .ConfigureAwait(false); }
private static async Task SwitchStateTo( IStateDefinition <TState, TEvent> newState, StateContainer <TState, TEvent> stateContainer, IStateDefinitionDictionary <TState, TEvent> stateDefinitions) { var oldState = stateContainer .CurrentStateId .Map(x => stateDefinitions[x]) .ExtractOr(null); stateContainer.CurrentStateId = Initializable <TState> .Initialized(newState.Id); await stateContainer .ForEach(extension => extension.SwitchedState(oldState, newState)) .ConfigureAwait(false); }
public AsyncActiveStateMachine <TState, TEvent> CreateActiveStateMachine(string name) { var stateContainer = new StateContainer <TState, TEvent>(name); foreach (var stateIdAndLastActiveState in this.initiallyLastActiveStates) { stateContainer.SetLastActiveStateFor(stateIdAndLastActiveState.Key, stateIdAndLastActiveState.Value); } var transitionLogic = new TransitionLogic <TState, TEvent>(stateContainer, stateContainer); var stateLogic = new StateLogic <TState, TEvent>(transitionLogic, stateContainer, stateContainer); transitionLogic.SetStateLogic(stateLogic); var standardFactory = new StandardFactory <TState, TEvent>(); var stateMachine = new StateMachine <TState, TEvent>(standardFactory, stateLogic); return(new AsyncActiveStateMachine <TState, TEvent>(stateMachine, stateContainer, this.stateDefinitions, this.initialState)); }