/// <summary> /// Makes the state machine go into another state. /// </summary> public void TransitionToNewState(StateBase newState, TriggerBase causedByTrigger, GuardBase guard, Func<StateBase, StateBase, TriggerBase, bool> lambda) { if (disposedValue) { // Silent throw new InvalidOperationException("State Machine Disposed"); } // Pull the trigger to find if condition is Ok. OnStartTransition(this.CurrentState, newState, causedByTrigger); if ( guard != null ) { guard.Execute(); } OnBeforeExitingPreviousState(this.CurrentState, newState, causedByTrigger); // exit the current state if (this.CurrentState != null) this.CurrentState.OnExit(causedByTrigger); StateBase previousState = this.CurrentState ; this.CurrentState = newState; // OnEvent(previousState, this.CurrentState, causedByTrigger); if (lambda != null) lambda(previousState, this.CurrentState, causedByTrigger); // enter the new state if (this.CurrentState != null) this.CurrentState.OnEntry(causedByTrigger); OnEndTransition(previousState, this.CurrentState, causedByTrigger); }
/// <summary> /// Makes the state machine go into another state. /// </summary> /// <param name="newState"></param> /// <param name="causedByTrigger"></param> /// <param name="guard"></param> /// <param name="EffectHandler"></param> /// <returns>true if done</returns> protected bool TransitionToNewState(StateBase newState, TriggerBase causedByTrigger, GuardBase guard, WeakEventSource <TransitionEventArgs> EffectHandler) { // we need recursion level here, so we can lock just on highest level try { // Console.WriteLine("----->" + transitionToNewStateRecursionLevel + "-" + this.GetHashCode() + "[" + GetCurrentThreadId() + "]->going in"); ++transitionToNewStateRecursionLevel; // first call we will have 1 after this line if (disposedValue) { return(false); } // Pull the trigger to find if condition is Ok. _wes_StartTransition?.Raise(this, new TransitionEventArgs(_CurrentState, newState, causedByTrigger)); if (!disposedValue && guard != null) { // guard is where thread can come IDLE so here it can dispose in parallel isInGuard = true; try { bool returnFalseFromGuardOrDisposedValue = (disposedValue || !guard.Execute() || disposedValue); if (returnFalseFromGuardOrDisposedValue) { return(false); // Guard said this trigger can't go on } } finally { isInGuard = false; } } _wes_BeforeExitingPreviousState?.Raise(this, new TransitionEventArgs(_CurrentState, newState, causedByTrigger)); // exit the current state if (!disposedValue && _CurrentState != null) { // arbitrary code in so it can dispose in _CurrentState.OnExit(causedByTrigger); } //check dispose if (disposedValue) { return(false); } StateBase previousState = _CurrentState; this.CurrentState = newState; //check dispose if (disposedValue) { return(false); } //call effect if (EffectHandler != null) { // arbitrary code in so it can dispose in ProcessEffect(new EffectAction(EffectHandler, new TransitionEventArgs(previousState, newState, causedByTrigger))); } //check dispose if (disposedValue) { return(false); } //check if new state is DecisionState if (_CurrentState is ConditionStateBase) { //take triggers foreach (TriggerBase t in (_CurrentState as ConditionStateBase).Triggers) { if (ProcessTriggerInternal(t as TriggerBase)) { // we did all return true, we should be in after decision state return(true); } //check dispose if (disposedValue) { return(false); } } //check dispose if (!disposedValue) { // no one did work so raise error throw new ApplicationException("ConditionState blocked!"); } } else { if (!disposedValue && _CurrentState != null) { _CurrentState.OnEntry(causedByTrigger); } //check dispose if (disposedValue) { return(false); } _wes_EndTransition?.Raise(this, new TransitionEventArgs(previousState, newState, causedByTrigger)); } // we did well so ok send true if not disposed return(!disposedValue); } finally { // we go out so decrease --transitionToNewStateRecursionLevel; // Console.WriteLine("----->" + transitionToNewStateRecursionLevel + "-" + this.GetHashCode() + "[" + GetCurrentThreadId() + "]->going out"); if (transitionToNewStateRecursionLevel < 0) { throw new ApplicationException("Wrong transitionToNewStateRecursionLevel!"); } } }
/// <summary> /// Makes the state machine go into another state. /// </summary> public void TransitionToNewState(StateBase newState, TriggerBase causedByTrigger, GuardBase guard, TransitionEventHandler EffectHandler) { if (disposedValue) { // Silent throw new InvalidOperationException("State Machine Disposed"); } // Pull the trigger to find if condition is Ok. OnTransitionEvent(StartTransition, this.CurrentState, newState, causedByTrigger); if ( guard != null ) { if (!guard.Execute()) return; // Guard said this trigger can't go on } OnTransitionEvent(BeforeExitingPreviousState, this.CurrentState, newState, causedByTrigger); // exit the current state if (this.CurrentState != null) this.CurrentState.OnExit(causedByTrigger); StateBase previousState = this.CurrentState ; this.CurrentState = newState; //call effect if(EffectHandler != null) OnTransitionEvent(EffectHandler, previousState, this.CurrentState, causedByTrigger); // enter the new state if (this.CurrentState != null) this.CurrentState.OnEntry(causedByTrigger); OnTransitionEvent(EndTransition, previousState, this.CurrentState, causedByTrigger); }