/// <summary> /// Makes the state machine receive a command and dispatch it through the internal Queue. /// </summary> /// <param name="trigger"></param> public void ProcessTrigger(TriggerBase trigger) { if (disposedValue) { return; } _queue.Enqueue(trigger); _timer.Start(); Application.DoEvents(); }
public TransitionEventArgs(StateBase prev, StateBase next, TriggerBase why) { Prev = prev; Next = next; Why = why; }
/// <summary> /// Makes the state machine processo a command. Depending on its current state /// and the designed transitions the machine reacts to the trigger. /// </summary> protected abstract void ProcessTriggerInternal(TriggerBase trigger);
protected void OnStartTransition(StateBase prev, StateBase next, TriggerBase why) { if (this.StartTransition != null) this.StartTransition(this, new TransitionEventArgs(prev, next, why)); }
protected void OnBeforeExitingPreviousState(StateBase prev, StateBase next, TriggerBase why) { if (this.BeforeExitingPreviousState != null) this.BeforeExitingPreviousState(this, new TransitionEventArgs(prev, next, why)); }
/// <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); }
/// <summary> /// Is executed when the state machine enters this state. /// </summary> public virtual void OnEntry(TriggerBase trigger) { }
/// <summary> /// Is executed when the state machine leaves this state. /// </summary> public virtual void OnExit(TriggerBase trigger) { }
/// <summary> /// Makes the state machine react to a trigger. /// </summary> protected override void ProcessTriggerInternal(TriggerBase trigger) { if (this.CurrentState == null) return; if (trigger == null) throw new ArgumentException("tigger must not be null"); // determine what action to take based on the current state // and the given trigger. if (this.CurrentState is StartState) { if (trigger is CreateTrigger) { SetCopyNumberGuard guard = new SetCopyNumberGuard(this) ; this.TransitionToNewState(new BozzaState(this), trigger, guard, null); return; } } if (this.CurrentState is BozzaState) { if (trigger is ConsolidateTrigger) { CheckListOkGuard guard = new CheckListOkGuard(this) ; this.TransitionToNewState(new ConsolidatoState(this), trigger, guard, (p, n, t) => { OnNotifyValidators(p, n, t); return true ; } ); return; } if (trigger is RemoveTrigger) { EraseGuard guard = new EraseGuard(this) ; this.TransitionToNewState(new EndState(this), trigger, guard, null); return; } } if (this.CurrentState is ConsolidatoState) { if (trigger is RejectTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new BozzaState(this), trigger, guard, (p, n, t) => { OnRecordRejected(p, n, t); return true ; } ); return; } if (trigger is ValidateTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new ValidatoState(this), trigger, guard, null); return; } } if (this.CurrentState is ValidatoState) { if (trigger is InvalidateTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new ConsolidatoState(this), trigger, guard, null); return; } if (trigger is PublishTrigger) { NotFallGuard guard = new NotFallGuard(this) ; this.TransitionToNewState(new PubblicatoState(this), trigger, guard, null); return; } if (trigger is VersionTrigger) { CreateBozzaGuard guard = new CreateBozzaGuard(this) ; this.TransitionToNewState(new ValidatoVersionatoState(this), trigger, guard, null); return; } if (trigger is SimpleFixTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new CorrezioneState(this), trigger, guard, null); return; } if (trigger is RejectTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new BozzaState(this), trigger, guard, null); return; } } if (this.CurrentState is PubblicatoState) { if (trigger is VersionTrigger) { CreateBozzaGuard guard = new CreateBozzaGuard(this) ; this.TransitionToNewState(new PubblicatoVersionatoState(this), trigger, guard, null); return; } if (trigger is HideTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new ValidatoState(this), trigger, guard, null); return; } if (trigger is SimpleFixTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new CorrezioneState(this), trigger, guard, null); return; } } if (this.CurrentState is CorrezioneState) { if (trigger is SaveTrigger) { RtfInGuard guard = new RtfInGuard(this) ; this.TransitionToNewState(new ValidatoState(this), trigger, guard, null); return; } } if (this.CurrentState is EndState) { } if (this.CurrentState is ValidatoVersionatoState) { if (trigger is RevertTrigger) { DupIsErasedGuard guard = new DupIsErasedGuard(this) ; this.TransitionToNewState(new ValidatoState(this), trigger, guard, null); return; } if (trigger is PublishTrigger) { NotFallGuard guard = new NotFallGuard(this) ; this.TransitionToNewState(new PubblicatoVersionatoState(this), trigger, guard, null); return; } if (trigger is SimpleFixTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new CorrezioneVersionatoState(this), trigger, guard, null); return; } } if (this.CurrentState is PubblicatoVersionatoState) { if (trigger is RevertTrigger) { DupIsErasedGuard guard = new DupIsErasedGuard(this) ; this.TransitionToNewState(new PubblicatoState(this), trigger, guard, null); return; } if (trigger is HideTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new ValidatoVersionatoState(this), trigger, guard, null); return; } if (trigger is SimpleFixTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new CorrezioneVersionatoState(this), trigger, guard, null); return; } } if (this.CurrentState is CorrezioneVersionatoState) { if (trigger is SaveTrigger) { RtfInGuard guard = new RtfInGuard(this) ; this.TransitionToNewState(new ValidatoVersionatoState(this), trigger, guard, null); return; } } // the start state if (this.CurrentState is StartState) { if (trigger is CreateTrigger) { SetCopyNumberGuard guard = new SetCopyNumberGuard(this) ; this.TransitionToNewState(new BozzaState(this), trigger, guard, null); return; } } }
/// <summary> /// Makes the state machine react to a trigger. /// </summary> protected override void ProcessTriggerInternal(TriggerBase trigger) { if (this.CurrentState == null) return; if (trigger == null) throw new ArgumentException("tigger must not be null"); // determine what action to take based on the current state // and the given trigger. if (this.CurrentState is StartState) { if (trigger is BeginTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileNonVigenteState(this), trigger, guard, null); return; } } if (this.CurrentState is NonVisibileNonVigenteState) { if (trigger is LiveTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileVigenteState(this), trigger, guard, null); return; } if (trigger is ShowTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVigenteState(this), trigger, guard, null); return; } } if (this.CurrentState is NonVigenteState) { if (trigger is LiveTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new VigenteState(this), trigger, guard, null); return; } if (trigger is HideTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileNonVigenteState(this), trigger, guard, null); return; } } if (this.CurrentState is VigenteState) { if (trigger is FallTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new StoricoState(this), trigger, guard, null); return; } if (trigger is HideTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileVigenteState(this), trigger, guard, null); return; } } if (this.CurrentState is StoricoState) { if (trigger is HideTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileStoricoState(this), trigger, guard, null); return; } } if (this.CurrentState is NonVisibileVigenteState) { if (trigger is FallTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileStoricoState(this), trigger, guard, null); return; } if (trigger is ShowTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new VigenteState(this), trigger, guard, null); return; } } if (this.CurrentState is NonVisibileStoricoState) { if (trigger is ShowTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new StoricoState(this), trigger, guard, null); return; } } // the start state if (this.CurrentState is StartState) { if (trigger is BeginTrigger) { DefaultGuardBase guard = null ; this.TransitionToNewState(new NonVisibileNonVigenteState(this), trigger, guard, null); return; } } }
protected void OnRecordRejected(StateBase prev, StateBase next, TriggerBase why) { if (this.RecordRejected != null) this.RecordRejected(this, new TransitionEventArgs(prev, next, why)); }
protected void OnNotifyValidators(StateBase prev, StateBase next, TriggerBase why) { if (this.NotifyValidators != null) this.NotifyValidators(this, new TransitionEventArgs(prev, next, why)); }
private void OnTransitionEvent(TransitionEventHandler handler, StateBase prev, StateBase next, TriggerBase why) { if (handler != null) { if (_invokeDelegate.InvokeRequired) { _invokeDelegate.Invoke(new TransitionEventHandler(handler), new[] { this, (object) new TransitionEventArgs(prev, next, why) } ); return; } handler(this, new TransitionEventArgs(prev, next, why)); } }
/// <summary> /// Makes the state machine recive a command and dispatch it through the internal Queue. /// </summary> public void ProcessTrigger(TriggerBase trigger) { if (disposedValue) { // Silent throw new InvalidOperationException("State Machine Disposed"); } lock (((ICollection)_queue).SyncRoot) { _queue.Enqueue(trigger); _syncEvents.NewTransitionEvent.Set(); } }
/// <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, 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 process a command. Depending on its current state /// and the designed transitions the machine reacts to the trigger. /// </summary> protected abstract bool ProcessTriggerInternal(TriggerBase trigger);
/// <summary> /// Is executed when the state machine enters this state. /// </summary> public override void OnEntry(TriggerBase trigger) { // Ask for available triggers. List<TriggerBase> tList = GetTriggers(); foreach (TriggerBase t in tList) { this.StateMachine.ProcessTrigger(t); } }