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
This commit is contained in:
412
GlobalSever/FSM/FSM.cs
Normal file
412
GlobalSever/FSM/FSM.cs
Normal file
@ -0,0 +1,412 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user