Skip to content

Instantly share code, notes, and snippets.

@RevenantX
Created August 17, 2016 16:10

Revisions

  1. RevenantX renamed this gist Aug 17, 2016. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. RevenantX created this gist Aug 17, 2016.
    184 changes: 184 additions & 0 deletions LiteStateMachine
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,184 @@
    using System.Collections.Generic;

    namespace Game.Shared.Helpers
    {
    public interface IStateMachineOwner
    {
    StateMachine StateMachine { get; }
    }

    public interface IState
    {
    void Update(float deltaTime);
    void OnCommand(string command);
    void OnEnter();
    void OnExit();
    }

    public abstract class BasicState<T> : IState where T : IStateMachineOwner
    {
    private readonly T _owner;
    public T Owner { get { return _owner; } }

    protected BasicState(T owner)
    {
    _owner = owner;
    }

    protected void SetState(string state)
    {
    _owner.StateMachine.SetState(state);
    }

    protected string CurrentCommand
    {
    get { return _owner.StateMachine.CurrentCommand; }
    }

    public virtual void Update(float deltaTime) { }
    public virtual void OnCommand(string command) { }
    public virtual void OnEnter() { }
    public virtual void OnExit() { }
    }

    public abstract class TransitionState<T> : BasicState<T> where T : IStateMachineOwner
    {
    private float _timer;
    private bool _forward;

    public float TransitionTime = 1f;
    public string BackwardState { get; private set; }
    public string ForwardState { get; private set; }
    public string[] BackCommands { get; private set; }
    public string[] ForwardCommands { get; private set; }

    public float Progress { get { return _timer / TransitionTime; } }
    public float Timer { get { return _timer; } }
    public bool Forward { get { return _forward; } }

    protected TransitionState(T owner) : base(owner)
    {

    }

    public override void OnEnter()
    {
    _timer = 0f;
    }

    public sealed override void OnCommand(string command)
    {
    for (int i = 0; i < ForwardCommands.Length; i++)
    {
    if (ForwardCommands[i].Equals(command))
    {
    if (!_forward && _timer > 0f)
    {
    _timer = TransitionTime - _timer;
    }
    _forward = true;
    OnStartTransition(_forward);
    return;
    }
    }

    for (int i = 0; i < ForwardCommands.Length; i++)
    {
    if (BackCommands[i].Equals(command))
    {
    if (_forward && _timer > 0)
    {
    _timer = TransitionTime - _timer;
    }
    _forward = false;
    OnStartTransition(_forward);
    return;
    }
    }
    }

    protected virtual void OnStartTransition(bool forward)
    {

    }

    public void SetBackwardCommands(string backwardState, params string[] commands)
    {
    BackwardState = backwardState;
    BackCommands = commands;
    }

    public void SetForwardCommands(string forwardState, params string[] commands)
    {
    ForwardState = forwardState;
    ForwardCommands = commands;
    }

    public override void Update(float deltaTime)
    {
    _timer += deltaTime;
    if (_timer >= TransitionTime)
    {
    _timer = TransitionTime;
    SetState(_forward ? ForwardState : BackwardState);
    }
    }
    }

    public class StateMachine
    {
    private IState _currentState;
    private string _currentStateName;
    private string _currentCommand;
    private readonly Dictionary<string, IState> _states = new Dictionary<string, IState>();

    public string CurrentStateName
    {
    get { return _currentStateName; }
    }

    public IState CurrentState
    {
    get { return _currentState; }
    }

    public string CurrentCommand
    {
    get { return _currentCommand; }
    }

    public void SetState(string stateName, IState state)
    {
    _states[stateName] = state;
    }

    public void CallCommand(string command)
    {
    _currentCommand = command;
    _currentState.OnCommand(command);
    }

    public void Update(float deltaTime)
    {
    _currentState.Update(deltaTime);
    }

    public void Start(string startCommand, string startState)
    {
    _currentCommand = startCommand;
    _currentStateName = startState;
    _currentState = _states[startState];
    _currentState.OnEnter();
    _currentState.OnCommand(startCommand);
    }

    public void SetState(string state)
    {
    _currentState.OnExit();
    _currentStateName = state;
    _currentState = _states[state];
    _currentState.OnEnter();
    _currentState.OnCommand(_currentCommand);
    }
    }
    }