using System.Collections;
using System.Collections.Generic;
/*
泛用型 狀態機
可以讓使用者 專注寫狀態就好
對外直接使用 AI<T>
撰寫邏輯使用繼承 State
State內取用 樣板資料 來取得客製化數據 來做對應的變化
事件取用方式?
對外事件操作方式
取得data後 可自行註冊內部事件
定義資料
這裡面定義可能要處理的資料與行為
定義狀態類別 : state
這裡面使用資料
定義AI : AI<資料>
讓外部取得data連結 然後做控制
AI本身就是執行動作
*/
/// <summary>聖淨之風</summary>
namespace Aether
{
/// <summary>行為</summary>
public class AI<T> where T : new()
{
/// <summary>狀態機</summary>
Context context = new Context();
/// <summary>建構式</summary>
public AI()
{
context.data = new T();
}
/// <summary>執行動作</summary>
public void RunAction()
{
context.RunAction();
}
/// <summary>取得目前狀態</summary>
/// <returns>目前狀態</returns>
public string GetState()
{
return context.GetState();
}
/// <summary>取得資料</summary>
/// <returns>回傳資料</returns>
public T GetData()
{
return (T)context.data;
}
}
/// <summary>狀態機</summary>
public class Context
{
/// <summary>資料</summary>
public object data = null;
/// <summary>狀態池 - 減少new的使用</summary>
Dictionary<string, State> stateDict = new Dictionary<string, State>();
/// <summary>目前狀態</summary>
State stateNow;
/// <summary>更換狀態</summary>
/// <typeparam name="T">狀態類別</typeparam>
public void ChangeState<T>() where T : State, new()
{ //取得狀態
string l_strClassName = typeof(T).Name;
State l_state = stateDict[l_strClassName];
if(l_state == null)
{
l_state = new T();
stateDict.Add(l_strClassName, l_state);
}
stateNow = l_state;
stateNow.SetContext(this);
}
/// <summary>執行動作</summary>
public void RunAction()
{
stateNow.RunAction();
}
/// <summary>取得目前狀態</summary>
/// <returns>目前狀態</returns>
public string GetState()
{
return stateNow.GetClassName();
}
/// <summary>取得資料</summary>
/// <typeparam name="T">類型</typeparam>
/// <returns>類型</returns>
public T GetData<T>()
{
return (T)data;
}
}
/// <summary>狀態</summary>
public class State
{
/// <summary>狀態機</summary>
protected Context context = null;
/// <summary>設定狀態機</summary>
/// <param name="i_context"></param>
public void SetContext(Context i_context)
{
context = i_context;
}
/// <summary>運作行為</summary>
public virtual void RunAction()
{
}
/// <summary>取得類別名稱</summary>
/// <returns>類別名稱</returns>
public string GetClassName()
{
return this.GetType().Name;
}
}
}