private async Task HandleReentryTriggerAsync(object[] args, StateRepresentation representativeState, Transition transition)
        {
            StateRepresentation representation;

            transition = await representativeState.ExitAsync(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);
                await newRepresentation.ExitAsync(transition);

                await _onTransitionedEvent.InvokeAsync(transition);

                representation = await EnterStateAsync(newRepresentation, transition, args);

                await _onTransitionCompletedEvent.InvokeAsync(transition);
            }
            else
            {
                await _onTransitionedEvent.InvokeAsync(transition);

                representation = await EnterStateAsync(newRepresentation, transition, args);

                await _onTransitionCompletedEvent.InvokeAsync(transition);
            }
            State = representation.UnderlyingState;
        }
Exemple #2
0
        public void MoveToState(TState state, StateTransitionOption option = StateTransitionOption.Default)
        {
            lock (syncRoot)
            {
                if (!IsEnabled)
                {
                    return;
                }
                StateRepresentation <TState, TTrigger> rep;
                if (configDictionary.TryGetValue(state, out rep))
                {
                    if ((option & StateTransitionOption.CurrentStateExitTransition) ==
                        StateTransitionOption.CurrentStateExitTransition)
                    {
                        ExecuteAction(CurrentStateRepresentation.OnExitAction);
                    }
                    if ((option & StateTransitionOption.NewStateEntryTransition) ==
                        StateTransitionOption.NewStateEntryTransition)
                    {
                        ExecuteAction(rep.OnEntryAction);
                    }

                    CurrentStateRepresentation = rep;
                }
                else
                {
                    throw new InvalidOperationException("Invalid state: " + state.ToString());
                }
            }
        }
Exemple #3
0
        private void HandleTransitioningTrigger(object[] args, StateRepresentation representativeState, Transition transition)
        {
            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(transition.Source, newRepresentation.InitialTransitionTarget, transition.Trigger);
                    newRepresentation = GetRepresentation(newRepresentation.InitialTransitionTarget);
                    newRepresentation.Enter(initialTransition, args);
                    State = newRepresentation.UnderlyingState;
                }
                //Alert all listeners of state transition
                _onTransitionedEvent.Invoke(transition);
            }
            else
            {
                //Alert all listeners of state transition
                _onTransitionedEvent.Invoke(transition);
                newRepresentation.Enter(transition, args);
            }
        }
Exemple #4
0
        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);
        }
            async Task ExecuteInternalActionsAsync(Transition transition, object[] args)
            {
                InternalTriggerBehaviour internalTransition = null;

                // Look for actions in superstate(s) recursivly until we hit the topmost superstate, or we actually find some trigger handlers.
                StateRepresentation aStateRep = this;

                while (aStateRep != null)
                {
                    if (aStateRep.TryFindLocalHandler(transition.Trigger, args, out TriggerBehaviourResult result))
                    {
                        // Trigger handler(s) found in this state
                        internalTransition = result.Handler as InternalTriggerBehaviour;
                        break;
                    }
                    // Try to look for trigger handlers in superstate (if it exists)
                    aStateRep = aStateRep._superstate;
                }

                // Execute internal transition event handler
                if (internalTransition == null)
                {
                    throw new ArgumentNullException("The configuration is incorrect, no action assigned to this internal transition.");
                }
                await(internalTransition.ExecuteAsync(transition, args)).ConfigureAwait(false);
            }
Exemple #6
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;
        }
Exemple #7
0
            internal void InternalAction(Transition transition, object[] args)
            {
                InternalTriggerBehaviour.Sync internalTransition = null;

                // Look for actions in superstate(s) recursivly until we hit the topmost superstate, or we actually find some trigger handlers.
                StateRepresentation aStateRep = this;

                while (aStateRep != null)
                {
                    if (aStateRep.TryFindLocalHandler(transition.Trigger, args, out TriggerBehaviourResult result))
                    {
                        // Trigger handler found in this state
                        if (result.Handler is InternalTriggerBehaviour.Async)
                        {
                            throw new InvalidOperationException("Running Async internal actions in synchronous mode is not allowed");
                        }

                        internalTransition = result.Handler as InternalTriggerBehaviour.Sync;
                        break;
                    }
                    // Try to look for trigger handlers in superstate (if it exists)
                    aStateRep = aStateRep._superstate;
                }

                // Execute internal transition event handler
                if (internalTransition == null)
                {
                    throw new ArgumentNullException("The configuration is incorrect, no action assigned to this internal transition.");
                }
                internalTransition.InternalAction(transition, args);
            }
Exemple #8
0
            /// <summary>
            /// Clone constructor
            /// </summary>
            private StateRepresentation(TState state,
                                        IEnumerable <KeyValuePair <TTrigger, ICollection <TriggerBehaviour> > > triggerBehaviours,
                                        IEnumerable <Action <Transition, object[]> > entryActions,
                                        IEnumerable <Action <Transition> > exitActions,
                                        StateRepresentation superstate,
                                        IEnumerable <StateRepresentation> substates)
            {
                _state = state;

                foreach (var behaviour in triggerBehaviours)
                {
                    _triggerBehaviours.Add(behaviour);
                }

                foreach (var action in entryActions)
                {
                    _entryActions.Add(action);
                }

                foreach (var action in exitActions)
                {
                    _exitActions.Add(action);
                }

                if (superstate != null)
                {
                    _superstate = superstate.Clone();
                }

                foreach (var substate in substates)
                {
                    _substates.Add(substate.Clone());
                }
            }
            internal void InternalAction(Transition transition, object[] args)
            {
                var possibleActions = new List <InternalActionBehaviour>();

                // Look for actions in superstate(s) recursivly until we hit the topmost superstate, or we actually find some trigger handlers.
                StateRepresentation aStateRep = this;

                while (aStateRep != null)
                {
                    if (aStateRep.TryFindLocalHandler(transition.Trigger, out TriggerBehaviourResult result))
                    {
                        // Trigger handler(s) found in this state
                        possibleActions.AddRange(aStateRep._internalActions);
                        break;
                    }
                    // Try to look for trigger handlers in superstate (if it exists)
                    aStateRep = aStateRep._superstate;
                }

                // Execute internal transition event handler
                foreach (var action in possibleActions)
                {
                    action.Execute(transition, args);
                }
            }
Exemple #10
0
 public void AddSubstate(StateRepresentation substate)
 {
     if (substate != null)
     {
         mSubStates.Add(substate);
     }
 }
            /// <summary>
            ///     Sets the superstate that the configured state is a substate of.
            /// </summary>
            /// <remarks>
            ///     Substates inherit the allowed transitions of their superstate.
            ///     When entering directly into a substate from outside of the superstate,
            ///     entry actions for the superstate are executed.
            ///     Likewise when leaving from the substate to outside the supserstate,
            ///     exit actions for the superstate will execute.
            /// </remarks>
            /// <param name="superstate">The superstate.</param>
            /// <returns>The receiver.</returns>
            public StateConfiguration SubstateOf(TState superstate)
            {
                StateRepresentation superRepresentation = _lookup(superstate);

                _representation.Superstate = superRepresentation;
                superRepresentation.AddSubstate(_representation);
                return(this);
            }
Exemple #12
0
        StateRepresentation GetRepresentation(TState state)
        {
            if (!_stateConfiguration.TryGetValue(state, out StateRepresentation result))
            {
                result = new StateRepresentation(state);
                _stateConfiguration.Add(state, result);
            }

            return(result);
        }
Exemple #13
0
 public StateConfiguration Permit(TTrigger trigger, TState destinationState, Func <TState, TTrigger, bool> action)
 {
     if (!_representation.TriggerBehaviours.ContainsKey(trigger))
     {
         StateRepresentation sr = _machine.GetRepresentation(_machine._nullState);
         sr.AddTriggerBehaviour(new TransitioningTriggerBehaviour(trigger, destinationState, action));
     }
     _representation.AddTriggerBehaviour(new TransitioningTriggerBehaviour(trigger, destinationState, action));
     return(this);
 }
Exemple #14
0
    private StateRepresentation GetRepresentation(TState state)
    {
        StateRepresentation result;

        if (!mStateConfiguration.TryGetValue(state, out result))
        {
            result = new StateRepresentation(state);
            mStateConfiguration.Add(state, result);
        }
        return(result);
    }
Exemple #15
0
        StateRepresentation GetRepresentation(TState state)
        {
            StateRepresentation result;

            if (!_stateConfiguration.TryGetValue(state, out result))
            {
                result = new StateRepresentation(state);
                _stateConfiguration.Add(state, result);
                //Configure(_state).Permit(_firstTrigger, state);
            }
            return(_stateConfiguration[state]);
        }
Exemple #16
0
        internal StateMachine(TState initialState, StateMachineConfiguration<TState, TTrigger> configuration)
        {
            Contract.Requires(configuration != null);
            Contract.Requires(initialState != null);

            currentStateRepresentation = configuration.GetStateRepresentation(initialState);
            if (currentStateRepresentation == null)
            {
                throw new InvalidOperationException("StateMachine has no state");
            }

            IsEnabled = true;
        }
Exemple #17
0
        internal StateConfigurationHelper(Dictionary <TState, StateRepresentation <TState, TTrigger> > config,
                                          TState currentState)
        {
            Contract.Requires(config != null);
            Contract.Requires(currentState != null);

            Contract.Ensures(this.config != null);
            Contract.Ensures(currentStateRepresentation != null);


            this.config = config;
            currentStateRepresentation = FindOrCreateStateRepresentation(currentState, config);
        }
Exemple #18
0
        internal BlockingStateMachine(TState initialState, StateMachineConfiguration <TState, TTrigger> configuration)
        {
            Contract.Requires(configuration != null);
            Contract.Requires(initialState != null);

            CurrentStateRepresentation = configuration.GetInitialStateRepresentation(initialState);
            if (CurrentStateRepresentation == null)
            {
                throw new InvalidOperationException("StateMachine has an unreachable state");
            }

            configDictionary = configuration.Config;
        }
Exemple #19
0
        private void HandleTransitioningTrigger(object[] args, StateRepresentation representativeState, Transition transition)
        {
            transition = representativeState.Exit(transition);

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

            //Alert all listeners of state transition
            _onTransitionedEvent.Invoke(transition);
            var representation = EnterState(newRepresentation, transition, args);

            State = representation.UnderlyingState;
        }
        protected RawStateMachineBase(TState initialState, Configuration <TState, TTrigger> configuration)
        {
            Representations = configuration.Representations;

            CurrentStateRepresentation = StateConfigurationHelper.FindStateRepresentation(
                initialState, Representations);

            if (CurrentStateRepresentation == null)
            {
                ExceptionHelper.ThrowInvalidState(initialState);
            }

            diagnostics = new RawStateMachineDiagnostics <TState, TTrigger>(this);
        }
Exemple #21
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);
        }
Exemple #22
0
        public void MoveToState(TState state, StateTransitionOption option = StateTransitionOption.Default)
        {
            if (monitor.TryEnter())
            {
                try
                {
                    if (!IsEnabled)
                    {
                        return;
                    }
                    StateRepresentation <TState, TTrigger> rep;
                    if (configDictionary.TryGetValue(state, out rep))
                    {
                        if ((option & StateTransitionOption.CurrentStateExitTransition) ==
                            StateTransitionOption.CurrentStateExitTransition)
                        {
                            ExecuteAction(CurrentStateRepresentation.OnExitAction);
                        }
                        if ((option & StateTransitionOption.NewStateEntryTransition) ==
                            StateTransitionOption.NewStateEntryTransition)
                        {
                            ExecuteAction(rep.OnEntryAction);
                        }

                        CurrentStateRepresentation = rep;
                    }
                    else
                    {
                        throw new InvalidOperationException("Invalid state: " + state.ToString());
                    }
                }
                finally
                {
                    monitor.Exit();
                }
            }
            else
            {
                if (IsEnabled)
                {
                    throw new InvalidOperationException("State cannot be changed while in transition. Use AsyncStateMachine or a BlockingStateMachine for these semantics.");
                }
            }
        }
Exemple #23
0
            void ExecuteInternalActions(Transition transition, object[] args)
            {
                var possibleActions = new List <InternalActionBehaviour>();

                // Look for actions in superstate(s) recursivly until we hit the topmost superstate
                StateRepresentation aStateRep = this;

                do
                {
                    possibleActions.AddRange(aStateRep._internalActions);
                    aStateRep = aStateRep._superstate;
                } while (aStateRep != null);

                // Execute internal transition event handler
                foreach (var action in possibleActions)
                {
                    action.Execute(transition, args);
                }
            }
Exemple #24
0
        internal static StateRepresentation <TState, TTrigger> FindOrCreateStateRepresentation(TState state,
                                                                                               Dictionary <TState, StateRepresentation <TState, TTrigger> > config)
        {
            Contract.Requires(state != null);
            Contract.Requires(config != null);

            Contract.Ensures(Contract.Result <StateRepresentation <TState, TTrigger> >() != null);

            StateRepresentation <TState, TTrigger> rep;

            if (config.TryGetValue(state, out rep))
            {
                return(rep);
            }

            rep           = new StateRepresentation <TState, TTrigger>(state);
            config[state] = rep;

            return(rep);
        }
Exemple #25
0
        private void HandleTransitioningTrigger(object[] args, StateRepresentation representativeState, Transition transition)
        {
            transition = representativeState.Exit(transition);

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

            //Alert all listeners of state transition
            _onTransitionedEvent.Invoke(transition);
            var representation = EnterState(newRepresentation, transition, args);

            // Check if state has changed by entering new state (by fireing triggers in OnEntry or such)
            if (!representation.UnderlyingState.Equals(State))
            {
                // The state has been changed after entering the state, must update current state to new one
                State = representation.UnderlyingState;
            }

            _onTransitionCompletedEvent.Invoke(transition);
        }
        private async Task HandleTransitioningTriggerAsync(object[] args, StateRepresentation representativeState, Transition transition)
        {
            transition = await representativeState.ExitAsync(transition);

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

            //Alert all listeners of state transition
            await _onTransitionedEvent.InvokeAsync(transition);

            var representation = await EnterStateAsync(newRepresentation, transition, args);

            // Check if state has changed by entering new state (by fireing triggers in OnEntry or such)
            if (!representation.UnderlyingState.Equals(State))
            {
                // The state has been changed after entering the state, must update current state to new one
                State = representation.UnderlyingState;
            }

            await _onTransitionCompletedEvent.InvokeAsync(new Transition(transition.Source, State, transition.Trigger, transition.Parameters));
        }
Exemple #27
0
        private StateRepresentation EnterState(StateRepresentation representation, Transition transition, object [] args)
        {
            // Enter the new state
            representation.Enter(transition, 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 Transition(transition.Source, representation.InitialTransitionTarget, transition.Trigger);
                representation = GetRepresentation(representation.InitialTransitionTarget);
                representation = EnterState(representation, initialTransition, args);
            }

            return(representation);
        }
Exemple #28
0
 public void AddSubstate(StateRepresentation substate)
 {
     Enforce.ArgumentNotNull(substate, nameof(substate));
     _substates.Add(substate);
 }
Exemple #29
0
        internal static TriggerRepresentation <TTrigger, TState> FindOrCreateTriggerRepresentation(TTrigger trigger,
                                                                                                   StateRepresentation <TState, TTrigger> stateRepresentation)
        {
            Contract.Requires(stateRepresentation != null);
            Contract.Requires(trigger != null);

            Contract.Ensures(Contract.Result <TriggerRepresentation <TTrigger, TState> >() != null);

            var rep = FindTriggerRepresentation(trigger, stateRepresentation);

            if (rep != null)
            {
                Contract.Assume(rep.Trigger != null);
                return(rep);
            }

            rep = new TriggerRepresentation <TTrigger, TState>(trigger);
            stateRepresentation.Triggers.Add(rep);
            return(rep);
        }
Exemple #30
0
 internal static TriggerRepresentation <TTrigger, TState> FindTriggerRepresentation(TTrigger trigger,
                                                                                    StateRepresentation <TState, TTrigger> stateRepresentation)
 {
     return(stateRepresentation.Triggers.Find(x => x.Trigger.Equals(trigger)));
 }