Project DescriptionRuntime interpreted statechart with hierarchical (composite) and orthogonal (concurrent) states. Join and fork transitions. History. Source code in C#. Independent from threading, synchronization and timer runtime services. A state machine "template" precomputes time consuming runtime checks (like finding the LCA of transitions) and thus reduces the per-instance costs.
The state machine approach is a fairly common technique for controlling a system with complex behaviour.
Several free implementations are available in different languages with partly subtle differences, e.g.
Andreas Huber "The Boost Statechart Library" (http://www.boost.org/libs/statechart/doc/index.html)
Rainer Hessmer "qf4net: Quantum Framework for .Net" (http://www.hessmer.org/dev/qhsm/)
Leslie Sanford "A .NET State Machine Toolkit" (http://www.codeproject.com/script/Articles/Article.aspx?aid=11663)
Unfortunately the very thorough implementation from Boost is in C++ and I doubt it can be ported to C# due to its massive usage of C++ generic programming. Therefore other approaches and proposals are needed. This project provides one.
Using StaMa a state machine is defined in code by building a tree structure of states and transitions. States carry entry and exit actions as delegates, likewise transitions carry a delegate for the transition action. During excution the tree of states is traversed to find the transition triggered by a signal. Action delegates are executed traversing the tree of states.
Supplementary visual modelling and partial code generation from the visual model is provided through a Microsoft Visio script.
Sample complex state machineCode and Microsoft Visio diagram is part of the release download.
Sample code for a simple state machineCorresponding Visio diagram below.
namespace SimpleWatch
{
class AppMain
{
[STAThread]
static void Main(string[] args)
{
SimpleWatch watch = new SimpleWatch();
watch.SendTriggerEvent(SimpleWatch.Event.LeftButtonPressed);
watch.SendTriggerEvent(SimpleWatch.Event.RightButtonPressed);
watch = null;
}
}
// The wrapper around the state machine controller provides the code of the entry and exit callbacks.
class SimpleWatch
{
public enum Event
{
RightButtonPressed,
LeftButtonPressed
}
// The state machine controller.
private StateMachine m_stateMachine = null;
public SimpleWatch()
{
StateMachineTemplate t = new StateMachineTemplate();
//## Begin Structure
// Generated from <file:S:\StaMa_State_Machine_Controller_Library\Samples\Clock\DlgMain.vst>
// at 01-31-2008 23:20:24 using StaMaShapes Version 2
t.Region("DisplayTime", false);
t.State("DisplayDate", EnterDisplayDate, null);
t.Transition("RightButtonPressed", "DisplayDate", "DisplayTime", Event.RightButtonPressed, null, null);
t.EndState();
t.State("DisplayTime", EnterDisplayTime, null);
t.Transition("LeftButtonPressed", "DisplayTime", "DisplayDate", Event.LeftButtonPressed, null, null);
t.EndState();
t.EndRegion();
//## End Structure
m_stateMachine = t.CreateStateMachine();
m_stateMachine.Startup();
System.Console.WriteLine("After startup. Active state is {0}", m_stateMachine.ToString());
}
// Forwards the trigger events to the embedded state machine
public void SendTriggerEvent(Event ev)
{
m_stateMachine.SendTriggerEvent(ev, null);
System.Console.WriteLine("After event {0}. Active state is {1}", ev, m_stateMachine.ToString());
}
// Entry callback method for state "DisplayTime".
private void EnterDisplayDate(StateMachine stateMachine, object triggerEvent, EventArgs eventArgs)
{
System.Console.WriteLine("EnterDisplayDate called.");
}
// Entry callback method for state "DisplayDate".
private void EnterDisplayTime(StateMachine stateMachine, object triggerEvent, EventArgs eventArgs)
{
System.Console.WriteLine("EnterDisplayTime called.");
}
}
}

Comments are greatly appreciated. If You decide to evaluate or actually use StaMa in some real world application it would be excellent if You leave a note whether or not StaMa met Your needs.