Update:
Again thanks for the examples, they have been very helpful and with the following I don't mean to take anything away from them.
Aren't the currently given examples, as far as I understand them & state-machines, only half of what we usually understand by a state-machine?
In the sense that the examples do change state but that's only represented by changing the value of a variable (and allowing different value- changes in different states), while usually a state machine should also change it's behavior, and behavior not (only) in the sense of allowing different value changes for a variable depending on state, but in the sense of allowing different methods to be executed for different states.
Or do I have a misconception of state machines and their common use?
Best regards
Original question:
I found this discussion about state machines & iterator blocks in c# and tools to create state machines and what not for C#, so I found a lot of abstract stuff but as a noob all of this is a little confusing.
So it would be great if someone could provide a C# source code-example that realizes a simple state machine with perhaps 3,4 states, just to get the gist of it.
There are 2 popular state machine packages in NuGet.
Appccelerate.StateMachine (13.6K downloads + 3.82K of legacy version (bbv.Common.StateMachine))
StateMachineToolkit (1.56K downloads)
The Appccelerate lib has good documentation, but it does not support .NET 4, so I chose StateMachineToolkit for my project.
Im posting annother answer here as this is state machines from a different perspective; very visual.
My origianl answer is clasic imperitive code. I think its quite visual as code goes becuase of the array which makes visualising the state machine simple. The downside is you have to write all this. Remos's answer aleviates the effort of writing the boiler-plate code but is far less visual. There is the third alternative; really drawing the state machine.
If you are using .NET and can target version 4 of the run time then you have the option of using workflow's state machine activities. These in essence let you draw the state machine (much as in Juliet's diagram) and have the WF runtime execute it for you.
See the MSDN article Building State Machines with Windows Workflow Foundation for more details, and this CodePlex site for the latest version.
Thats the option I would always prefer when targeting .NET because its easy to see, change and explain to non programmers; pictures are worth a thousand words as they say!
I've just contributed this:
https://code.google.com/p/ysharp/source/browse/#svn%2Ftrunk%2FStateMachinesPoC
Here's one of the examples demoing direct and indirect sending of commands, with states as IObserver(of signal), thus responders to a signal source, IObservable(of signal):
Note : this example is rather artificial and mostly meant to demo a number of orthogonal features. There should seldomly be a real need to implement the state value domain itself by a full blown class, using the CRTP ( see : http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern ) like this.
Here's for a certainly simpler and likely much more common implementation use case (using a simple enum type as the states value domain), for the same state machine, and with the same test case :
https://code.google.com/p/ysharp/source/browse/trunk/StateMachinesPoC/WatchingTVSample.cs
'HTH
I would recommend state.cs. I personally used state.js (the JavaScript version) and am very happy with it. That C# version works in a similar way.
You instantiate states:
You instantiate some transitions:
You define actions on states and transitions:
And that's (pretty much) it. Look at the website for more information.
It's useful to remember that state machines are an abstraction, and you don't need particular tools to create one, however tools can be useful.
You can for example realise a state machine with functions:
This machine would hunt for gulls and try to hit them with water balloons. If it misses it will try firing one until it hits (could do with some realistic expectations ;)), otherwise it will gloat in the console. It continues to hunt until it's out of gulls to harass.
Each function corresponds to each state; the start and end (or accept) states are not shown. There are probably more states in there than modelled by the functions though. For example after firing the balloon the machine is really in another state than it was before it, but I decided this distinction was impractical to make.
A common way is to use classes to represent states, and then connect them in different ways.
I made this generic state machine out of Juliet's code. It's working awesome for me.
These are the benefits:
TState
andTCommand
,TransitionResult<TState>
to have more control over the output results of[Try]GetNext()
methodsStateTransition
only throughAddTransition(TState, TCommand, TState)
making it easier to work with itCode:
This is the return type of TryGetNext method:
How to use:
This is how you can create a
OnlineDiscountStateMachine
from the generic class:Define an enum
OnlineDiscountState
for its states and an enumOnlineDiscountCommand
for its commands.Define a class
OnlineDiscountStateMachine
derived from the generic class using those two enumsDerive the constructor from
base(OnlineDiscountState.InitialState)
so that the initial state is set toOnlineDiscountState.InitialState
Use
AddTransition
as many times as neededuse the derived state machine