using GFramework.Core.command;
using GFramework.Core.events;
using GFramework.Core.ioc;
using GFramework.Core.model;
using GFramework.Core.query;
using GFramework.Core.system;
using GFramework.Core.utility;
namespace GFramework.Core.architecture;
///
/// 架构基类,提供系统、模型、工具等组件的注册与管理功能。
/// 使用单例模式确保全局唯一实例,并支持命令、查询和事件机制。
///
/// 派生类类型,用于实现单例
public abstract class Architecture : IArchitecture where T : Architecture, new()
{
///
/// 标记架构是否已初始化完成
///
private bool _mInited;
///
/// 存储尚未初始化的系统集合,在初始化阶段统一调用Init方法
///
private readonly HashSet _mSystems = [];
///
/// 存储尚未初始化的模型集合,在初始化阶段统一调用Init方法
///
private readonly HashSet _mModels = [];
///
/// 注册补丁委托,允许在架构创建后执行额外逻辑
///
public static Action OnRegisterPatch { get; set; } = _ => { };
///
/// 静态只读字段,用于延迟初始化架构实例
/// 使用Lazy确保线程安全的单例模式实现
///
///
/// 初始化过程包括:
/// 1. 创建T类型的实例
/// 2. 调用用户自定义的Init方法
/// 3. 执行注册的补丁逻辑
/// 4. 初始化所有已注册的模型和系统
/// 5. 清理临时集合并标记初始化完成
///
/// T类型的架构实例
private static readonly Lazy MArchitectureLazy = new(() =>
{
var arch = new T();
// 调用用户实现的初始化
arch.Init();
// 执行注册的补丁逻辑
OnRegisterPatch?.Invoke(arch);
// 初始化所有已注册但尚未初始化的模型
foreach (var model in arch._mModels)
{
model.Init();
}
arch._mModels.Clear();
// 初始化所有已注册但尚未初始化的系统
foreach (var system in arch._mSystems)
{
system.Init();
}
arch._mSystems.Clear();
arch._mInited = true;
return arch;
}, LazyThreadSafetyMode.ExecutionAndPublication);
///
/// 获取架构实例的受保护静态属性
/// 通过Lazy初始化确保只创建一个实例
///
/// T类型的架构实例
protected static T MArchitecture => MArchitectureLazy.Value;
///
/// 获取架构实例的公共静态属性,以接口形式暴露
/// 提供对外访问架构功能的标准接口
///
/// IArchitecture接口类型的架构实例
public static IArchitecture Interface => MArchitectureLazy.Value;
///
/// 抽象初始化方法,由子类重写以进行自定义初始化操作
///
protected abstract void Init();
///
/// 控制反转容器,用于存储和获取各种服务(如系统、模型、工具)
///
private readonly IocContainer _mContainer = new();
///
/// 注册一个系统到架构中。
/// 若当前未初始化,则暂存至待初始化列表;否则立即初始化该系统。
///
/// 要注册的系统类型
/// 要注册的系统实例
public void RegisterSystem(TSystem system) where TSystem : ISystem
{
system.SetArchitecture(this);
_mContainer.Register(system);
if (!_mInited)
{
_mSystems.Add(system);
}
else
{
system.Init();
}
}
///
/// 注册一个模型到架构中。
/// 若当前未初始化,则暂存至待初始化列表;否则立即初始化该模型。
///
/// 要注册的模型类型
/// 要注册的模型实例
public void RegisterModel(TModel model) where TModel : IModel
{
model.SetArchitecture(this);
_mContainer.Register(model);
if (!_mInited)
{
_mModels.Add(model);
}
else
{
model.Init();
}
}
///
/// 注册一个工具到架构中。
/// 工具不会被延迟初始化,直接放入IOC容器供后续使用。
///
/// 要注册的工具类型
/// 要注册的工具实例
public void RegisterUtility(TUtility utility) where TUtility : IUtility =>
_mContainer.Register(utility);
///
/// 从IOC容器中获取指定类型的系统实例
///
/// 目标系统类型
/// 对应的系统实例
public TSystem GetSystem() where TSystem : class, ISystem => _mContainer.Get();
///
/// 从IOC容器中获取指定类型的模型实例
///
/// 目标模型类型
/// 对应的模型实例
public TModel GetModel() where TModel : class, IModel => _mContainer.Get();
///
/// 从IOC容器中获取指定类型的工具实例
///
/// 目标工具类型
/// 对应的工具实例
public TUtility GetUtility() where TUtility : class, IUtility => _mContainer.Get();
///
/// 发送一个带返回结果的命令请求
///
/// 命令执行后的返回值类型
/// 要发送的命令对象
/// 命令执行的结果
public TResult SendCommand(ICommand command) => ExecuteCommand(command);
///
/// 发送一个无返回结果的命令请求
///
/// 命令的具体类型
/// 要发送的命令对象
public void SendCommand(TCommand command) where TCommand : ICommand => ExecuteCommand(command);
///
/// 执行一个带返回结果的命令
///
/// 命令执行后的返回值类型
/// 要执行的命令对象
/// 命令执行的结果
protected virtual TResult ExecuteCommand(ICommand command)
{
command.SetArchitecture(this);
return command.Execute();
}
///
/// 执行一个无返回结果的命令
///
/// 要执行的命令对象
protected virtual void ExecuteCommand(ICommand command)
{
command.SetArchitecture(this);
command.Execute();
}
///
/// 发起一次查询请求并获得其结果
///
/// 查询结果的数据类型
/// 要发起的查询对象
/// 查询得到的结果数据
public TResult SendQuery(IQuery query) => DoQuery(query);
///
/// 实际执行查询逻辑的方法
///
/// 查询结果的数据类型
/// 要处理的查询对象
/// 查询结果
protected virtual TResult DoQuery(IQuery query)
{
query.SetArchitecture(this);
return query.Do();
}
///
/// 类型化事件系统,负责事件的发布与订阅管理
///
private readonly TypeEventSystem _mTypeEventSystem = new();
///
/// 发布一个默认构造的新事件对象
///
/// 事件类型
public void SendEvent() where TEvent : new() => _mTypeEventSystem.Send();
///
/// 发布一个具体的事件对象
///
/// 事件类型
/// 要发布的事件实例
public void SendEvent(TEvent e) => _mTypeEventSystem.Send(e);
///
/// 订阅某个特定类型的事件
///
/// 事件类型
/// 当事件发生时触发的动作
/// 可用于取消订阅的对象
public IUnRegister RegisterEvent(Action onEvent) => _mTypeEventSystem.Register(onEvent);
///
/// 取消对某类型事件的监听
///
/// 事件类型
/// 之前绑定的事件处理器
public void UnRegisterEvent(Action onEvent) => _mTypeEventSystem.UnRegister(onEvent);
}