using System; namespace Bro.Common.AbstractFSM { public interface IStateManager : IDisposable { void ChangeState(object sender, StateEventArgs eventArgs); bool CheckState(object sender, StateEventArgs eventArgs); } public abstract class StatesManager : IStateManager { // Declare the delegate (if using non-generic pattern). public delegate void StateChangedEventHandler(object sender, StateEventArgs eventArgs); // Declare the event. public event StateChangedEventHandler StateChanged; public StatesManager() { //build transitions and set an initial state m_activeState = BuildTransitionsTable(); } public virtual void Dispose() { //virtual method } State m_activeState = null; public State ActiveState { get { return m_activeState; } } Transitions m_transitions = new Transitions(); public Transitions Transitions { get { return m_transitions; } } //returns initial state protected abstract State BuildTransitionsTable(); // public virtual void ChangeState(object sender, StateEventArgs eventArgs) { Transition transition = m_transitions[m_activeState, eventArgs]; m_activeState = transition.finalState; //raise 'StateChanged' event if (StateChanged != null) StateChanged(this, eventArgs); if (transition.action != null) transition.action(this, eventArgs); //if the transitional is automatic - automatically go to the next state: if (transition.AutoMode == true && transition.AutoTransition != null) { m_activeState = transition.AutoTransition.initialState; ChangeState(sender, transition.AutoTransition.eventArgs); } } public virtual bool CheckState(object sender, StateEventArgs eventArgs) { return m_transitions.ContainsKey(Transition.GetHashCode(m_activeState, eventArgs)); } } }