feat(godot): 集成Godot生命周期管理

- 新增ArchitectureAnchorNode类用于监听场景树销毁事件
- 在AbstractArchitecture中实现AttachToGodotLifecycle方法
- 自动绑定架构销毁逻辑到Godot节点退出时机
- 防止架构组件在热重载或多次初始化时重复挂载
- 完善系统注册与销毁流程,确保资源正确释放
This commit is contained in:
GwWuYou 2025-12-17 19:52:25 +08:00
parent b7739dd1df
commit eae45625a7
3 changed files with 68 additions and 3 deletions

View File

@ -1,4 +1,5 @@
using GFramework.Core.architecture;
using Godot;
namespace GFramework.Core.Godot.architecture;
@ -8,6 +9,8 @@ namespace GFramework.Core.Godot.architecture;
/// <typeparam name="T">架构的具体类型必须继承自Architecture且能被实例化</typeparam>
public abstract class AbstractArchitecture<T> : Architecture<T> where T : Architecture<T>, new()
{
private const string ArchitectureName = "__GFrameworkArchitectureAnchor";
/// <summary>
/// 初始化架构,按顺序注册模型、系统和工具
/// </summary>
@ -16,8 +19,35 @@ public abstract class AbstractArchitecture<T> : Architecture<T> where T : Archit
RegisterModels();
RegisterSystems();
RegisterUtilities();
AttachToGodotLifecycle();
}
/// <summary>
/// 将架构绑定到Godot生命周期中确保在场景树销毁时能够正确清理资源
/// 通过创建一个锚节点来监听场景树的销毁事件
/// </summary>
private void AttachToGodotLifecycle()
{
if (Engine.GetMainLoop() is not SceneTree tree)
return;
// 防止重复挂载(热重载 / 多次 Init
if (tree.Root.GetNodeOrNull(ArchitectureName) != null)
return;
var anchor = new ArchitectureAnchorNode
{
Name = ArchitectureName
};
anchor.Bind(() =>
{
Destroy();
});
tree.Root.AddChild(anchor);
}
/// <summary>
/// 注册工具抽象方法,由子类实现具体的工具注册逻辑
/// </summary>
@ -33,3 +63,4 @@ public abstract class AbstractArchitecture<T> : Architecture<T> where T : Archit
/// </summary>
protected abstract void RegisterModels();
}

View File

@ -0,0 +1,32 @@
using Godot;
namespace GFramework.Core.Godot.architecture;
/// <summary>
/// 架构锚点节点类用于在Godot场景树中作为架构组件的根节点
/// 该类提供了退出时的回调绑定功能,可以在节点从场景树中移除时执行清理操作
/// </summary>
public partial class ArchitectureAnchorNode : Node
{
private Action? _onExit;
/// <summary>
/// 绑定节点退出时的回调动作
/// </summary>
/// <param name="onExit">当节点从场景树退出时要执行的动作</param>
public void Bind(Action onExit)
{
_onExit = onExit;
}
/// <summary>
/// 当节点从场景树中移除时调用此方法
/// 执行绑定的退出回调并清理引用
/// </summary>
public override void _ExitTree()
{
_onExit?.Invoke();
_onExit = null;
}
}

View File

@ -65,6 +65,8 @@ public abstract class Architecture<T> : IArchitecture where T : Architecture<T>,
/// 存储尚未初始化的系统集合在初始化阶段统一调用Init方法
/// </summary>
private readonly HashSet<ISystem> _mSystems = [];
private readonly HashSet<ISystem> _allSystems = [];
/// <summary>
/// 类型化事件系统,负责事件的发布与订阅管理
@ -99,7 +101,7 @@ public abstract class Architecture<T> : IArchitecture where T : Architecture<T>,
{
system.SetArchitecture(this);
_mContainer.Register(system);
_allSystems.Add(system);
if (!_mInited)
_mSystems.Add(system);
else
@ -242,11 +244,11 @@ public abstract class Architecture<T> : IArchitecture where T : Architecture<T>,
public void Destroy()
{
// 销毁所有已注册的系统
foreach (var system in _mSystems)
foreach (var system in _allSystems)
{
system.Destroy();
}
_mSystems.Clear();
_allSystems.Clear();
}