CenterBase
Coding Style wiki
CenterBase<TCenter, TClass> 是 CenterFrame 的中心注册抽象基类,内置线程安全单例与 Dictionary<int, TClass> 类型安全缓存,统一提供**注册(Add)、移除(Delete)、查找(Find)**等对象管理接口。APICenter(APIBase)与 EventCenter(EventBase)皆以此为共同基底,也可自定义 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 规则
- 每个注册对象以唯一的
intid 作为缓存键。泛型重载未指定 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)
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 注册 id。未指定时,以 typeof(UClass).GetHashCode() 作为 id。 |
| @class | TClass | 已创建的对象实例(以指定 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)
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 注册 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
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 注册 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
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| eventId | int | 注册 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
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 注册 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)
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 注册 id。未指定时,以 typeof(UClass).GetHashCode() 作为 id。 |
| @class | TClass | 已创建的对象实例(以指定 id 注册)。 |
说明
Add 的实例成员版本,在子类构造函数中注册对象时使用(构造函数中不可调用静态 Default API)。相同 id 重复注册会输出警告并跳过。
示例
public EventCenterExample()
{
this.Register<EventMsgTest>();
}
Remove
public void Remove<UClass>() where UClass : TClass
public void Remove(int id)
参数
| 参数 | 类型 | 说明 |
|---|---|---|
| id | int | 注册 id。未指定时,以 typeof(UClass).GetHashCode() 查找。 |
说明
Delete 的实例成员版本;未找到时不做任何操作。
RemoveAll
public void RemoveAll()
说明
DeleteAll 的实例成员版本,清空缓存中的所有已注册对象。