Blog Archive

Friday, July 13, 2012

State Machine Desing Pattern






  #region SM definition and setup

    public interface IState
    {
        void EventSink(string eventData);
        void GoToNextState();
    }

    public class StateMachine
    {
        List _states ;
        public IState CurrentState { get; set; }
        public StateMachine()
        {
            _states = new List() { new State1(this), new State2(this)};  // omited Start and End State
        }

        public void SignalEvent(string infor)
        {
            if (infor == "Start")
            {
                CurrentState = (from _ in _states where _.GetType() == typeof(State1) select _).FirstOrDefault();
            }
            CurrentState.EventSink(infor);
        }

        internal void MoveState(IState st)
        {
            if (st.GetType() == typeof(State1))  // State2 would have move to End State
                CurrentState = (from _ in _states where _.GetType() == typeof(State2) select _).FirstOrDefault();
        }
    }

    #endregion


    #region Concrete States

    public class State1 : IState
    {
        StateMachine _sm;
        public State1(StateMachine sm)
        {
            _sm = sm;
        }
        public void EventSink(string eventData)
        {
            if (eventData == "RequiredInforType1Received")
            {
                Console.WriteLine("Processing Type1 Infor");
                Console.WriteLine("Passed, move to state2");
                GoToNextState();
            }
        }

        public void GoToNextState()
        {
            _sm.MoveState(this);
        } 
  
    }


    public class State2 : IState
    {
        StateMachine _sm;
        public State2(StateMachine sm)
        {
            _sm = sm;
        }
        public void EventSink(string eventData)
        {
            if (eventData == "RequiredInforType2Received")
            {
                Console.WriteLine("Processing Type2 Infor");
                Console.WriteLine("Passed, move to end state");
                GoToNextState();
            }
        }

        public void GoToNextState()
        {
            _sm.MoveState(this);
        }
    }

    #endregion

        static void Main(string[] args)
        {
            StateMachine sm = new StateMachine();
            sm.SignalEvent("Start");
            sm.SignalEvent("RequiredInforType1Received");
            sm.SignalEvent("RequiredInforType12Received");
            
            Console.ReadKey();
        }

No comments: