Files
hjha-server/GlobalSever/FSM/FSM.cs
xiaoou e9616125ce feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) +
game logic (GameFix/GameDAL/ServerData) +
network layer (NetWorkMessage) +
data layer (ObjectModel) +
utilities (MrWu/Core/Config/CloudAPI/dll) +
adapters (zyxAdapter/base)

.NET 8.0 C# solution, 16 projects, 958 source files
2026-07-07 12:02:15 +08:00

412 lines
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
using MrWu.Debug;
namespace GlobalSever.FSM
{
/// <summary>
/// 状态机
/// </summary>
public class FSM<T> where T : class
{
/// <summary>
/// 所有状态
/// </summary>
private readonly Dictionary<Type, FSMState<T>> m_States = new Dictionary<Type, FSMState<T>>();
/// <summary>
/// 状态切换事件
/// </summary>
public Action<FSM<T>, FSMState<T>> OnStateChanged;
/// <summary>
/// 状态准备切换事件 (延时的情况,还没有真正切换)
/// </summary>
public Action<FSM<T>, FSMState<T>> OnStatePreChanged;
/// <summary>
/// 状态机持有者
/// </summary>
public T Owner { get; private set; }
/// <summary>
/// 是否正在运行
/// </summary>
public bool IsRunning => CurrentState != null;
/// <summary>
/// 有限状态机是否被销毁
/// </summary>
public bool IsDestroyed { get; private set; }
/// <summary>
/// 状态机内存
/// </summary>
public FSMMem Mem { get; private set; }
/// <summary>
/// 上一个状态
/// </summary>
public FSMState<T> LastState { get; private set; }
/// <summary>
/// 当前状态机的状态
/// </summary>
public FSMState<T> CurrentState { get; private set; }
/// <summary>
/// 开启状态
/// </summary>
public FSMState<T> StartState { get; private set; }
/// <summary>
/// 结束状态
/// </summary>
public FSMState<T> EndState { get; private set; }
public static FSM<T> Create(T owner, FSMMem mem, params FSMState<T>[] states)
{
if (owner == null)
{
throw new Exception("FSM owner is invalid.");
}
if (states == null || states.Length < 1)
{
throw new Exception("FSM states is invalid.");
}
FSM<T> fsm = new FSM<T>();
fsm.Mem = mem;
fsm.Owner = owner;
fsm.IsDestroyed = false;
for (int i = 0; i < states.Length; i++)
{
FSMState<T> state = states[i];
if (state == null)
{
throw new Exception("FSM states is invalid.");
}
Type stateType = state.StateType;
if (fsm.m_States.ContainsKey(stateType))
{
throw new Exception($"FSM state '{stateType}' is already exist.");
}
fsm.m_States.Add(stateType, state);
if (i + 1 < states.Length)
state.NextState = states[i + 1];
if (i - 1 >= 0)
state.LastState = states[i - 1];
if (i == 0)
fsm.StartState = state;
if (i == states.Length - 1)
fsm.EndState = state;
state.OnInit(fsm);
}
return fsm;
}
/// <summary>
/// 创建有限状态机
/// </summary>
/// <param name="owner"></param>
/// <param name="states"></param>
public static FSM<T> Create(T owner, params FSMState<T>[] states)
{
return Create(owner, new FSMMem(), states);
}
/// <summary>
/// 创建独立的状态机
/// </summary>
public void CreateSingle(FSMState<T> state)
{
if (state == null)
{
throw new Exception("FSM states is invalid.");
}
Type stateType = state.StateType;
if (m_States.ContainsKey(stateType))
{
throw new Exception($"FSM state '{stateType}' is already exist.");
}
m_States.Add(stateType, state);
state.OnInit(this);
}
/// <summary>
/// 清理有限状态机
/// </summary>
public void Clear()
{
Stop();
foreach (KeyValuePair<Type, FSMState<T>> state in m_States)
{
state.Value.OnDestroy(this);
}
Owner = null;
m_States.Clear();
IsDestroyed = true;
}
/// <summary>
/// 默认从起始节点开始
/// </summary>
public void Start()
{
Start(StartState.StateType);
}
/// <summary>
/// 从某个节点恢复
/// </summary>
public void Recover(int stateId)
{
foreach (var state in m_States)
{
if (state.Value.StateId == stateId)
{
Start(state.Key);
break;
}
}
}
/// <summary>
/// 通过内存恢复状态机
/// </summary>
public void Recover()
{
var state = GetState(Mem.NowStateId);
Mem.NowStateType = state.StateType;
Debug.Info($"[FSM] Recover Success. State = {Mem.NowStateType} Id = {Mem.NowStateId}");
ReallyChangeState(Mem.NowStateType);
}
/// <summary>
/// 开始有限状态机
/// </summary>
/// <typeparam name="TState"></typeparam>
public void Start<TState>() where TState : FSMState<T>
{
Start(typeof(TState));
}
/// <summary>
/// 开始有限状态机
/// </summary>
/// <param name="stateType"></param>
/// <exception cref="Exception"></exception>
public void Start(Type stateType)
{
if (IsRunning)
{
throw new Exception("FSM is running, can not start again.");
}
if (stateType == null)
{
throw new Exception("State type is invalid.");
}
if (!typeof(FSMState<T>).IsAssignableFrom(stateType))
{
throw new Exception($"State type '{stateType}' is invalid.");
}
Debug.Info($"[FSM] Start Success. State = {stateType}");
ReallyChangeState(stateType);
}
/// <summary>
/// 是否存在有限状态机
/// </summary>
/// <typeparam name="TState"></typeparam>
/// <returns></returns>
public bool HasState<TState>() where TState : FSMState<T>
{
return m_States.ContainsKey(typeof(TState));
}
/// <summary>
/// 是否存在有限状态机
/// </summary>
/// <param name="stateType"></param>
/// <returns></returns>
public bool HasState(Type stateType)
{
if (stateType == null)
{
throw new Exception("State type is invalid.");
}
if (!typeof(FSMState<T>).IsAssignableFrom(stateType))
{
throw new Exception($"State type '{stateType}' is invalid.");
}
return m_States.ContainsKey(stateType);
}
/// <summary>
/// 获取有限状态机
/// </summary>
/// <typeparam name="TState"></typeparam>
/// <returns></returns>
public TState GetState<TState>() where TState : FSMState<T>
{
FSMState<T> state = null;
if (m_States.TryGetValue(typeof(TState), out state))
{
return (TState)state;
}
return null;
}
/// <summary>
/// 获取有限状态机状态
/// </summary>
/// <param name="stateType"></param>
/// <returns></returns>
public FSMState<T> GetState(Type stateType)
{
if (stateType == null)
{
throw new Exception("State type is invalid.");
}
if (!typeof(FSMState<T>).IsAssignableFrom(stateType))
{
throw new Exception($"State type '{stateType}' is invalid.");
}
FSMState<T> state = null;
if (m_States.TryGetValue(stateType,out state))
{
return state;
}
return null;
}
public FSMState<T> GetState(int stateId)
{
foreach (var s in m_States)
{
if (s.Value.StateId == stateId)
return s.Value;
}
throw new Exception($"State Id '{stateId}' is invalid.");
}
/// <summary>
/// 有限状态机更新
/// </summary>
/// <param name="interval">与上次更新的时间间隔</param>
public void Update(int interval)
{
//更新持续时间
if (!IsRunning)
{
return;
}
Mem.RunDuratime += interval;
CurrentState.RunDuratime += interval;
CurrentState.Update(this,interval);
if (Mem.NeedChange && Mem.RunDuratime - Mem.LastUpdateTime >= Mem.NowChangeDelayTime)
{
Mem.NowChangeDelayTime = 0;
Mem.NeedChange = false;
// Debug.Info($"[FSM] Start State = {Mem.NowStateType}");
ReallyChangeState(Mem.NowStateType);
}
}
/// <summary>
/// 关闭有限状态机
/// </summary>
public void ShutDown()
{
Clear();
}
public void Stop()
{
if (CurrentState != null)
{
CurrentState.OnLeave(this);
}
CurrentState = null;
Mem.NowStateId = -1;
Mem.NowStateType = null;
Mem.NeedChange = false;
}
public void ChangeStateImmediate<K>() where K : FSMState<T>
{
Mem.NowStateType = typeof(K);
Mem.NeedChange = false;
ReallyChangeState(Mem.NowStateType);
Debug.Info($"[FSM] Change State Immediate = {Mem.NowStateType}");
}
public void ChangeState<K>() where K : FSMState<T>
{
ChangeState(typeof(K));
}
/// <summary>
/// 切换当前有限状态机状态
/// </summary>
/// <param name="stateType">目标状态</param>
public void ChangeState(Type stateType, int delayTime = 0)
{
if (!IsRunning)
{
throw new Exception("Current state is invalid.");
}
Debug.Info($"[FSM] Change State = {stateType} Delay = {delayTime}");
Mem.NowStateType = stateType;
Mem.NowStateId = GetState(stateType).StateId;
Mem.NeedChange = true;
Mem.NowChangeDelayTime = delayTime;
Mem.LastUpdateTime = Mem.RunDuratime;
}
void ReallyChangeState(Type stateType)
{
FSMState<T> state = GetState(stateType);
if (state == null)
{
throw new Exception($"FSM can not change state to '{stateType}' which is not exist.");
}
if (CurrentState != null)
{
CurrentState.OnLeave(this);
LastState = CurrentState;
}
CurrentState = state;
Mem.NowStateId = CurrentState.StateId;
Mem.NowStateType = CurrentState.StateType;
OnStateChanged?.Invoke(this, CurrentState);
CurrentState.OnEnter(this);
}
}
}