From 569713b41ddc2457813f77cfaa1301bce6cc19d8 Mon Sep 17 00:00:00 2001
From: GwWuYou <95328647+GeWuYou@users.noreply.github.com>
Date: Tue, 9 Dec 2025 21:48:19 +0800
Subject: [PATCH] =?UTF-8?q?feat(godot):=20=E6=B7=BB=E5=8A=A0=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增 QueueFreeX 扩展方法,安全地延迟释放节点资源
- 新增 FreeX 扩展方法,立即释放节点资源
- 新增 WaitUntilReady 扩展方法,等待节点就绪信号
- 新增 IsValidNode 扩展方法,检查节点有效性
- 新增 IsInvalidNode 扩展方法,检查节点无效性
- 所有方法均包含空值检查和实例有效性验证
- 方法支持Godot编译条件指令控制
---
framework/godot/NodeExtensions.cs | 107 ++++++++++++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 framework/godot/NodeExtensions.cs
diff --git a/framework/godot/NodeExtensions.cs b/framework/godot/NodeExtensions.cs
new file mode 100644
index 0000000..9e22fe9
--- /dev/null
+++ b/framework/godot/NodeExtensions.cs
@@ -0,0 +1,107 @@
+#if GODOT
+using System.Threading.Tasks;
+using Godot;
+namespace GFramework.framework.godot;
+
+///
+/// 节点扩展方法类,提供对Godot节点的扩展功能
+///
+public static class NodeExtensions
+{
+ ///
+ /// 安全地将节点加入删除队列,在下一帧开始时释放节点资源
+ ///
+ /// 要释放的节点实例
+ public static void QueueFreeX(this Node node)
+ {
+ // 检查节点是否为空
+ if (node is null)
+ {
+ return;
+ }
+
+ // 检查节点实例是否有效
+ if (!GodotObject.IsInstanceValid(node))
+ {
+ return;
+ }
+
+ // 检查节点是否已经加入删除队列
+ if (node.IsQueuedForDeletion())
+ {
+ return;
+ }
+
+ // 延迟调用QueueFree方法,避免在当前帧中直接删除节点
+ node.CallDeferred(Node.MethodName.QueueFree);
+ }
+
+ ///
+ /// 立即释放节点资源,不等待下一帧
+ ///
+ /// 要立即释放的节点实例
+ public static void FreeX(this Node node)
+ {
+ // 检查节点是否为空
+ if (node is null)
+ {
+ return;
+ }
+
+ // 检查节点实例是否有效
+ if (!GodotObject.IsInstanceValid(node))
+ {
+ return;
+ }
+
+ // 检查节点是否已经加入删除队列
+ if (node.IsQueuedForDeletion())
+ {
+ return;
+ }
+
+ // 立即释放节点资源
+ node.Free();
+ }
+
+ ///
+ /// 如果节点尚未进入场景树,则等待 ready 信号。
+ /// 如果已经在场景树中,则立刻返回。
+ ///
+ public static async Task WaitUntilReady(this Node node)
+ {
+ if (!node.IsInsideTree())
+ {
+ await node.ToSignal(node, Node.SignalName.Ready);
+ }
+ }
+
+ ///
+ /// 检查节点是否有效:
+ /// 1. 非 null
+ /// 2. Godot 实例仍然存在(未被释放)
+ /// 3. 已经加入 SceneTree
+ ///
+ public static bool IsValidNode(this Node node)
+ {
+ return node is not null &&
+ GodotObject.IsInstanceValid(node) &&
+ node.IsInsideTree();
+ }
+
+ ///
+ /// 检查节点是否无效:
+ /// 1. 为 null,或者
+ /// 2. Godot 实例已被释放,或者
+ /// 3. 尚未加入 SceneTree
+ ///
+ /// 返回 true 表示该节点不可用。
+ ///
+ public static bool IsInvalidNode(this Node node)
+ {
+ return node is null ||
+ !GodotObject.IsInstanceValid(node) ||
+ !node.IsInsideTree();
+ }
+}
+#endif
\ No newline at end of file