Skip to content

Instantly share code, notes, and snippets.

@takazerker
Last active July 23, 2022 17:07
Show Gist options
  • Save takazerker/c62ebf6b8d9d287b20b4de660a5a897b to your computer and use it in GitHub Desktop.
Save takazerker/c62ebf6b8d9d287b20b4de660a5a897b to your computer and use it in GitHub Desktop.
C# StateMachine
//=============================================================================
// Licensed under CC0. Takanori Shibasaki
//=============================================================================
using System.Collections.Generic;
using System.Runtime.CompilerServices;
public abstract class StateBase
{
public virtual void Begin() { }
public virtual void End() { }
}
public abstract class GenericState<OwnerType> : StateBase where OwnerType : class
{
OwnerType m_Owner;
protected OwnerType Owner
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return m_Owner;
}
}
public virtual void Setup(OwnerType owner)
{
m_Owner = owner;
}
public virtual void Reset()
{
m_Owner = null;
}
}
public static class StatePool<OwnerType, StateType>
where OwnerType : class
where StateType : GenericState<OwnerType>
{
static List<StateType> m_States = new List<StateType>();
public static T Get<T>() where T : StateType, new()
{
var list = m_States;
T result;
for (var i = 0; i < list.Count; ++i)
{
if (list[i].GetType() == typeof(T))
{
result = list[i] as T;
list.RemoveAt(i);
return result;
}
}
result = new T();
return result;
}
public static void Release(StateType state)
{
state.Reset();
m_States.Add(state);
}
}
public struct StateMachine<OwnerType, StateType>
: System.IDisposable
where OwnerType : class
where StateType : GenericState<OwnerType>
{
public readonly OwnerType Owner;
StateType m_State;
public StateMachine(OwnerType owner)
{
Owner = owner;
m_State = null;
}
public StateType Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return m_State;
}
}
public void Dispose()
{
if (m_State != null)
{
m_State.End();
StatePool<OwnerType, StateType>.Release(m_State);
m_State = null;
}
}
public bool IsInState<T>() where T: StateType
{
return m_State is T;
}
public T GotoState<T>() where T : StateType, new()
{
if (m_State != null)
{
m_State.End();
StatePool<OwnerType, StateType>.Release(m_State);
m_State = null;
}
var nextState = StatePool<OwnerType, StateType>.Get<T>();
nextState.Setup(Owner);
nextState.Begin();
m_State = nextState;
return nextState;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment