Пример #1
0
        private void HandleReentryTrigger(object[] args, StateRepresentation representativeState, Transition transition)
        {
            StateRepresentation representation;

            transition = representativeState.Exit(transition);
            var newRepresentation = GetRepresentation(transition.Destination);

            if (!transition.Source.Equals(transition.Destination))
            {
                // Then Exit the final superstate
                transition = new Transition(transition.Destination, transition.Destination, transition.Trigger, args);
                newRepresentation.Exit(transition);

                _onTransitionedEvent.Invoke(transition);
                representation = EnterState(newRepresentation, transition, args);
                _onTransitionCompletedEvent.Invoke(transition);
            }
            else
            {
                _onTransitionedEvent.Invoke(transition);
                representation = EnterState(newRepresentation, transition, args);
                _onTransitionCompletedEvent.Invoke(transition);
            }
            State = representation.UnderlyingState;
        }
Пример #2
0
        /// <summary>
        /// This method handles the execution of a trigger handler. It finds a
        /// handle, then updates the current state information.
        /// </summary>
        /// <param name="trigger"></param>
        /// <param name="args"></param>
        void InternalFireOne(TTrigger trigger, params object[] args)
        {
            // If this is a trigger with parameters, we must validate the parameter(s)
            if (_triggerConfiguration.TryGetValue(trigger, out TriggerWithParameters 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 TriggerBehaviourResult result))
            {
                _unhandledTriggerAction.Execute(representativeState.UnderlyingState, trigger, result?.UnmetGuardConditions);
                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);
                transition = representativeState.Exit(transition);
                State      = transition.Destination;
                var newRepresentation = GetRepresentation(transition.Destination);

                // Then Exit the final superstate
                transition = new Transition(handler.Destination, handler.Destination, trigger);
                newRepresentation.Exit(transition);
                _onTransitionedEvent.Invoke(new Transition(source, handler.Destination, trigger));

                newRepresentation.Enter(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 TState destination))
            {
                // Handle transition, and set new state
                var transition = new Transition(source, destination, trigger);

                transition = representativeState.Exit(transition);

                State = transition.Destination;
                var newRepresentation = GetRepresentation(transition.Destination);
                _onTransitionedEvent.Invoke(new Transition(source, destination, trigger));

                newRepresentation.Enter(transition, args);
            }
            else
            {
                // Internal transitions does not update the current state, but must execute the associated action.
                var transition = new Transition(source, destination, trigger);

                CurrentRepresentation.InternalAction(transition, args);
            }
        }
Пример #3
0
        void InternalFireOne(TTrigger trigger, params object[] args)
        {
            if (_triggerConfiguration.TryGetValue(trigger, out TriggerWithParameters configuration))
            {
                configuration.ValidateParameters(args);
            }

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

            if (!representativeState.TryFindHandler(trigger, out TriggerBehaviourResult result))
            {
                _unhandledTriggerAction.Execute(representativeState.UnderlyingState, trigger, result?.UnmetGuardConditions);
                return;
            }

            if (result.Handler.ResultsInTransitionFrom(source, args, out TState destination))
            {
                var transition = new Transition(source, destination, trigger);

                representativeState.Exit(transition);

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

                newRepresentation.Enter(transition, args);
            }
            else
            {
                var transition = new Transition(source, destination, trigger);

                CurrentRepresentation.InternalAction(transition, args);
            }
        }
Пример #4
0
        private void HandleReentryTrigger(object[] args, StateRepresentation representativeState, Transition transition)
        {
            transition = representativeState.Exit(transition);
            State      = transition.Destination;
            var newRepresentation = GetRepresentation(transition.Destination);

            if (!transition.Source.Equals(transition.Destination))
            {
                // Then Exit the final superstate
                transition = new Transition(transition.Destination, transition.Destination, transition.Trigger);
                newRepresentation.Exit(transition);
            }

            _onTransitionedEvent.Invoke(transition);

            newRepresentation.Enter(transition, args);
        }
Пример #5
0
        /// <summary>
        /// This method handles the execution of a trigger handler. It finds a
        /// handle, then updates the current state information.
        /// </summary>
        /// <param name="trigger"></param>
        /// <param name="args"></param>
        void InternalFireOne(TTrigger trigger, params object[] args)
        {
            // If this is a trigger with parameters, we must validate the parameter(s)
            if (_triggerConfiguration.TryGetValue(trigger, out TriggerWithParameters 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 TriggerBehaviourResult result))
            {
                _unhandledTriggerAction.Execute(representativeState.UnderlyingState, trigger, result?.UnmetGuardConditions);
                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);
                transition = representativeState.Exit(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);
                    newRepresentation.Exit(transition);
                }

                _onTransitionedEvent.Invoke(new Transition(source, handler.Destination, trigger));

                newRepresentation.Enter(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 TState destination))
            {
                // Handle transition, and set new state
                var transition = new Transition(source, destination, trigger);

                transition = representativeState.Exit(transition);

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

                // 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 Transition(source, newRepresentation.InitialTransitionTarget, trigger);
                        newRepresentation = GetRepresentation(newRepresentation.InitialTransitionTarget);
                        newRepresentation.Enter(initialTransition, args);
                        State = newRepresentation.UnderlyingState;
                    }
                    //Alert all listeners of state transition
                    _onTransitionedEvent.Invoke(new Transition(source, destination, trigger));
                }
                else
                {
                    //Alert all listeners of state transition
                    _onTransitionedEvent.Invoke(new Transition(source, destination, trigger));

                    newRepresentation.Enter(transition, args);
                }
            }
            else
            {
                // Internal transitions does not update the current state, but must execute the associated action.
                var transition = new Transition(source, destination, trigger);

                CurrentRepresentation.InternalAction(transition, args);
            }
        }
Пример #6
0
 protected void NotifyOfTransition(T context, StateTransitionResult <TState, TTrigger> transitionResult)
 {
     OnTransitionedEvent?.Invoke(context, transitionResult);
 }