Last active
August 7, 2016 01:30
-
-
Save Danielmelody/42da732e4c5325340c9ba83f28a84575 to your computer and use it in GitHub Desktop.
Simple State Machine for Generally Use in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simple State Machine with clever transition-event management | |
// created by yiminghu:github.com/Danielhu | |
using System.Collections.Generic; | |
public class StateMachine<StateType>{ | |
public delegate void TransitionDelegate(); | |
public StateType current { | |
get { return currentState; } | |
} | |
StateType currentState; | |
Dictionary<StateType, Dictionary<StateType, TransitionDelegate>> stateChangeEvents; | |
Dictionary<StateType, TransitionDelegate> onStateEnterEvents; | |
Dictionary<StateType, TransitionDelegate> onStateLeaveEvents; | |
Dictionary<StateType, HashSet<StateType>> forbidenTrasitions; | |
public StateMachine() { | |
stateChangeEvents = new Dictionary<StateType, Dictionary<StateType, TransitionDelegate>> (); | |
onStateEnterEvents = new Dictionary<StateType, TransitionDelegate> (); | |
onStateLeaveEvents = new Dictionary<StateType, TransitionDelegate> (); | |
forbidenTrasitions = new Dictionary<StateType, HashSet<StateType>> (); | |
} | |
public void forbidTrasition(StateType fromState, StateType toState) { | |
HashSet<StateType> toForbiddenList; | |
if (!forbidenTrasitions.TryGetValue (fromState, out toForbiddenList)) { | |
forbidenTrasitions.Add (fromState, new HashSet<StateType>()); | |
} | |
if (!forbidenTrasitions [fromState].Contains (toState)) { | |
forbidenTrasitions [fromState].Add (toState); | |
} | |
} | |
public void addOnStateEnterEvent (StateType state, TransitionDelegate onChange) { | |
if (!onStateEnterEvents.ContainsKey(state)){ | |
onStateEnterEvents.Add (state, onChange); | |
} else { | |
onStateEnterEvents [state] += onChange; | |
} | |
} | |
public void addOnStateLeaveEvent (StateType state, TransitionDelegate onChange) { | |
if (!onStateLeaveEvents.ContainsKey(state)){ | |
onStateLeaveEvents.Add (state, onChange); | |
} else { | |
onStateLeaveEvents [state] += onChange; | |
} | |
} | |
public void addOnStateChangeEvent(StateType fromState, StateType toState, TransitionDelegate onChange) { | |
if (fromState.Equals(toState)) { | |
Debug.LogWarning ("cannot add change events because from and to events are equal"); | |
return; | |
} | |
if (!stateChangeEvents.ContainsKey (fromState)) { | |
stateChangeEvents.Add (fromState, new Dictionary<StateType, TransitionDelegate> ()); | |
} | |
if (!stateChangeEvents [currentState].ContainsKey (toState)) { | |
stateChangeEvents [fromState].Add (toState, onChange); | |
} else { | |
stateChangeEvents [fromState] [toState] += onChange; | |
} | |
} | |
public void changeState(StateType state) { | |
if (state.Equals(currentState)) { | |
Debug.LogWarning ("state not change"); | |
return; | |
} | |
if (forbidenTrasitions.ContainsKey (currentState)) { | |
if (forbidenTrasitions [currentState].Contains (state)) { | |
Debug.Log ("transition has been forbidden"); | |
return; | |
} | |
} | |
Dictionary<StateType, TransitionDelegate> fromDict; | |
if (stateChangeEvents.TryGetValue (currentState, out fromDict)) { | |
TransitionDelegate trans; | |
if (stateChangeEvents [currentState].TryGetValue (state, out trans)) { | |
trans (); | |
} | |
} | |
TransitionDelegate leaveTrans; | |
if (onStateLeaveEvents.TryGetValue (currentState, out leaveTrans)) { | |
leaveTrans (); | |
Debug.LogWarning ("leave trans"); | |
} | |
TransitionDelegate enterTrans; | |
if (onStateEnterEvents.TryGetValue (state, out enterTrans)) { | |
enterTrans (); | |
} | |
currentState = state; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment