跳至主要内容
版本:v3

CenterBase

重要 注意 提醒

Coding Style wiki


CenterBase<TCenter, TClass>CenterFrame 的中心註冊抽象基類,內建執行緒安全單例與 Dictionary<int, TClass> 型別安全快取,統一提供**註冊(Add)、移除(Delete)、查找(Find)**等物件管理介面。APICenterAPIBase)與 EventCenterEventBase)皆以此為共同基底,也可自訂 TClass 基底型別實作自己的中心。

命名空間OxGFrame.CenterFrame
類型public abstract class
原始碼CenterBase.cs
using OxGFrame.CenterFrame;

宣告

public abstract class CenterBase<TCenter, TClass> where TCenter : CenterBase<TCenter, TClass>, new()

泛型參數

泛型參數說明
TCenter中心子類自身型別(CRTP 自我參照約束),需具備無參數建構子(new())。
TClass受管理物件的基底型別(如 APICenter 的 APIBase、EventCenter 的 EventBase)。

繼承時將子類自身與受管理的基底型別作為泛型參數傳入:

public class APICenterExample : CenterBase<APICenterExample, APIBase> { /* ... */ }
public class EventCenterExample : CenterBase<EventCenterExample, EventBase> { /* ... */ }

運作方式

單例與註冊時機

CenterBase<TCenter, TClass> 內建執行緒安全的延遲單例(Double-Checked Locking)。首次呼叫任一 Default API 靜態方法時,自動建立 TCenter 實例並執行其建構子;建議於子類建構子中以 Register 完成物件註冊。

重要 不可於子類建構子中呼叫任何 Default API 靜態方法(如 Add / Find),會導致 GetInstance() 遞迴而 StackOverflow(死循環);建構子中請改用實例成員方法(如 Register)。

ID 規則

  • 每個註冊物件以唯一的 int id 作為快取鍵。泛型多載未指定 id 時,以 typeof(UClass).GetHashCode() 作為 id(同型別僅能註冊一個實例)。
  • 指定 id 的多載可自訂 id,同型別即可註冊多個實例。
  • 相同 id 重複註冊會輸出警告日誌並略過,不會覆蓋既有物件。

Default API 與成員方法

靜態 Default API(Add / Delete / Find)內部皆透過單例轉呼叫對應的實例成員方法(Register / Remove / Get):

  • 外部呼叫端:直接以子類類名使用 Default API(如 EventCenterExample.Find<UClass>())。
  • 子類內部(建構子):使用實例成員方法(如 this.Register<UClass>())。

注意 CenterBase 僅負責物件的註冊與快取管理;若受管理物件持有 Unity 資源(如 Prefab),請於移除前自行配合 AssetLoaders 進行正確的釋放處理。

繼承實作範例

以 EventCenter 風格為例,自訂事件中心與事件類:

using Cysharp.Threading.Tasks;
using OxGFrame.CenterFrame;
using OxGFrame.CenterFrame.EventCenter;
using UnityEngine;

// 自訂事件中心:TCenter 傳入子類自身(CRTP),TClass 指定受管理的基底型別
public class EventCenterExample : CenterBase<EventCenterExample, EventBase>
{
public EventCenterExample()
{
// 建構子中註冊事件(僅能使用實例成員方法 Register,不可呼叫 Default API)
this.Register<EventMsgTest>();
}
}

// 自訂事件:繼承 EventBase
public class EventMsgTest : EventBase
{
private string _message;

public void Emit(string message)
{
this._message = message;
this.HandleEvent().Forget();
}

public async override UniTaskVoid HandleEvent()
{
// 處理事件內容
Debug.Log($"Received message: {this._message}");
this.Release();
}

protected override void Release()
{
// 釋放事件持有的資料
this._message = null;
}
}

呼叫端透過 Default API 查找並派送事件:

// 以型別查找已註冊的事件並派送
EventCenterExample.Find<EventMsgTest>()?.Emit("Hello OxGFrame");

APICenter 風格作法相同,僅將 TClass 改為 APIBase

using OxGFrame.CenterFrame;
using OxGFrame.CenterFrame.APICenter;

// APIGetPlayerData 為繼承 APIBase 的自訂 API 類
public class APICenterExample : CenterBase<APICenterExample, APIBase>
{
public APICenterExample()
{
this.Register<APIGetPlayerData>();
}
}

提醒 可透過 Project 視窗右鍵範本快速建立:Create → OxGFrame → Center Frame → Event Center / API Center → Template Scripts 下的範本腳本。

成員總覽

靜態方法(Default API)

繼承後直接以子類類名呼叫(如 EventCenterExample.Find<UClass>())。

方法說明
Add實例化並註冊物件至快取。
Delete從快取移除物件。
DeleteAll清空快取中的所有物件。
Find<UClass>從快取查找物件並轉型回傳。

一般方法(實例成員)

方法說明
Get<UClass>從快取取得物件並轉型(Find 的成員版本)。
Has<UClass>檢查物件是否已註冊。
Register註冊物件至快取(Add 的成員版本)。
Remove從快取移除物件(Delete 的成員版本)。
RemoveAll清空快取(DeleteAll 的成員版本)。

受保護成員(繼承後可用)

成員型別說明
GetInstance()static TCenter取得中心單例(延遲建立、執行緒安全)。
GetFromCache(int id)TClass從快取取出物件;查無時輸出錯誤日誌並回傳 default
HasInCache(int id)bool檢查快取中是否存在指定 id。

Add

public static void Add<UClass>() where UClass : TClass, new()
public static void Add<UClass>(int id) where UClass : TClass, new()
public static void Add(int id, TClass @class)

參數

參數型別說明
idint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 作為 id。
@classTClass已建立的物件實例(以指定 id 註冊)。

說明

實例化(new UClass())並註冊物件至快取,或以指定 id 直接註冊既有實例。

注意
  • 泛型多載要求 UClass 具備無參數建構子(new() 約束)。
  • 相同 id 重複註冊會輸出警告並略過,不會覆蓋既有物件。

範例

// 以型別 hash 作為 id 註冊
EventCenterExample.Add<EventMsgTest>();

// 以自訂 id 註冊既有實例
EventCenterExample.Add(0x01, new EventMsgTest());

Delete

public static void Delete<UClass>() where UClass : TClass
public static void Delete(int id)

參數

參數型別說明
idint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 查找。

說明

從快取移除已註冊的物件;查無時不動作。


DeleteAll

public static void DeleteAll()

說明

清空快取中的所有已註冊物件。


Find<UClass>

public static UClass Find<UClass>() where UClass : TClass
public static UClass Find<UClass>(int id) where UClass : TClass

參數

參數型別說明
idint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 查找。

回傳值

UClass — 快取中對應的物件(已轉型為 UClass);查無時輸出錯誤日誌並回傳 default(參考型別即 null)。

說明

從快取查找已註冊的物件並自動轉型。無參數多載以型別 hash 查找,僅適用於未指定 id 註冊的物件;以自訂 id 註冊者請使用 Find<UClass>(int id)

範例

var evt = EventCenterExample.Find<EventMsgTest>();
evt?.Emit("Hello OxGFrame");

Get<UClass>

public UClass Get<UClass>() where UClass : TClass
public UClass Get<UClass>(int eventId) where UClass : TClass

參數

參數型別說明
eventIdint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 查找。

回傳值

UClass — 快取中對應的物件(已轉型為 UClass);查無時輸出錯誤日誌並回傳 default

說明

Find<UClass> 的實例成員版本,供子類內部使用。


Has<UClass>

public bool Has<UClass>() where UClass : TClass
public bool Has<UClass>(int id) where UClass : TClass

參數

參數型別說明
idint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 檢查。

回傳值

bool — 指定物件是否已註冊於快取。

說明

檢查物件是否已註冊。可於註冊或查找前先行判斷,避免重複註冊的警告或查無的錯誤日誌。


Register

public void Register<UClass>() where UClass : TClass, new()
public void Register<UClass>(int id) where UClass : TClass, new()
public void Register(int id, TClass @class)

參數

參數型別說明
idint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 作為 id。
@classTClass已建立的物件實例(以指定 id 註冊)。

說明

Add 的實例成員版本,於子類建構子中註冊物件時使用(建構子中不可呼叫靜態 Default API)。相同 id 重複註冊會輸出警告並略過。

範例

public EventCenterExample()
{
this.Register<EventMsgTest>();
}

Remove

public void Remove<UClass>() where UClass : TClass
public void Remove(int id)

參數

參數型別說明
idint註冊 id。未指定時,以 typeof(UClass).GetHashCode() 查找。

說明

Delete 的實例成員版本;查無時不動作。


RemoveAll

public void RemoveAll()

說明

DeleteAll 的實例成員版本,清空快取中的所有已註冊物件。