Project Description
Runtime 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 machine
Code and Microsoft Visio diagram is part of the release download.

ClockSample.png


Sample code for a simple state machine
Corresponding 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.");
        }
    }
}


SimpleClockSample.png

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.
Last edited Feb 6 2008 at 9:48 PM by RolandSchneider, version 8

 

Want to leave feedback?
Please use Discussions or Reviews instead.

Archived page comments (1)

Updating...
© 2006-2009 Microsoft | About CodePlex | Privacy Statement | Terms of Use | Code of Conduct | Advertise With Us | Version 2009.10.27.15987