Click here to Skip to main content
13,201,451 members (74,015 online)
Click here to Skip to main content
Add your own
alternative version


19 bookmarked
Posted 18 Feb 2011

Hierarchy XML Based C# Statemachine Generator

, 23 Feb 2011
Rate this:
Please Sign up or sign in to vote.
Design a Statemachine in XML and generate a C# code representing it.


This article discusses how to create hierarchical statemachines based in XML with C# code-behind.


Statemachines allow us to represent a problem in a concrete and manageable form that generally has a common solution. The Statemachine code allows one to write a hierarchical based statemachine using XML and generate a corresponding C# code file representing the statemachine with all the semantics needed to execute the statemachine.

Creating a Statemachine

The majority of code to use the statemachine is simply writing it in XML:

<StateMachines name="<NamespaceName>" xmlns="StateMachines">
    <StateMachine name="<ClassName>">
            <State name="<StateName>"/>
            <Event name="<EventName>"/>
            <Transition from="<StateName>"

                to="<StateName>" trigger="<EventName>"/>

A State element can be another StateMachine with the exact same format. The correct XML formatting is provided through a schema, but valid references are not checked. The following C# code is generated from the XML:

using StateMachines;

namespace StateMachines.NamespaceName
    public partial class ClassName :
    StateMachine<ClassName.States, ClassName.Events, ClassName.Transitions>
        public enum States

        public enum Events

        public enum Transitions

        public ClassName()
            _States[(int)States.StateName] =
                (this.New(this, States.StateName));

            InitialState = _States[(int)States.StateName];
            _currentState = InitialState;

            [(int)Transitions.EventName__StateName_StateName] =
            new Transition<States, Events, Transitions>
            (States.StateName, States.StateName, Events.EventName);
            Transitions.EventName__StateName_StateName].Conditions =
            new Condition(() => { return true; });

        public new void Fire(ClassName.Events Event, params object[] args)
                case Events.EventName:
                if (_Transitions[(int)Transitions.EventName__
                    CurrentState =

        // User defined functions. Must Implement.
        // Comment out or remove these declarations when used.

To use the code, you simply have to instantiate the statemachine, add handlers to its events, then fire them. To generate the statemachine, you must add the file to the parser.


States are objects representing the states in a statemachine. They cannot be instantiated by anything but the StateMachine and have low weight. A statemachine itself is a state.


Standard OnEnter and OnLeave events exist for all states.


Each transition can have an optional set of conditions that must be passed for the transition to take place. This is to reduce the complexity to set up complex conditions. A transition may have a hierarchical conditional block that will be evaluated before a transition takes place.

    <Transition from="<StateName>" to="<StateName>" trigger="<EventName>">
        <Conditions op="<OperationType>">
            <Condition name="<ConditionName" op="<OperationType>">

<Conditions> adds a block of conditions and maybe nested. A <Condition> references a method in the class by "ConditionName", and op is the operation to combine the conditions.

Adding Functionality

In the sample code, there is an example of a statemachine of a mouse interacting with objects. The basic code of this machine is:

void B_MouseEnter(object sender, MouseEventArgs e)
    switch (mouseSM.CurrentState._State)
        case MouseSM.States.Waiting :
            mouseSM.Waiting.Fire(Waiting.Events.IntoObject, sender);

        case MouseSM.States.LeftButton :
                (LeftButton.Events.IntoObject, sender);

        case MouseSM.States.RightButton :
                (RightButton.Events.IntoObject, sender);

        default: break;

    CurrentState.Text = mouseSM.ActiveState.ToString();

The handler here simply fires the appropriate event off when an object (a Button in this case) is interacted with. ForceCurrentState is used in this case to make all the top level states follow each other when they are over a button or not. This is so we enter the correct substate. This could be avoided by using a common class of events and rewriting the statemachine. In this case, we actually have three statemachines working simultaneously. That is being on or off a button, and that of the mouse button being down or not. A third statemachine can be used to manage the possible combinational outcomes of those two. This could also be implemented as one statemachine and having states such as LeftButtonOnObject and LeftButtonOffObject.

We also hook up OnEvents and OnLeaves in the sample code without console output.


The usefulness of this code is to reduce all the boilerplate code required in implementing the statemachine along with the type safety of C#. The major point of posting this code is to provide a foundation for your own statemachine code projects. While T4 is used, it was designed in such a way that it is not required and the code generation can easily be migrated to its own executable. One could add a visual frontend to generate the statemachines.

The files required in the project are:

  • StateMachine.cs
  • StateMachine.xsd

Things To Do

Add the ability to use a common set of events, transitions, states, and conditions. This may make the statemachine overly complex but can reduce complexity in some cases significantly.


  • v0.5 - 02/19/2011 - First release.
  • v0.55 - 02/21/2011 - Added local state fields for easy state access. Updated passing data to event handlers.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralMy vote of 4 Pin
Kanasz Robert5-Nov-12 2:48
mvpKanasz Robert5-Nov-12 2:48 
GeneralMy vote of 4 Pin
lluism6526-Feb-11 10:43
memberlluism6526-Feb-11 10:43 
Generalsuggestion in StateMachine.cs Pin
lluism6526-Feb-11 10:35
memberlluism6526-Feb-11 10:35 
GeneralRe: suggestion in StateMachine.cs Pin
Jon_Slaughter26-Feb-11 11:55
memberJon_Slaughter26-Feb-11 11:55 
QuestionSuggestions? Pin
Jon_Slaughter24-Feb-11 10:46
memberJon_Slaughter24-Feb-11 10:46 
GeneralPls provide example of MouseSM.cs Pin
JohnWindy19-Feb-11 11:42
memberJohnWindy19-Feb-11 11:42 
GeneralRe: Pls provide example of MouseSM.cs [modified] Pin
Jon_Slaughter19-Feb-11 11:56
memberJon_Slaughter19-Feb-11 11:56 
GeneralRe: Pls provide example of MouseSM.cs Pin
JohnWindy24-Feb-11 14:02
memberJohnWindy24-Feb-11 14:02 
GeneralRe: Pls provide example of MouseSM.cs Pin
Jon_Slaughter26-Feb-11 12:04
memberJon_Slaughter26-Feb-11 12:04 
GeneralRe: Pls provide example of MouseSM.cs Pin
vishnu5721-Oct-13 5:13
membervishnu5721-Oct-13 5:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171020.1 | Last Updated 23 Feb 2011
Article Copyright 2011 by Jon_Slaughter
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid