コード例 #1
0
ファイル: StateMachine.cs プロジェクト: kroluu/Peg-Solitaire
        private StateRepresentation EnterState(StateRepresentation representation, Transition transition, object [] args)
        {
            // Enter the new state
            representation.Enter(transition, args);

            if (FiringMode.Immediate.Equals(_firingMode) && !State.Equals(transition.Destination))
            {
                // This can happen if triggers are fired in OnEntry
                // Must update current representation with updated State
                representation = GetRepresentation(State);
                transition     = new Transition(transition.Source, State, transition.Trigger, args);
            }

            // Recursively enter substates that have an initial transition
            if (representation.HasInitialTransition)
            {
                // Verify that the target state is a substate
                // Check if state has substate(s), and if an initial transition(s) has been set up.
                if (!representation.GetSubstates().Any(s => s.UnderlyingState.Equals(representation.InitialTransitionTarget)))
                {
                    throw new InvalidOperationException($"The target ({representation.InitialTransitionTarget}) for the initial transition is not a substate.");
                }

                var initialTransition = new InitialTransition(transition.Source, representation.InitialTransitionTarget, transition.Trigger, args);
                representation = GetRepresentation(representation.InitialTransitionTarget);
                representation = EnterState(representation, initialTransition, args);
            }

            return(representation);
        }
コード例 #2
0
 public static void InitialTransitionAddTransition(InitialTransition initialTransition, Transition transition)
 => initialTransition.AddTransition(transition);
コード例 #3
0
        async Task InternalFireOneAsync(TTrigger trigger, params object[] args)
        {
            // If this is a trigger with parameters, we must validate the parameter(s)
            if (_triggerConfiguration.TryGetValue(trigger, out var configuration))
            {
                configuration.ValidateParameters(args);
            }

            var source = State;
            var representativeState = GetRepresentation(source);

            // Try to find a trigger handler, either in the current state or a super state.
            if (!representativeState.TryFindHandler(trigger, args, out var result))
            {
                await _unhandledTriggerAction.ExecuteAsync(representativeState.UnderlyingState, trigger, result?.UnmetGuardConditions).ConfigureAwait(false);

                return;
            }
            // Check if this trigger should be ignored
            if (result.Handler is IgnoredTriggerBehaviour)
            {
                return;
            }

            // Handle special case, re-entry in superstate
            if (result.Handler is ReentryTriggerBehaviour handler)
            {
                // Handle transition, and set new state
                var transition = new Transition(source, handler.Destination, trigger, args);
                transition = await representativeState.ExitAsync(transition);

                State = transition.Destination;
                var newRepresentation = GetRepresentation(transition.Destination);

                if (!source.Equals(transition.Destination))
                {
                    // Then Exit the final superstate
                    transition = new Transition(handler.Destination, handler.Destination, trigger, args);
                    await newRepresentation.ExitAsync(transition);
                }

                await _onTransitionedEvent.InvokeAsync(new Transition(source, handler.Destination, trigger, args));

                await newRepresentation.EnterAsync(transition, args);
            }
            // Check if it is an internal transition, or a transition from one state to another.
            else if (result.Handler.ResultsInTransitionFrom(source, args, out var destination))
            {
                var transition = new Transition(source, destination, trigger, args);

                transition = await representativeState.ExitAsync(transition).ConfigureAwait(false);

                State = transition.Destination;
                var newRepresentation = GetRepresentation(transition.Destination);
                await newRepresentation.EnterAsync(transition, args);

                // Check if there is an intital transition configured
                if (newRepresentation.HasInitialTransition)
                {
                    // Verify that the target state is a substate
                    if (!newRepresentation.GetSubstates().Any(s => s.UnderlyingState.Equals(newRepresentation.InitialTransitionTarget)))
                    {
                        throw new InvalidOperationException($"The target ({newRepresentation.InitialTransitionTarget}) for the initial transition is not a substate.");
                    }

                    // Check if state has substate(s), and if an initial transition(s) has been set up.
                    while (newRepresentation.GetSubstates().Any() && newRepresentation.HasInitialTransition)
                    {
                        var initialTransition = new InitialTransition(source, newRepresentation.InitialTransitionTarget, trigger, args);
                        newRepresentation = GetRepresentation(newRepresentation.InitialTransitionTarget);
                        await newRepresentation.EnterAsync(initialTransition, args);

                        State = newRepresentation.UnderlyingState;
                    }
                }
                // Alert all listeners of state transition
                await _onTransitionedEvent.InvokeAsync(new Transition(source, destination, trigger, args));
            }
            else
            {
                var transition = new Transition(source, destination, trigger, args);

                await CurrentRepresentation.InternalActionAsync(transition, args).ConfigureAwait(false);
            }
        }
コード例 #4
0
 public static void StateNodeSetInitialTransition(PartialStateNode stateNode, InitialTransition initialTransition)
 => stateNode.Initial = Option.From <OneOf <InitialTransition, string> >(initialTransition);