Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }