This little project was born from an old (but good) state machine written in C++, with the goal to improve it and make it object-oriented and suited for a .NET application.
Special thanks to the stateless project, that helped me pretty much.
StateMachine has a simple workflow. It requires the definition of states, transitions between them and actions which can be performed when entering or exiting a state and when going from one to another.
The example below describes a three-states machine with trasitions from/to the next one.
enumStates{R,G,B}StateMachine<States>machine=newStateMachine<States>();machine.AddState(States.R);machine.AddState(States.G);machine.AddState(States.B);machine.AddTransition(States.R,States.G);machine.AddTransition(States.R,States.B);machine.AddTransition(States.G,States.R);machine.AddTransition(States.G,States.B);machine.AddTransition(States.B,States.R);machine.AddTransition(States.B,States.G);machine.AddEnterStateCallback(States.R,(state)=>Console.WriteLine("Entering state {0}",state));machine.AddEnterStateCallback(States.G,(state)=>Console.WriteLine("Entering state {0}",state));machine.AddEnterStateCallback(States.B,(state)=>Console.WriteLine("Entering state {0}",state));machine.AddExitStateCallback(States.R,(state)=>Console.WriteLine("Exiting state {0}",state));machine.AddExitStateCallback(States.G,(state)=>Console.WriteLine("Exiting state {0}",state));machine.AddExitStateCallback(States.B,(state)=>Console.WriteLine("Exiting state {0}",state));machine.AddTransitionCallback(States.R,States.G,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));machine.AddTransitionCallback(States.R,States.B,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));machine.AddTransitionCallback(States.G,States.R,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));machine.AddTransitionCallback(States.G,States.B,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));machine.AddTransitionCallback(States.B,States.R,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));machine.AddTransitionCallback(States.B,States.G,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));StateMachine<States>machine=newStateMachine<States>();When declaring, StateMachine accepts an enum that indicates the states type.
machine.AddState(States.R);Call the AddState() method to add the state to the machine.
machine.AddTransition(States.R,States.G);Call the AddTransition() method to add a new transition between two states.
The actions performed by StateMachine can be defined using delegates. They will be kept in memory by StateMachine and executed when desired.
machine.AddEnterStateCallback(States.R,(state)=>Console.WriteLine("Entering state {0}",state));machine.AddExitStateCallback(States.R,(state)=>Console.WriteLine("Exiting state {0}",state));machine.AddTransitionCallback(States.R,States.G,(from,to)=>Console.WriteLine("Going from {0} to {1}",from,to));The two state methods want the related state or states followed by the delegate. The first one accept the target state as a parameter, while the transition method wants the source state and the target one.
To keep track of what happens inside StateMachine, two event handlers have been implemented, Transiting and Transited.
machine.Transiting+=newEventHandler<TransitingEventArgs<States>>(TransitingEventHandler);machine.Transited+=newEventHandler<TransitedEventArgs<States>>(callbacks.TransitedEventHandler);
...
private void TransitingEventHandler(objectsender,TransitingEventArgse){Console.WriteLine("Event fired: Transiting into state {0}",e.State);}privatevoidTransitedEventHandler(objectsender,TransitedEventArgse){Console.WriteLine("Event fired: Transited into state {0}",e.State);}The transiting event fires before the exiting callbacks, while the Transited one is fired at the end of the process (after the entering callbacks).
