GFramework/GFramework.Godot/Architectures/AbstractArchitecture.cs
GeWuYou e022a10bd5 refactor(architecture): 将架构相关文件从 Architecture 目录移动到 Architectures 目录
- 重命名目录名称从 Architecture 到 Architectures
- 更新所有相关文件的命名空间声明
- 保持代码功能不变,仅调整目录结构和命名空间一致性
2026-03-14 16:54:07 +08:00

141 lines
4.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using GFramework.Core.Abstractions.Architectures;
using GFramework.Core.Abstractions.Environment;
using GFramework.Core.Architectures;
using GFramework.Core.Constants;
using GFramework.Godot.Extensions;
using Godot;
namespace GFramework.Godot.Architectures;
/// <summary>
/// 抽象架构类,为特定类型的架构提供基础实现框架。
/// 此类负责管理架构的初始化、生命周期绑定以及扩展模块的安装与销毁。
/// </summary>
public abstract class AbstractArchitecture(
IArchitectureConfiguration? configuration = null,
IEnvironment? environment = null,
IArchitectureServices? services = null,
IArchitectureContext? context = null
) : Architecture(configuration, environment, services, context)
{
/// <summary>
/// 存储所有已安装的Godot架构扩展组件列表
/// 用于在架构销毁时正确清理所有扩展资源
/// </summary>
private readonly List<IGodotModule> _extensions = [];
/// <summary>
/// 架构锚点节点引用
/// 用于将架构绑定到Godot生命周期并作为扩展节点的父节点
/// </summary>
private ArchitectureAnchor? _anchor;
/// <summary>
/// 架构锚点节点的唯一标识名称
/// 用于在Godot场景树中创建和查找架构锚点节点
/// </summary>
private string _architectureAnchorName = null!;
/// <summary>
/// 标记架构是否已被销毁的状态标志
/// 用于防止架构被重复销毁,确保资源清理只执行一次
/// </summary>
private bool _destroyed;
/// <summary>
/// 获取架构根节点。如果尚未初始化或已被销毁,则抛出异常。
/// </summary>
/// <exception cref="InvalidOperationException">当架构未准备就绪时抛出。</exception>
protected Node ArchitectureRoot => _anchor ?? throw new InvalidOperationException("Architecture root not ready");
/// <summary>
/// 初始化架构,按顺序注册模型、系统和工具。
/// 包括将架构绑定到Godot生命周期并调用模块安装逻辑。
/// </summary>
protected override void OnInitialize()
{
_architectureAnchorName =
$"__{GFrameworkConstants.FrameworkName}__{GetType().Name}__{GetHashCode()}__ArchitectureAnchor__";
AttachToGodotLifecycle();
InstallModules();
}
/// <summary>
/// 安装模块抽象方法,由子类实现具体的模块注册逻辑。
/// 子类应在此方法中完成所有模型、系统及工具的注册工作。
/// </summary>
protected abstract void InstallModules();
/// <summary>
/// 将架构绑定到Godot生命周期中确保在场景树销毁时能够正确清理资源。
/// 通过创建一个锚节点来监听场景树的销毁事件。
/// </summary>
private void AttachToGodotLifecycle()
{
if (Engine.GetMainLoop() is not SceneTree tree)
return;
// 防止重复挂载(热重载 / 多次 OnInitialize
if (tree.Root.GetNodeOrNull(_architectureAnchorName) != null)
return;
_anchor = new ArchitectureAnchor
{
Name = _architectureAnchorName
};
_anchor.Bind(() => DestroyAsync().AsTask());
tree.Root.CallDeferred(Node.MethodName.AddChild, _anchor);
}
/// <summary>
/// 安装Godot模块扩展
/// </summary>
/// <typeparam name="TModule">模块类型必须实现IGodotModule接口</typeparam>
/// <param name="module">要安装的模块实例</param>
/// <returns>异步任务</returns>
protected async Task InstallGodotModule<TModule>(TModule module) where TModule : IGodotModule
{
module.Install(this);
// 检查锚点是否已初始化,未初始化则抛出异常
if (_anchor == null)
throw new InvalidOperationException("Anchor not initialized");
// 等待锚点准备就绪
await _anchor.WaitUntilReadyAsync();
// 延迟调用将扩展节点添加为锚点的子节点
_anchor.CallDeferred(Node.MethodName.AddChild, module.Node);
// 调用扩展的附加回调方法
module.OnAttach(this);
// 将扩展添加到扩展集合中
_extensions.Add(module);
}
/// <summary>
/// 销毁架构及其相关资源。
/// 调用所有已安装扩展的OnDetach方法并清空扩展列表。
/// 若已被销毁则直接返回。
/// </summary>
public override async ValueTask DestroyAsync()
{
if (_destroyed)
return;
_destroyed = true;
foreach (var ext in _extensions)
ext.OnDetach();
_extensions.Clear();
await base.DestroyAsync();
}
}