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