Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace EstotyWorld.StateMachines
- {
- public class StateMachine<TContext>
- {
- private Dictionary<Type, BaseState<TContext>> map;
- public TContext Context { get; private set; }
- public BaseState<TContext> CurrentState { get; private set; }
- public StateMachine(TContext context)
- {
- Context = context;
- map = new Dictionary<Type, BaseState<TContext>>();
- CurrentState = null;
- }
- public void AddState(BaseState<TContext> state)
- {
- Type stateType = state.GetType();
- if (map.ContainsKey(stateType))
- {
- throw new InvalidOperationException(
- $"[StateMachine] AddState: State {stateType.Name} is already in map"
- );
- }
- if (!state.ValidateMachine(this))
- {
- state.Setup(this);
- }
- map.Add(stateType, state);
- }
- public T AddState<T>() where T : BaseState<TContext>, new()
- {
- T state = new T();
- AddState(state);
- return state;
- }
- public void ChangeStateTo<T>() where T : BaseState<TContext>
- {
- if (CurrentState != null)
- {
- CurrentState.OnExit();
- }
- Type stateType = typeof(T);
- if (map.TryGetValue(stateType, out BaseState<TContext> state))
- {
- CurrentState = state;
- CurrentState.OnEnter();
- }
- else
- {
- throw new InvalidOperationException(
- $"[StateMachine] ChangeStateTo<{stateType.Name}>: State not found in map"
- );
- }
- }
- public bool InState<T>() where T : BaseState<TContext>
- {
- return CurrentState != null
- && CurrentState.GetType() == typeof(T);
- }
- }
- }
- namespace EstotyWorld.StateMachines
- {
- public abstract class BaseState<TContext>
- {
- private StateMachine<TContext> machine;
- protected StateMachine<TContext> Machine => machine;
- protected TContext Context => machine.Context;
- public virtual void Setup(StateMachine<TContext> machine)
- {
- this.machine = machine;
- }
- public bool ValidateMachine(object refMachine)
- {
- return machine != null
- && machine == refMachine;
- }
- /// <summary> Called once, when the StateMachine enters this state </summary>
- public abstract void OnEnter();
- /// <summary> Called once, when the State Machine exits from this state </summary>
- public abstract void OnExit();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement