public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var junction1 = new PseudoState<Instance>("junction1", model, PseudoStateKind.Junction); var junction2 = new PseudoState<Instance>("junction2", model, PseudoStateKind.Junction); var pass = new State<Instance>("success", model); var fail = new State<Instance>("error", model); initial.To(junction1); junction1.To(junction2).When(i => i.Int1 == 0).Effect(i => i.Int1++); junction1.To(fail).Else(); junction2.To(pass).When(i => i.Int1 == 0).Effect(i => i.Int1++); junction2.To(fail).Else(); model.Validate(); var instance = new Instance("static"); model.Initialise(instance); Trace.Assert(pass == instance.GetCurrent(model.DefaultRegion)); Trace.Assert(2 == instance.Int1); }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model); var choice = new PseudoState <Instance>("choice", model, PseudoStateKind.Choice); var junction = new PseudoState <Instance>("junction", model, PseudoStateKind.Junction); var finalState = new FinalState <Instance>("final", model); initial.To(choice); choice.To(junction).When(i => i.Int1 == 0).Effect(i => i.Int1 = 1); choice.To(finalState).Else(); junction.To(choice).When(i => i.Int2 == 0).Effect(i => i.Int2 = 2); model.Validate(); var instance = new Instance("else"); model.Initialise(instance); Trace.Assert(model.IsComplete(instance)); Trace.Assert(instance.Int1 == 1); Trace.Assert(instance.Int2 == 2); }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var junction1 = new PseudoState <Instance>("junction1", model, PseudoStateKind.Junction); var junction2 = new PseudoState <Instance>("junction2", model, PseudoStateKind.Junction); var pass = new State <Instance>("success", model); var fail = new State <Instance>("error", model); initial.To(junction1); junction1.To(junction2).When(i => i.Int1 == 0).Effect(i => i.Int1++); junction1.To(fail).Else(); junction2.To(pass).When(i => i.Int1 == 0).Effect(i => i.Int1++); junction2.To(fail).Else(); model.Validate(); var instance = new Instance("static"); model.Initialise(instance); Trace.Assert(pass == instance.GetCurrent(model.DefaultRegion)); Trace.Assert(2 == instance.Int1); }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model); var choice = new PseudoState<Instance>("choice", model, PseudoStateKind.Choice); var junction = new PseudoState<Instance>("junction", model, PseudoStateKind.Junction); var finalState = new FinalState<Instance>("final", model); initial.To(choice); choice.To(junction).When(i => i.Int1 == 0).Effect(i => i.Int1 = 1); choice.To(finalState).Else(); junction.To(choice).When(i => i.Int2 == 0).Effect(i => i.Int2 = 2); model.Validate(); var instance = new Instance("else"); model.Initialise(instance); Trace.Assert(model.IsComplete(instance)); Trace.Assert(instance.Int1 == 1); Trace.Assert(instance.Int2 == 2); }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var target = new State <Instance>("state", model).Entry(i => i.Int1++).Exit(i => i.Int2++); initial.To(target); target.To().When <string>(m => m == "internal").Effect(i => i.Int3++); target.To(target).When <string>(m => m == "external").Effect(i => i.Int3++); var instance = new Instance("internal"); model.Validate(); model.Initialise(instance); model.Evaluate(instance, "internal"); Trace.Assert(target == instance.GetCurrent(model.DefaultRegion)); Trace.Assert(1 == instance.Int1); Trace.Assert(0 == instance.Int2); Trace.Assert(1 == instance.Int3); model.Evaluate(instance, "external"); Trace.Assert(target == instance.GetCurrent(model.DefaultRegion)); Trace.Assert(2 == instance.Int1); Trace.Assert(1 == instance.Int2); Trace.Assert(2 == instance.Int3); }
public static void Run () { var model = new StateMachine<Instance>("compTest"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var activity1 = new State<Instance>("activity1", model); var activity2 = new State<Instance>("activity2", model); var activity3 = new State<Instance>("activity3", model); var junction1 = new PseudoState<Instance>("junction1", model, PseudoStateKind.Junction); var junction2 = new PseudoState<Instance>("junction2", model, PseudoStateKind.Junction); var end = new FinalState<Instance>("end", model); var subInitial = new PseudoState<Instance>("subInitial", activity2, PseudoStateKind.Initial); var subEnd = new FinalState<Instance>("subEnd", activity2); subInitial.To(subEnd); initial.To(activity1); activity1.To(activity2); activity2.To(junction1); junction1.To(junction2).Else(); junction2.To(activity3).Else(); activity3.To(end); model.Validate(); var instance = new Instance("transitions"); model.Initialise(instance); Trace.Assert(model.IsComplete(instance)); }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var target = new State<Instance>("state", model).Entry(i => i.Int1++).Exit(i => i.Int2++); initial.To(target); target.To().When<string>(m => m == "internal").Effect(i => i.Int3++); target.To(target).When<string>(m => m == "external").Effect(i => i.Int3++); var instance = new Instance("internal"); model.Validate(); model.Initialise(instance); model.Evaluate(instance, "internal"); Trace.Assert(target == instance.GetCurrent(model.DefaultRegion)); Trace.Assert(1 == instance.Int1); Trace.Assert(0 == instance.Int2); Trace.Assert(1 == instance.Int3); model.Evaluate(instance, "external"); Trace.Assert(target == instance.GetCurrent(model.DefaultRegion)); Trace.Assert(2 == instance.Int1); Trace.Assert(1 == instance.Int2); Trace.Assert(2 == instance.Int3); }
public override void VisitPseudoState(PseudoState <TInstance> pseudoState, bool deepHistoryAbove) { base.VisitPseudoState(pseudoState, deepHistoryAbove); // evaluate comppletion transitions once vertex entry is complete if (pseudoState.IsInitial) { this.Behaviour(pseudoState).endEnter += (message, instance, history) => { if (pseudoState.IsHistory && instance.GetCurrent(pseudoState.Region) != null) { this.Behaviour(pseudoState).leave(message, instance, history | pseudoState.Kind == PseudoStateKind.DeepHistory); this.Behaviour(instance.GetCurrent(pseudoState.Region)).Enter(message, instance, history | pseudoState.Kind == PseudoStateKind.DeepHistory); } else { pseudoState.Outgoing.Single().Traverse(instance, null); } }; } else if (pseudoState.Kind == PseudoStateKind.Terminate) { // terminate the state machine instance upon transition to a terminate pseudo state this.Behaviour(pseudoState).beginEnter += (message, instance, history) => instance.Terminate(); } }
public static void Run() { var model = new StateMachine <Instance>("compTest"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var activity1 = new State <Instance>("activity1", model); var activity2 = new State <Instance>("activity2", model); var activity3 = new State <Instance>("activity3", model); var junction1 = new PseudoState <Instance>("junction1", model, PseudoStateKind.Junction); var junction2 = new PseudoState <Instance>("junction2", model, PseudoStateKind.Junction); var end = new FinalState <Instance>("end", model); var subInitial = new PseudoState <Instance>("subInitial", activity2, PseudoStateKind.Initial); var subEnd = new FinalState <Instance>("subEnd", activity2); subInitial.To(subEnd); initial.To(activity1); activity1.To(activity2); activity2.To(junction1); junction1.To(junction2).Else(); junction2.To(activity3).Else(); activity3.To(end); model.Validate(); var instance = new Instance("transitions"); model.Initialise(instance); Trace.Assert(model.IsComplete(instance)); }
public static void Run() { var model = new StateMachine <Instance>("history"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var shallow = new State <Instance>("shallow", model); var deep = new State <Instance>("deep", model); var end = new FinalState <Instance>("final", model); var s1 = new State <Instance>("s1", shallow); var s2 = new State <Instance>("s2", shallow); initial.To(shallow); new PseudoState <Instance>("shallow", shallow, PseudoStateKind.ShallowHistory).To(s1); s1.To(s2).When <string>(c => c == "move"); shallow.To(deep).When <string>(c => c == "go deep"); deep.To(shallow).When <string>(c => c == "go shallow"); s2.To(end).When <string>(c => c == "end"); model.Validate(); var instance = new Instance("history"); model.Initialise(instance); model.Evaluate(instance, "move"); model.Evaluate(instance, "go deep"); model.Evaluate(instance, "go shallow"); model.Evaluate(instance, "end"); Trace.Assert(model.IsComplete(instance)); }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial1 = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var myComposite1 = new State <Instance>("composite1", model); var state3 = new State <Instance>("state3", model); var initial2 = new PseudoState <Instance>("initial", myComposite1, PseudoStateKind.Initial); var state1 = new State <Instance>("state1", myComposite1); var state2 = new State <Instance>("state2", myComposite1); initial1.To(myComposite1); initial2.To(state1); myComposite1.To(state3).When <string>(c => c == "a"); state1.To(state2).When <string>(c => c == "a"); model.Validate(); var instance = new Instance("brice"); model.Initialise(instance); model.Evaluate(instance, "a"); Trace.Assert(instance.GetCurrent(myComposite1.DefaultRegion) == state2); }
public static void Test() { var machine = new Region( "history" ); var initial = new PseudoState( "initial", PseudoStateKind.Initial, machine ); var shallow = new CompositeState( "shallow", machine ); var deep = new SimpleState( "deep", machine ); var final = new FinalState( "final", machine ); var s1 = new SimpleState( "s1", shallow ); var s2 = new SimpleState( "s2", shallow ); new Transition( initial, shallow ); new Transition( new PseudoState( "shallow", PseudoStateKind.ShallowHistory, shallow ), s1 ); new Transition<String>( s1, s2, c => c.Equals( "move" ) ); new Transition<String>( shallow, deep, c => c.Equals( "go deep" ) ); new Transition<String>( deep, shallow, c => c.Equals( "go shallow" ) ); new Transition<String>( s2, final, c => c.Equals( "end" ) ); var state = new State(); machine.Initialise( state ); Trace.Assert( machine.Process( state, "move" ) ); Trace.Assert( machine.Process( state, "go deep" ) ); Trace.Assert( machine.Process( state, "go shallow" ) ); Trace.Assert( !machine.Process( state, "go shallow" ) ); Trace.Assert( machine.Process( state, "end" ) ); Trace.Assert( machine.IsComplete( state ) ); }
public static void Run () { var model = new StateMachine<Instance>("history"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var shallow = new State<Instance>("shallow", model); var deep = new State<Instance>("deep", model); var end = new FinalState<Instance>("final", model); var s1 = new State<Instance>("s1", shallow); var s2 = new State<Instance>("s2", shallow); initial.To(shallow); new PseudoState<Instance>("shallow", shallow, PseudoStateKind.ShallowHistory).To(s1); s1.To(s2).When<string>(c => c == "move"); shallow.To(deep).When<string>(c => c == "go deep"); deep.To(shallow).When<string>(c => c == "go shallow"); s2.To(end).When<string>(c => c == "end"); model.Validate(); var instance = new Instance("history"); model.Initialise(instance); model.Evaluate(instance, "move"); model.Evaluate(instance, "go deep"); model.Evaluate(instance, "go shallow"); model.Evaluate(instance, "end"); Trace.Assert(model.IsComplete(instance)); }
public static void Test() { try { var main = new Region<State>( "muximise1" ); var initial = new PseudoState<State>( "initial", PseudoStateKind.Initial, main ); var ortho = new OrthogonalState<State>( "ortho", main ); var simple = new SimpleState<State>( "simple", main ); var final = new FinalState<State>( "final", main ); var r1 = new Region<State>( "r1", ortho ); var r2 = new Region<State>( "r2", ortho ); var i1 = new PseudoState<State>( "initial", PseudoStateKind.ShallowHistory, r1 ); var i2 = new PseudoState<State>( "initial", PseudoStateKind.ShallowHistory, r2 ); var s1 = new SimpleState<State>( "s1", r1 ); var s2 = new SimpleState<State>( "s2", r2 ); var f1 = new FinalState<State>( "f1", r1 ); var f2 = new FinalState<State>( "f2", r2 ); new Transition<State>( initial, ortho ); new Transition<State>( i1, s1 ); new Transition<State>( i2, s2 ); new Transition<State>( ortho, final ); // This should happen once all regions in ortho are complete? new Transition<State, String>( s1, f1, ( s, c ) => c == "complete1" ); new Transition<State, String>( s2, f2, ( s, c ) => c == "complete2" ); new Transition<State, String>( ortho, simple, ( s, c ) => c == "jump" ); new Transition<State, String>( simple, ortho, ( s, c ) => c == "back" ); var state = new State(); main.Initialise( state ); main.Process( state, "complete1" ); main.Process( state, "complete2" ); Trace.Assert( main.IsComplete( state ) ); } catch( Exception x ) { Trace.Fail( x.Message ); } }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var state1 = new State <Instance>("state1", model); var state2 = new State <Instance>("state2", model); var regionA = new Region <Instance>("regionA", state1); var initialA = new PseudoState <Instance>("initialA", regionA, PseudoStateKind.Initial); var state3 = new State <Instance>("state3", regionA); var state8 = new State <Instance>("state8", regionA); var regionB = new Region <Instance>("regionB", state1); var initialB = new PseudoState <Instance>("initialB", regionB, PseudoStateKind.Initial); var state4 = new State <Instance>("state4", regionB); var state5 = new State <Instance>("state5", regionB); var regionBa = new Region <Instance>("regionBa", state4); var initialBa = new PseudoState <Instance>("initialBa", regionBa, PseudoStateKind.Initial); var state6 = new State <Instance>("state6", regionBa); var regionBb = new Region <Instance>("regionBb", state4); var initialBb = new PseudoState <Instance>("initialBb", regionBb, PseudoStateKind.Initial); var state7 = new State <Instance>("state7", regionBb); initial.To(state1); initialA.To(state3); initialB.To(state4); initialBa.To(state6); initialBb.To(state7); state3.To(state2).When <string>(c => c == "event2"); state3.To(state8).When <string>(c => c == "event1"); state7.To(state5).When <string>(c => c == "event2"); state7.To(state5).When <string>(c => c == "event1"); model.Validate(); var instance = new Instance("p3pp3r"); model.Initialise(instance); model.Evaluate(instance, "event2"); Trace.Assert(state2 == instance.GetCurrent(model.DefaultRegion), instance.GetCurrent(model.DefaultRegion).ToString()); Trace.Assert(state4 == instance.GetCurrent(regionB)); }
override public void VisitPseudoState(PseudoState <TInstance> pseudoState) { base.VisitPseudoState(pseudoState); if (pseudoState.Kind == PseudoStateKind.Choice || pseudoState.Kind == PseudoStateKind.Junction) { // [7] In a complete statemachine, a junction vertex must have at least one incoming and one outgoing transition. // [8] In a complete statemachine, a choice vertex must have at least one incoming and one outgoing transition. if (pseudoState.Outgoing.Count == 0) { Console.Error.WriteLine(pseudoState + ": " + pseudoState.Kind + " pseudo states must have at least one outgoing transition."); } // choice and junction pseudo state can have at most one else transition if (pseudoState.Outgoing.Where(transition => transition.guard == Transition <TInstance> .FalseGuard).Count() > 1) { Console.Error.WriteLine(pseudoState + ": " + pseudoState.Kind + " pseudo states cannot have more than one Else transitions."); } } else { // non choice/junction pseudo state may not have else transitions if (pseudoState.Outgoing.Where(transition => transition.guard == Transition <TInstance> .FalseGuard).Count() != 0) { Console.Error.WriteLine(pseudoState + ": " + pseudoState.Kind + " pseudo states cannot have Else transitions."); } if (pseudoState.IsInitial) { if (pseudoState.Outgoing.Count > 1) { // [1] An initial vertex can have at most one outgoing transition. // [2] History vertices can have at most one outgoing transition. Console.Error.WriteLine(pseudoState + ": initial/history pseudo states can have at most one outgoing transition."); } else if (pseudoState.Outgoing.Count == 1) { // [9] The outgoing transition from an initial vertex may have a behavior, but not a trigger or guard. if (pseudoState.Outgoing.Single().guard != Transition <TInstance> .TrueGuard) { Console.Error.WriteLine(pseudoState + ": initial pseudo states cannot have a guard condition."); } } } } }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var state1 = new State<Instance>("state1", model); var state2 = new State<Instance>("state2", model); var regionA = new Region<Instance>("regionA", state1); var initialA = new PseudoState<Instance>("initialA", regionA, PseudoStateKind.Initial); var state3 = new State<Instance>("state3", regionA); var state8 = new State<Instance>("state8", regionA); var regionB = new Region<Instance>("regionB", state1); var initialB = new PseudoState<Instance>("initialB", regionB, PseudoStateKind.Initial); var state4 = new State<Instance>("state4", regionB); var state5 = new State<Instance>("state5", regionB); var regionBa = new Region<Instance>("regionBa", state4); var initialBa = new PseudoState<Instance>("initialBa", regionBa, PseudoStateKind.Initial); var state6 = new State<Instance>("state6", regionBa); var regionBb = new Region<Instance>("regionBb", state4); var initialBb = new PseudoState<Instance>("initialBb", regionBb, PseudoStateKind.Initial); var state7 = new State<Instance>("state7", regionBb); initial.To(state1); initialA.To(state3); initialB.To(state4); initialBa.To(state6); initialBb.To(state7); state3.To(state2).When<string>(c => c == "event2"); state3.To(state8).When<string>(c => c == "event1"); state7.To(state5).When<string>(c => c == "event2"); state7.To(state5).When<string>(c => c == "event1"); model.Validate(); var instance = new Instance("p3pp3r"); model.Initialise(instance); model.Evaluate(instance, "event2"); Trace.Assert(state2 == instance.GetCurrent(model.DefaultRegion), instance.GetCurrent(model.DefaultRegion).ToString() ); Trace.Assert(state4 == instance.GetCurrent(regionB)); }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var stateA = new State<Instance>("stateA", model); var choice = new PseudoState<Instance>("choice", model, PseudoStateKind.Choice); initial.To(stateA); stateA.To(choice).When<string>(message => message == "choose"); choice.To(stateA).Effect(instance => instance.Int1++); choice.To(stateA).Effect(instance => instance.Int2++); choice.To(stateA).Effect(instance => instance.Int3++); model.Validate(); var instance1 = new Instance("instance1"); model.Initialise(instance1); for (var i = 0; i < 99; i++) { model.Evaluate(instance1, "choose"); } Trace.Assert(99 == (instance1.Int1 + instance1.Int2 + instance1.Int3)); Runtime.Extensions.RandomSelector = randRobin; var instance2 = new Instance("instance2"); model.Initialise(instance2); for (var i = 0; i < 99; i++) { model.Evaluate(instance2, "choose"); } model.Evaluate(instance2, "end"); Trace.Assert(33 == instance2.Int1); Trace.Assert(33 == instance2.Int2); Trace.Assert(33 == instance2.Int3); }
// select next leg of composite transitions after choice and junction pseudo states internal static Transition <TInstance> SelectTransition <TInstance>(this PseudoState <TInstance> pseudoState, TInstance instance, object message) where TInstance : IInstance <TInstance> { var results = pseudoState.Outgoing.Where(transition => transition.guard(message, instance)); if (pseudoState.Kind == PseudoStateKind.Choice) { return(results.Count() != 0 ? results.ElementAt(Extensions.RandomSelector(results.Count())) : pseudoState.FindElse()); } else { if (results.Count() > 1) { throw new Exception("Multiple outbound transition guards returned true at " + pseudoState + " for " + message); } else { return(results.SingleOrDefault() ?? pseudoState.FindElse()); } } }
/// <summary> /// Gets the state machine this vertex belongs to. /// </summary> /// <returns>An instance of <see cref="IStateMachine"/>.</returns> public IStateMachine ContainingStateMachine() { if (this.container != null) { return(this.container.ContainingStateMachine()); } else { if (this is PseudoState) { PseudoState pseudoState = this as PseudoState; return(pseudoState.ContainingStateMachine()); } else { ConnectionPointReference connectionPointReference = this as ConnectionPointReference; return(connectionPointReference.ContainingStateMachine()); } } }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model); var stateA = new State<Instance>("stateA", model); var terminate = new PseudoState<Instance>("terminate", model, PseudoStateKind.Terminate); initial.To(stateA); stateA.To(terminate).When<string>(message => message == "1"); model.Validate(); var instance = new Instance("terminate"); model.Initialise(instance); Trace.Assert(!model.Evaluate(instance, "2")); Trace.Assert(model.Evaluate(instance, "1")); Trace.Assert(!model.Evaluate(instance, "1")); Trace.Assert(instance.IsTerminated); }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model); var stateA = new State <Instance>("stateA", model); var terminate = new PseudoState <Instance>("terminate", model, PseudoStateKind.Terminate); initial.To(stateA); stateA.To(terminate).When <string>(message => message == "1"); model.Validate(); var instance = new Instance("terminate"); model.Initialise(instance); Trace.Assert(!model.Evaluate(instance, "2")); Trace.Assert(model.Evaluate(instance, "1")); Trace.Assert(!model.Evaluate(instance, "1")); Trace.Assert(instance.IsTerminated); }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var stateA = new State<Instance>("stateA", model).Exit(i => i.Int1 += 1); var stateB = new State<Instance>("stateB", model).Entry(i => i.Int1 += 2); initial.To(stateA); stateA.To(stateB).When<string>(message => message == "move").Effect(i => i.Int1 += 4); model.Validate(); var instance = new Instance("callbacks"); model.Initialise(instance); model.Evaluate(instance, "move"); Trace.Assert(1 == (1 & instance.Int1)); Trace.Assert(2 == (2 & instance.Int1)); Trace.Assert(4 == (4 & instance.Int1)); }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var stateA = new State <Instance>("stateA", model).Exit(i => i.Int1 += 1); var stateB = new State <Instance>("stateB", model).Entry(i => i.Int1 += 2); initial.To(stateA); stateA.To(stateB).When <string>(message => message == "move").Effect(i => i.Int1 += 4); model.Validate(); var instance = new Instance("callbacks"); model.Initialise(instance); model.Evaluate(instance, "move"); Trace.Assert(1 == (1 & instance.Int1)); Trace.Assert(2 == (2 & instance.Int1)); Trace.Assert(4 == (4 & instance.Int1)); }
public static void Run() { // create the state machine model elements var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var stateA = new State <Instance>("stateA", model); var stateB = new State <Instance>("stateB", model).Exit(i => i.Int1++); var bInitial = new PseudoState <Instance>("bInitial", stateB); var bStateI = new State <Instance>("bStateI", stateB); var bStateII = new State <Instance>("bStateII", stateB); // create the state machine model transitions initial.To(stateA); stateA.To(stateB).When <string>(message => message == "move"); bInitial.To(bStateI); stateB.To(bStateII, TransitionKind.Local).When <string>(message => message == "local"); stateB.To(bStateII, TransitionKind.External).When <string>(message => message == "external"); model.Validate(); // create a state machine instance var instance = new Instance("local"); // initialise the model and instance model.Initialise(instance); // send the machine instance a message for evaluation, this will trigger the transition from stateA to stateB model.Evaluate(instance, "move"); model.Evaluate(instance, "local"); Trace.Assert(0 == instance.Int1); model.Evaluate(instance, "external"); Trace.Assert(1 == instance.Int1); }
public static void Run () { // create the state machine model elements var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var stateA = new State<Instance>("stateA", model); var stateB = new State<Instance>("stateB", model).Exit(i => i.Int1++); var bInitial = new PseudoState<Instance>("bInitial", stateB); var bStateI = new State<Instance>("bStateI", stateB); var bStateII = new State<Instance>("bStateII", stateB); // create the state machine model transitions initial.To(stateA); stateA.To(stateB).When<string>(message => message == "move"); bInitial.To(bStateI); stateB.To(bStateII, TransitionKind.Local).When<string>(message => message == "local"); stateB.To(bStateII, TransitionKind.External).When<string>(message => message == "external"); model.Validate(); // create a state machine instance var instance = new Instance("local"); // initialise the model and instance model.Initialise(instance); // send the machine instance a message for evaluation, this will trigger the transition from stateA to stateB model.Evaluate(instance, "move"); model.Evaluate(instance, "local"); Trace.Assert(0 == instance.Int1); model.Evaluate(instance, "external"); Trace.Assert(1 == instance.Int1); }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial1 = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var myComposite1 = new State<Instance>("composite1", model); var state3 = new State<Instance>("state3", model); var initial2 = new PseudoState<Instance>("initial", myComposite1, PseudoStateKind.Initial); var state1 = new State<Instance>("state1", myComposite1); var state2 = new State<Instance>("state2", myComposite1); initial1.To(myComposite1); initial2.To(state1); myComposite1.To(state3).When<string>(c => c == "a"); state1.To(state2).When<string>(c => c == "a"); model.Validate(); var instance = new Instance("brice"); model.Initialise(instance); model.Evaluate(instance, "a"); Trace.Assert(instance.GetCurrent(myComposite1.DefaultRegion) == state2); }
static NormalState ParseState(XmlNode states_nd, XmlNamespaceManager xmlnsManager, int nestCount, List <NormalState> StateActionList) { StringBuilder spacer = new StringBuilder(); for (int i = 0; i < nestCount; i++) { spacer.Append(" "); } //Console.WriteLine($"{spacer}NodeType: " + states_nd.LocalName); var attrnd_id = states_nd.SelectSingleNode("@xmi.id"); //Console.WriteLine($"{spacer}xmi.id : " + attrnd_id.Value); var attrnd_name = states_nd.SelectSingleNode("@name"); //Console.WriteLine($"{spacer}xmi.name : " + attrnd_name.Value); var normalState = new NormalState { Id = attrnd_id.Value, Name = attrnd_name.Value }; AllStateList.Add(normalState); // 内部遷移 var internalTransitionNodes = states_nd.SelectNodes("UML:State.internalTransition/UML:Transition", xmlnsManager); foreach (XmlNode interTrans_nd in internalTransitionNodes) { string triggerName = "", actionName = ""; var triggerNode = interTrans_nd.SelectSingleNode("UML:Transition.trigger/UML:Event/@name", xmlnsManager); //Console.WriteLine($"{spacer}InterTrans Event[name]: " + triggerNode.Value); triggerName = triggerNode.Value; var actionNode = interTrans_nd.SelectSingleNode("UML:Transition.effect/UML:Action/@name", xmlnsManager); if (actionNode != null) { //Console.WriteLine($"{spacer}InterTrans Action[name]: " + actionNode.Value); actionName = actionNode.Value; } var events = new InternalEvent { Name = triggerName, MethodName = actionName }; AddTransition(triggerName, events); normalState.InternalEvent.Add(events); } // 開始疑似状態 var pseudoStates = states_nd.SelectSingleNode("UML:CompositeState.subvertex/UML:Pseudostate", xmlnsManager); if (pseudoStates != null) { var pseudo_id = pseudoStates.SelectSingleNode("@xmi.id"); var pseudo_name = pseudoStates.SelectSingleNode("@name"); PseudoState pseudoState = new PseudoState() { Id = pseudo_id.Value, Name = pseudo_name.Value }; normalState.PseudoState = pseudoState; AllStateList.Add(pseudoState); //Console.WriteLine($"{spacer}開始状態 {pseudo_name.Value} ({pseudo_id.Value})"); } // Entry var entryNode = states_nd.SelectSingleNode("UML:State.entry", xmlnsManager); if (entryNode != null) { normalState.EntryMethod = entryNode.SelectSingleNode("UML:Action/@name", xmlnsManager).Value; } // Exit var exitNode = states_nd.SelectSingleNode("UML:State.exit", xmlnsManager); if (exitNode != null) { normalState.ExitMethod = exitNode.SelectSingleNode("UML:Action/@name", xmlnsManager).Value; } StateActionList.Add(normalState); // サブ状態 var substatesList = states_nd.SelectNodes("UML:CompositeState.subvertex/UML:CompositeState", xmlnsManager); if (substatesList.Count > 0) { if (normalState.PseudoState == null) { throw new ApplicationException("サブ状態を定義している場合は、開始疑似状態が必須です。"); } foreach (XmlNode states_nd2 in substatesList) { normalState.SubState.Add( ParseState(states_nd2, xmlnsManager, nestCount + 1, StateActionList) ); } } return(normalState); }
// look for else transitins from a junction or choice internal static Transition <TInstance> FindElse <TInstance>(this PseudoState <TInstance> pseudoState) where TInstance : IInstance <TInstance> { return(pseudoState.Outgoing.Where(transition => transition.guard == Transition <TInstance> .FalseGuard).SingleOrDefault()); }
/// <summary> /// Visits a pseudo state within a state machine model. /// </summary> /// <param name="pseudoState">The pseudo state to visit.</param> /// <remarks>Prior to visiting the pseudo state, it is visited as the vertex type.</remarks> public virtual void VisitPseudoState(PseudoState <TInstance> pseudoState) { this.VisitVertex(pseudoState); }
public static void Run () { var model = new StateMachine<Instance>("model"); var initial = new PseudoState<Instance>("initial", model, PseudoStateKind.Initial); var ortho = new State<Instance>("ortho", model); var simple = new State<Instance>("simple", model); var final = new FinalState<Instance>("final", model); var r1 = new Region<Instance>("r1", ortho); var r2 = new Region<Instance>("r2", ortho); var i1 = new PseudoState<Instance>("initial", r1, PseudoStateKind.ShallowHistory); var i2 = new PseudoState<Instance>("initial", r2, PseudoStateKind.ShallowHistory); var s1 = new State<Instance>("s1", r1); var s2 = new State<Instance>("s2", r2); var f1 = new FinalState<Instance>("f1", r1); var f2 = new FinalState<Instance>("f2", r2); initial.To(ortho); i1.To(s1); i2.To(s2); ortho.To(final); // This should happen once all regions in ortho are complete? s1.To(f1).When<string>(c => c == "complete1"); s2.To(f2).When<string>(c => c == "complete2"); ortho.To(simple).When<string>(c => c == "jump"); simple.To(ortho).When<string>(c => c == "back"); model.Validate(); var instance = new Instance("muximise"); model.Initialise(instance); /* console.log("simple.isSimple = " + simple.isSimple()); console.log("simple.isComposite = " + simple.isComposite()); console.log("simple.isOrthogonal = " + simple.isOrthogonal()); console.log("model.isSimple = " + model.isSimple()); console.log("model.isComposite = " + model.isComposite()); console.log("model.isOrthogonal = " + model.isOrthogonal()); console.log("ortho.isSimple = " + ortho.isSimple()); console.log("ortho.isComposite = " + ortho.isComposite()); console.log("ortho.isOrthogonal = " + ortho.isOrthogonal()); */ Trace.Assert(simple.IsSimple); Trace.Assert(!model.IsSimple); Trace.Assert(!ortho.IsSimple); Trace.Assert(!simple.IsComposite); Trace.Assert(model.IsComposite); Trace.Assert(ortho.IsComposite); Trace.Assert(!simple.IsOrthogonal); Trace.Assert(!model.IsOrthogonal); Trace.Assert(ortho.IsOrthogonal); model.Evaluate(instance, "complete1"); model.Evaluate(instance, "complete2"); Trace.Assert(model.IsComplete(instance)); }
static void GenerateStateChartWorkflow(DirectoryInfo outputDirectory, XmlNode rootNode, XmlNode packageNode, XmlNamespaceManager xmlnsManager) { var packageName = packageNode.SelectSingleNode("@name").Value; var packageTagDict = GetPackageTagList(packageNode, xmlnsManager); // 状態遷移図取得 XmlNodeList stNodeList = packageNode.SelectNodes("*/UML:StateMachine[@xmi.id]", xmlnsManager); foreach (XmlNode stateNd in stNodeList) { List <NormalState> StateActionList = new List <NormalState>(); //< 状態遷移図内で、アクションを含む状態の一覧(開始疑似状態は除く) NormalState rootState = new NormalState(); // 状態遷移図のルート状態 var stateMachineId = stateNd.SelectSingleNode("@xmi.id", xmlnsManager).Value; var stateMachineName = stateNd.SelectSingleNode("@name", xmlnsManager).Value; string stateMachineFullName = packageName + "." + stateMachineName; string namespaceValue; if (packageTagDict.ContainsKey("namespace")) { namespaceValue = packageTagDict["namespace"]; } else { namespaceValue = packageName; } string namespaceDirectoryPath = namespaceValue.Replace(".", "/"); string pathOutputDirectory = Path.Combine(outputDirectory.FullName, namespaceDirectoryPath); Directory.CreateDirectory(pathOutputDirectory); string pathOutput = Path.Combine(pathOutputDirectory, $"{stateMachineFullName}.cs"); //Console.WriteLine("NodeType: " + nd.LocalName); var pseudoStates = stateNd.SelectSingleNode("UML:StateMachine.top/UML:CompositeState/UML:CompositeState.subvertex/UML:Pseudostate", xmlnsManager); if (pseudoStates != null) { if (rootState.PseudoState != null) { throw new ApplicationException("1つの状態内には、開始疑似状態は1つのみ設定できます。"); } var attrnd_id = pseudoStates.SelectSingleNode("@xmi.id"); var attrnd_name = pseudoStates.SelectSingleNode("@name"); PseudoState pseudoState = new PseudoState() { Id = attrnd_id.Value, Name = attrnd_name.Value }; AllStateList.Add(pseudoState); rootState.PseudoState = pseudoState; //Console.WriteLine($"開始状態 {attrnd_name.Value} ({attrnd_id.Value})"); } var statesList = stateNd.SelectNodes("UML:StateMachine.top/UML:CompositeState/UML:CompositeState.subvertex/UML:CompositeState", xmlnsManager); foreach (XmlNode states_nd in statesList) { rootState.SubState.Add( ParseState(states_nd, xmlnsManager, 0, StateActionList) ); } // 遷移取得 XmlNodeList transitonsNodeList = stateNd.SelectNodes("UML:StateMachine.transitions", xmlnsManager); foreach (XmlNode transition_nd in transitonsNodeList) { foreach (XmlNode transition_item in transition_nd.SelectNodes("UML:Transition", xmlnsManager)) { string transitionName = "", actionName = ""; var transition_bname = transition_item.SelectSingleNode("UML:Transition.trigger/UML:Event/@name", xmlnsManager); if (transition_bname != null) // Transition.triggerを持たない遷移もある(開始疑似状態からの遷移など) { //Console.WriteLine($"TransitionName = {transition_bname.Value}"); transitionName = transition_bname.Value; } var transition_effect = transition_item.SelectSingleNode("UML:Transition.effect/UML:Action/@name", xmlnsManager); if (transition_effect != null) { //Console.WriteLine($"ActionName = {transition_effect.Value}"); actionName = transition_effect.Value; } string srcId, destId; var transition_source = transition_item.SelectSingleNode("UML:Transition.source/UML:StateVertex/@xmi.idref", xmlnsManager); //Console.WriteLine($"Source = {transition_source.Value}"); srcId = transition_source.Value; var transition_target = transition_item.SelectSingleNode("UML:Transition.target/UML:StateVertex/@xmi.idref", xmlnsManager); //Console.WriteLine($"Target = {transition_target.Value}"); destId = transition_target.Value; var rs = from u in AllStateList where u.Id == srcId select u; var rd = from u in AllStateList where u.Id == destId select u; var srcState = rs.FirstOrDefault() as State; var destState = rd.FirstOrDefault() as State; if (srcState != null && destState != null) { if (srcState is PseudoState) { if (destState is NormalState normalState) { normalState.InitialAttribute = true; } } else { if (srcState is NormalState normalState_src && destState is NormalState normalState_dest) { var eventObj = new TransitionEvent { Name = transitionName, MethodName = actionName, Destination = normalState_dest }; normalState_src.TransitionEvent.Add(eventObj); AddTransition(transitionName, eventObj); } } } } } bool isFrameTransitionStateMachine = false; var tags = GetStateMachineTagList(stateMachineId, rootNode, xmlnsManager); if (tags.ContainsKey("FrameTransition") && tags["FrameTransition"].ToUpper() == "TRUE") { isFrameTransitionStateMachine = true; } Console.WriteLine(rootState.Dump(0)); // ステートマシンのワークフローを出力 using (System.IO.StreamWriter sw = new System.IO.StreamWriter(pathOutput)) { sw.WriteLine(@"using System; using System.Threading.Tasks; using System.Collections.Generic; using Hyperion.Pf.Workflow; using Appccelerate.StateMachine; using Appccelerate.StateMachine.Infrastructure; using Appccelerate.StateMachine.Machine; using Appccelerate.StateMachine.Persistence; using Appccelerate.StateMachine.Reports; using Hyperion.Pf.Workflow.StateMachine; "); sw.WriteLine("using " + DeclareDefineCodeNamespace + ";"); sw.WriteLine($"namespace {namespaceValue} {{"); if (isFrameTransitionStateMachine) { sw.WriteLine($"public partial class {stateMachineName} : FrameStateMachine<States, Events>, IAsyncPassiveStateMachine {{"); //sw.WriteLine($" public {stateMachineName}(Katalib.WPF.Infrastructures.IContent content) : base(content) {{ }}"); // 出力しない } else { sw.WriteLine($"public partial class {stateMachineName} : AppStateMachine<States, Events>, IAsyncPassiveStateMachine {{"); } sw.WriteLine($" public static string Name = \"{stateMachineFullName}\";"); sw.WriteLine("public void Setup() {"); rootState.ExportHierarchy(sw); Array.ForEach <NormalState>(StateActionList.Where(prop => prop is NormalState).Cast <NormalState>().ToArray(), prop => prop.ExportTransition(sw)); Array.ForEach <NormalState>(StateActionList.Where(prop => prop is NormalState).Cast <NormalState>().ToArray(), prop => prop.ExportEvent(sw, isFrameTransitionStateMachine)); var startSubState = rootState.StartSubState; sw.WriteLine($" Initialize(States.{startSubState.TinyName});"); sw.WriteLine("}"); Array.ForEach <NormalState>(StateActionList.Where(prop => prop is NormalState).Cast <NormalState>().ToArray(), prop => prop.ExportEventHandler(sw, isFrameTransitionStateMachine)); sw.WriteLine("}"); sw.WriteLine("}"); // end of namespace } } }
public static void Run() { var model = new StateMachine <Instance>("model"); var initial = new PseudoState <Instance>("initial", model, PseudoStateKind.Initial); var ortho = new State <Instance>("ortho", model); var simple = new State <Instance>("simple", model); var final = new FinalState <Instance>("final", model); var r1 = new Region <Instance>("r1", ortho); var r2 = new Region <Instance>("r2", ortho); var i1 = new PseudoState <Instance>("initial", r1, PseudoStateKind.ShallowHistory); var i2 = new PseudoState <Instance>("initial", r2, PseudoStateKind.ShallowHistory); var s1 = new State <Instance>("s1", r1); var s2 = new State <Instance>("s2", r2); var f1 = new FinalState <Instance>("f1", r1); var f2 = new FinalState <Instance>("f2", r2); initial.To(ortho); i1.To(s1); i2.To(s2); ortho.To(final); // This should happen once all regions in ortho are complete? s1.To(f1).When <string>(c => c == "complete1"); s2.To(f2).When <string>(c => c == "complete2"); ortho.To(simple).When <string>(c => c == "jump"); simple.To(ortho).When <string>(c => c == "back"); model.Validate(); var instance = new Instance("muximise"); model.Initialise(instance); /* * console.log("simple.isSimple = " + simple.isSimple()); * console.log("simple.isComposite = " + simple.isComposite()); * console.log("simple.isOrthogonal = " + simple.isOrthogonal()); * * console.log("model.isSimple = " + model.isSimple()); * console.log("model.isComposite = " + model.isComposite()); * console.log("model.isOrthogonal = " + model.isOrthogonal()); * * console.log("ortho.isSimple = " + ortho.isSimple()); * console.log("ortho.isComposite = " + ortho.isComposite()); * console.log("ortho.isOrthogonal = " + ortho.isOrthogonal()); */ Trace.Assert(simple.IsSimple); Trace.Assert(!model.IsSimple); Trace.Assert(!ortho.IsSimple); Trace.Assert(!simple.IsComposite); Trace.Assert(model.IsComposite); Trace.Assert(ortho.IsComposite); Trace.Assert(!simple.IsOrthogonal); Trace.Assert(!model.IsOrthogonal); Trace.Assert(ortho.IsOrthogonal); model.Evaluate(instance, "complete1"); model.Evaluate(instance, "complete2"); Trace.Assert(model.IsComplete(instance)); }