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); }
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); }