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
412 lines
12 KiB
C#
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);
|
|
}
|
|
}
|
|
} |