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; }
/// <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); } }
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); } }
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); }
/// <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); } }
protected void NotifyOfTransition(T context, StateTransitionResult <TState, TTrigger> transitionResult) { OnTransitionedEvent?.Invoke(context, transitionResult); }