1
0
AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs

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;
}
}
}
}