コード例 #1
0
ファイル: StateMachine.cs プロジェクト: wtjerry/statemachine
 private static void CheckThatStateMachineHasEnteredInitialState(StateContainer <TState, TEvent> stateContainer)
 {
     if (!stateContainer.CurrentState.IsInitialized)
     {
         throw new InvalidOperationException(ExceptionMessages.StateMachineHasNotYetEnteredInitialState);
     }
 }
コード例 #2
0
ファイル: StateMachine.cs プロジェクト: wtjerry/statemachine
        /// <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);
        }
コード例 #3
0
ファイル: StateMachine.cs プロジェクト: wtjerry/statemachine
        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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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));
        }