forked from sin365/AxibugEmuOnline
116 lines
3.2 KiB
C#
116 lines
3.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace AxibugEmuOnline.Client.Tools
|
|
{
|
|
public class SimpleFSM<HOST>
|
|
{
|
|
private Dictionary<Type, State> m_states = new Dictionary<Type, State>();
|
|
private State m_current;
|
|
|
|
public HOST Host { get; private set; }
|
|
|
|
public SimpleFSM(HOST host)
|
|
{
|
|
Host = host;
|
|
}
|
|
|
|
public State CurrentState => m_current;
|
|
public T AddState<T>() where T : State, new()
|
|
{
|
|
var stateType = typeof(T);
|
|
|
|
if (m_states.ContainsKey(stateType)) { return null; }
|
|
|
|
var state = State.CreateState<T>(this);
|
|
m_states.Add(typeof(T), state);
|
|
|
|
return (T)state;
|
|
}
|
|
|
|
public void BackToLast()
|
|
{
|
|
if (m_current == null) return;
|
|
if (m_current.LastState == null) return;
|
|
|
|
if (m_states.Values.FirstOrDefault(s => s == m_current.LastState) is State lastState)
|
|
{
|
|
m_current.LastState = null;
|
|
m_current.OnExit(lastState);
|
|
|
|
lastState.OnEnter(m_current);
|
|
m_current = lastState;
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (m_current != null)
|
|
{
|
|
m_current.OnExit(null);
|
|
m_current = null;
|
|
}
|
|
|
|
foreach (var state in m_states.Values)
|
|
state.LastState = null;
|
|
}
|
|
|
|
public void ChangeState<T>() where T : State, new()
|
|
{
|
|
var stateType = typeof(T);
|
|
m_states.TryGetValue(stateType, out State nextState);
|
|
|
|
if (nextState == null) return;
|
|
|
|
if (m_current != null) m_current.OnExit(nextState);
|
|
nextState.LastState = m_current;
|
|
nextState.OnEnter(m_current);
|
|
m_current = nextState;
|
|
}
|
|
|
|
public T GetState<T>() where T : State, new()
|
|
{
|
|
m_states.TryGetValue(typeof(T), out var value);
|
|
return value as T;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
m_current?.OnUpdate();
|
|
foreach (var state in m_states.Values)
|
|
{
|
|
if (state == m_current) continue;
|
|
state.AnyStateUpdate(m_current);
|
|
}
|
|
}
|
|
|
|
public abstract class State
|
|
{
|
|
public SimpleFSM<HOST> FSM { get; private set; }
|
|
public HOST Host => FSM.Host;
|
|
protected virtual void OnInit() { }
|
|
public virtual void OnEnter(State preState) { }
|
|
public virtual void OnExit(State nextState) { }
|
|
public virtual void OnUpdate() { }
|
|
public virtual void AnyStateUpdate(State currentState) { }
|
|
|
|
public State LastState { get; set; }
|
|
|
|
protected State() { }
|
|
public static State CreateState<T>(SimpleFSM<HOST> fsm) where T : State, new()
|
|
{
|
|
var state = new T()
|
|
{
|
|
FSM = fsm
|
|
};
|
|
|
|
state.OnInit();
|
|
|
|
return state;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|