chicken_dy/Assets/Scripts/Core/FSM.cs

120 lines
2.8 KiB
C#

using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FSM<T>
{
public string CurrentState => mCurrentState != null ? mCurrentState.GetType().ToString() : "";
private Dictionary<Type, BaseState<T>> mStateDic;
private T mMaster;
private BaseState<T> mCurrentState;
private bool mActive;
public FSM(T pMaster)
{
mMaster = pMaster;
mStateDic = new Dictionary<Type, BaseState<T>>();
mActive = true;
}
public void ChangeState(Type pStateType = null)
{
if (pStateType == null)//change to empty
{
if (mCurrentState != null)
mCurrentState.ExitState(null);
mCurrentState = null;
return;
}
BaseState<T> tNextState = null;
if (pStateType != null)
{
if (!mStateDic.ContainsKey(pStateType))
{
object tInstance = pStateType.Assembly.CreateInstance(pStateType.Name);
if (tInstance is BaseState<T>)
{
tNextState = tInstance as BaseState<T>;
tNextState.SetFSM(this);
tNextState.SetMaster(mMaster);
mStateDic.Add(pStateType, tNextState);
}
else
{
Debug.LogError("State Class : " + pStateType.Name + " is not a " + typeof(BaseState<T>).Name + "!");
}
}
else
{
tNextState = mStateDic[pStateType];
}
}
else
{
Debug.LogError("State Class : " + pStateType.Name + " is not found!");
}
if (tNextState != null && tNextState != mCurrentState)
{
if (mCurrentState != null)
mCurrentState.ExitState(tNextState.GetType());
tNextState.EnterState(mCurrentState?.GetType());
mCurrentState = tNextState;
}
}
public void Execute(float pDeltaTime)
{
if (!mActive)
return;
if (mCurrentState != null)
mCurrentState.ExecuteState(pDeltaTime);
}
public void SetActive(bool pActive)
{
mActive = pActive;
}
}
public class BaseState<T>
{
protected T mMaster;
protected FSM<T> mFSM;
public void SetFSM(FSM<T> pFSM)
{
mFSM = pFSM;
}
public void SetMaster(T pMaster)
{
mMaster = pMaster;
}
public virtual void EnterState(Type pLastState)
{
}
public virtual void ExitState(Type pNextState)
{
}
public virtual void ExecuteState(float pDeltaTime)
{
}
protected void ChangeState(Type pType)
{
mFSM.ChangeState(pType);
}
}