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