Ok, I have googled around this but found conflicting information and hideous reflection being used.
Context:
I have a generic state machine:
public class StateMachine<T>
{
protected Dictionary<T, StateHandler<T>> mHandlers;
public StateHandler<T> Current;
public StateMachine(StateHandler<T> _startState)
{
mHandlers = new Dictionary<T, StateHandler<T>>();
mHandlers.Add(_startState.StateCode, _startState);
_startState.Start(null);
Current = _startState;
}
public void Add(StateHandler<T> _new)
{
mHandlers.Add(_new.StateCode, _new);
}
public void ChangeState(T _new)
{
if (mHandlers.Count > 0)
{
if (Current.CanChange(_new))
{
StateHandler<T> a;
if (mHandlers.TryGetValue(_new, out a))
{
Current.Stop(a);
a.Start(Current);
Current = a;
}
else
{
throw new Exception("State machine does not contain a handler for " + _new);
}
}
else
{
throw new Exception("Invalid state change from " + Current.StateCode + " to " + _new);
}
}
}
}
Which contain a collection of state handlers:
public abstract class StateHandler<T>
{
public readonly T StateCode;
public abstract void Start(StateHandler<T> _oldState);
public abstract void Stop(StateHandler<T> _newState);
protected HashSet<T> mAllowedChanges;
public void AddAllowedChange(T _state)
{
mAllowedChanges.Add(_state);
}
public void RemoveAllowedChange(T _state)
{
mAllowedChanges.Remove(_state);
}
public bool CanChange(T _newState)
{
return mAllowedChanges.Contains(_newState);
}
public StateHandler(T _code)
{
mAllowedChanges = new HashSet<T>();
StateCode = _code;
}
}
This works really well. In my game I have a enum represeting possible states I can do this:
mGameStateManager = new StateMachine<MakiGameState>(a);
InGameState s = new InGameState();
s.Game = this;
s.AddAllowedChange(MakiGameState.Paused);
s.AddAllowedChange(MakiGameState.GameOver);
mGameStateManager.Add(s);
However I can use anything to represent the state code but I would really like to limit T to be a type of enum. I know how to limit generics using where but there doesnāt seem to be a way to force T to be of type enum only.
Any C# gurus have any advice?
Thanks.