Esempio n. 1
0
        internal static List <InternalState <TInternalState> > FindAllStates(
            IReadOnlyDictionary <InternalState <TInternalState>, InternalState <TInternalState> > relations,
            InternalState <TInternalState> childState)
        {
            if (childState == null)
            {
                throw new ArgumentNullException("childState", "When trying to find a parent state the childState cannot be null!");
            }

            var _nextStates = new Stack <InternalState <TInternalState> >();

            // Find the list of states that represents every state that surround the state we are trying to transition to

            InternalState <TInternalState> currentState = childState;

            _nextStates.Push(childState);

            while (relations.ContainsKey(currentState))
            {
                var t = relations[currentState];
                _nextStates.Push(t);
                currentState = t;
            }

            return(_nextStates.ToList());
        }
Esempio n. 2
0
        private static void Dispatch <TInternalState, TEvent>(TEvent evnt
                                                              , IMachineState <TInternalState> internalState
                                                              , InternalState <TInternalState> currentState
                                                              , IReadOnlyDictionary <InternalState <TInternalState>, InternalState <TInternalState> > relations
                                                              , IEnumerable <Func <object, object> > eventInterceptors
                                                              , MachineConfiguration <TInternalState> config
                                                              , bool outerTransitionsTakePrecedence
                                                              , Func <string, InternalState <TInternalState> > lookup)
        {
            var currentStates = Misc <TInternalState> .FindAllStates(relations, currentState);

            if (!outerTransitionsTakePrecedence)
            {
                currentStates.Reverse();
            }

            var nextState = DispatchToStates(evnt, internalState, currentStates, eventInterceptors, config, lookup);

            if (nextState != null && nextState != currentStates.Last())
            {
                nextState = TransitionTo((object)evnt, internalState, relations, nextState, eventInterceptors, false, config, lookup);
            }

            if (nextState != null)
            {
                UpdateStateHistories(internalState, relations, nextState);
            }
        }
Esempio n. 3
0
 internal MachineState(
     Dictionary <InternalState <TInternalState>, InternalState <TInternalState> > stateHistories
     , TInternalState state
     , InternalState <TInternalState> currentState)
 {
     _stateHistories       = stateHistories;
     _currentInternalState = state;
     _currentState         = currentState;
 }
Esempio n. 4
0
        private static InternalState <TInternalState> TransitionTo <TInternalState>(
            object evnt
            , IMachineState <TInternalState> machineState
            , IReadOnlyDictionary <InternalState <TInternalState>, InternalState <TInternalState> > relations
            , InternalState <TInternalState> transitionToState
            , IEnumerable <Func <object, object> > eventInterceptors
            , bool exitInnerStatesFirst
            , MachineConfiguration <TInternalState> config
            , Func <string, InternalState <TInternalState> > lookup)
        {
            config.Logger(string.Format("SM:{0}:{1} = State: {2} -> {3} on ^{4} = '{5}'"
                                        , config.Name
                                        , config.GetUniqueId(machineState.CurrentInternalState)
                                        , machineState.CurrentState.Name
                                        , transitionToState.Name
                                        , evnt.GetType().Name
                                        , config.LogEvents(evnt)));

            var _currentStates = Misc <TInternalState> .FindAllStates(relations, machineState.CurrentState);

            var _nextStates = Misc <TInternalState> .FindAllStates(relations, transitionToState);

            while (machineState.StateHistory.ContainsKey(transitionToState))
            {
                var nextTransitionToState = machineState.StateHistory[transitionToState];
                transitionToState = nextTransitionToState;
                _nextStates.Add(nextTransitionToState);
            }

            var entryConditionsToRun = _nextStates.Except(_currentStates);
            var exitConditionsToRun  = _currentStates.Except(_nextStates);

            if (exitInnerStatesFirst)
            {
                entryConditionsToRun.Reverse();
                exitConditionsToRun.Reverse();
            }

            // Dispatch and do not transition...
            var newState = DispatchToStates(new Events.ExitEvent(), machineState, exitConditionsToRun, eventInterceptors, config, lookup);

            machineState.ChangeState(_nextStates.Last());

            // Dispath entry event - transition if neccesary  and do not transition...
            newState = DispatchToStates(new Events.EntryEvent(), machineState, entryConditionsToRun, eventInterceptors, config, lookup);
            if (newState != null)
            {
                transitionToState = TransitionTo(evnt, machineState, relations, newState, eventInterceptors, exitInnerStatesFirst, config, lookup);
            }

            return(transitionToState);
        }
Esempio n. 5
0
 internal static InternalState <TInternalState> FindParentState(
     IReadOnlyDictionary <InternalState <TInternalState>, InternalState <TInternalState> > relations,
     InternalState <TInternalState> childState)
 {
     if (relations.ContainsKey(childState))
     {
         return(relations[childState]);
     }
     else
     {
         return(null);
     }
 }
Esempio n. 6
0
        void IMachineState <TInternalState> .AddInitialHistory(InternalState <TInternalState> parentState, InternalState <TInternalState> initialState)
        {
            if (parentState == null)
            {
                throw new ArgumentNullException("parentState", "The Parent state cannot be null when trying to Add initial histories");
            }

            if (initialState == null)
            {
                throw new ArgumentNullException("initialState", "The Initial State cannot be null when trying to Add initial histories");
            }

            _stateHistories[parentState] = initialState;
        }
Esempio n. 7
0
        /// <summary>
        /// Runs through all the current states - and updates the state histories to the current ones.
        /// </summary>
        private static void UpdateStateHistories <TInternalState>(IMachineState <TInternalState> internalState,
                                                                  IReadOnlyDictionary <InternalState <TInternalState>, InternalState <TInternalState> > parentStates,
                                                                  InternalState <TInternalState> nextState)
        {
            foreach (var state in Misc <TInternalState> .FindAllStates(parentStates, nextState))
            {
                var parentState = Misc <TInternalState> .FindParentState(parentStates, state);

                if ((parentState != null) && internalState.StateHistory.ContainsKey(parentState))
                {
                    internalState.StateHistory[parentState] = state;
                }
            }
        }
Esempio n. 8
0
        private static InternalState <TInternalState> DispatchToStates <TInternalState, TEvent>(TEvent evnt
                                                                                                , IMachineState <TInternalState> internalState
                                                                                                , IEnumerable <InternalState <TInternalState> > statesToDispatchTo
                                                                                                , IEnumerable <Func <object, object> > eventInterceptors
                                                                                                , MachineConfiguration <TInternalState> config
                                                                                                , Func <string, InternalState <TInternalState> > lookup)
        {
            TEvent evntToDispatch = ExecuteInterceptorsForEvent(evnt, eventInterceptors);

            if (evntToDispatch == null)
            {
                // Do not dispatch a null event!
                return(null);
            }

            InternalState <TInternalState> finalTransitionState = null;
            Type eventType = evnt.GetType();

            foreach (var currentState in statesToDispatchTo)
            {
                if (currentState.Handlers.ContainsKey(eventType))
                {
                    finalTransitionState = Execute(evnt, internalState, config, finalTransitionState, currentState, lookup);
                }
                else if (eventType != typeof(Events.EntryEvent) & eventType != typeof(Events.ExitEvent))
                {
                    if (currentState.Handlers.ContainsKey(typeof(Events.DefaultEvent)))
                    {
                        finalTransitionState = Execute(new Events.DefaultEvent(), internalState, config, finalTransitionState, currentState, lookup);
                    }
                }

                if (eventType != typeof(Events.EntryEvent) & eventType != typeof(Events.ExitEvent))
                {
                    // Always run an AnyEvent() -
                    if (currentState.Handlers.ContainsKey(typeof(Events.AnyEvent)))
                    {
                        finalTransitionState = Execute(new Events.AnyEvent(), internalState, config, finalTransitionState, currentState, lookup);
                    }
                }
            }

            return(finalTransitionState);
        }
Esempio n. 9
0
 void IMachineState <TInternalState> .ChangeState(InternalState <TInternalState> newState)
 {
     _currentState = newState;
 }
Esempio n. 10
0
        private static InternalState <TInternalState> Execute <TInternalState, TEvent>(TEvent evnt,
                                                                                       IMachineState <TInternalState> internalState,
                                                                                       MachineConfiguration <TInternalState> config,
                                                                                       InternalState <TInternalState> finalTransitionState,
                                                                                       InternalState <TInternalState> currentState,
                                                                                       Func <string, InternalState <TInternalState> > lookup)
        {
            var handler = currentState.Handlers[evnt.GetType()];

            Action <string> log =
                str => config.Logger($"SM:{config.Name}:{config.GetUniqueId(internalState.CurrentInternalState)} = State: {currentState.Name} - {str}");

            foreach (var action in handler.TransistionDefinitions)
            {
                if (action.GuardCondition(internalState.CurrentInternalState, evnt))
                {
                    action.Action?.Invoke(internalState.CurrentInternalState, evnt, log);

                    if (action.TransitionTo != null)
                    {
                        finalTransitionState = finalTransitionState ?? lookup(action.TransitionTo);
                    }
                }
            }

            return(finalTransitionState);
        }