Last active
July 23, 2022 17:07
-
-
Save takazerker/c62ebf6b8d9d287b20b4de660a5a897b to your computer and use it in GitHub Desktop.
C# StateMachine
This file contains 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
//============================================================================= | |
// 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