Click here to Skip to main content
15,884,099 members
Articles / Programming Languages / C#

A Simple State Machine

Rate me:
Please Sign up or sign in to vote.
4.67/5 (28 votes)
23 Jan 2014CPOL3 min read 121.7K   4.6K   117  
Create loose coupled States using a Finite State Automation (FSM) model.
using System;
using System.Collections.Generic;  

namespace AbstractFSM
{
    //actions that are performed when state changed
    public delegate void StateAction(object sender, StateEventArgs eventArgs);

    public class Transition
    {
        private State m_initialState;
        public State initialState
        {
            get { return m_initialState; }
        }
        private StateEventArgs m_eventArgs;
        public StateEventArgs eventArgs
        {
            get { return m_eventArgs; }
        }
        private State m_finalState;
        public State finalState
        {
            get { return m_finalState; }
        }
        private StateAction m_state_action;
        public StateAction action
        {
            get { return m_state_action; }
        }
        private bool m_autoMode = false;
        public bool AutoMode
        {
            get { return m_autoMode; }
        }

        private Transition m_autoTransition = null;
        public Transition AutoTransition
        {
            get { return m_autoTransition; }
        }

        public Transition(State initialState, StateEventArgs sevent, State finalState, StateAction action)
        {
            m_initialState = initialState;
            m_eventArgs = sevent;
            m_finalState = finalState;
            m_state_action = action;
        }
        public Transition(State initialState, StateEventArgs sevent, State finalState, StateAction action, bool autoMode, Transition autoTransition) 
                         : this(initialState, sevent, finalState, action)    
        {
            m_autoMode = autoMode;
            m_autoTransition = autoTransition; 
        }
        public override int GetHashCode()
        {
            //create a unique transition key
            return GetHashCode(m_initialState, m_eventArgs);
        }

        public static int GetHashCode(State state, StateEventArgs sevent)
        {
            return (state.GetHashCode() << 8) + sevent.Id;
        }
    }
    /// <summary>
    /// Represents a collection of transition objects.
    /// </summary>
    public class Transitions : System.Collections.Generic.Dictionary <int, Transition>   
    {
        /// <summary>Adds the specified transition to the collection.</summary> 
        /// <param name="transition">Transition object</param>      
        /// <see cref="System.Collections.Generic.Dictionary {int, Transition}"/>
        /// <exception cref="System.ArgumentNullException">Key is null</exception>
        /// <exception cref="System.ArgumentException">An transition with the same key already exists.</exception>
        public void Add(Transition transition)
        {
            // The Add method throws an exception if the new key is already in the dictionary.
            try
            {
                base.Add(transition.GetHashCode(), transition);
            }
            catch (ArgumentException)
            {
                throw new ArgumentException("A transition with the key (Initials state " + 
                        transition.initialState + ", Event " + 
                        transition.eventArgs + ") already exists.");
            }  
        }
        //
        public Transition this[State state, StateEventArgs sevent]
        {
            get
            {
                try
                {
                    return this[Transition.GetHashCode(state, sevent)];
                }
                catch(KeyNotFoundException)
                {
                    throw new KeyNotFoundException("The given transition was not found.");
                }
            }
            set
            {
                this[Transition.GetHashCode(state, sevent)] = value;
            }
        }
        //
        public bool Remove(State state, StateEventArgs sevent)
        {
            return base.Remove(Transition.GetHashCode(state, sevent));   
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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


Written By
Software Developer (Senior)
Canada Canada
Has been engaging in software development for over 15 years. Has deliberately chosen this path and has no compunction about it at all. Has a nasty habit of sharing his 'out-of-office' code hoping to get some positive feedback. Smile | :)

Comments and Discussions