diff --git a/GFramework.Godot/coroutine/Timing.cs b/GFramework.Godot/coroutine/Timing.cs index 3b850c2..7e22f49 100644 --- a/GFramework.Godot/coroutine/Timing.cs +++ b/GFramework.Godot/coroutine/Timing.cs @@ -2,6 +2,7 @@ using GFramework.Core.Abstractions.coroutine; using GFramework.Core.coroutine; using GFramework.Core.coroutine.instructions; +using GFramework.Godot.extensions; using Godot; namespace GFramework.Godot.coroutine; @@ -62,16 +63,17 @@ public partial class Timing : Node var tree = (SceneTree)Engine.GetMainLoop(); _instance = tree.Root.GetNodeOrNull(nameof(Timing)); - - if (_instance == null) + if (_instance != null) { - _instance = new Timing - { - Name = nameof(Timing) - }; - tree.Root.AddChild(_instance); + return _instance; } + _instance = new Timing + { + Name = nameof(Timing) + }; + tree.Root.WaitUntilReady(() => { tree.Root.AddChild(_instance); }); + return _instance; } } diff --git a/GFramework.Godot/extensions/NodeExtensions.cs b/GFramework.Godot/extensions/NodeExtensions.cs index b45a82f..ac93cd8 100644 --- a/GFramework.Godot/extensions/NodeExtensions.cs +++ b/GFramework.Godot/extensions/NodeExtensions.cs @@ -49,11 +49,40 @@ public static class NodeExtensions /// 如果节点尚未进入场景树,则等待 ready 信号。 /// 如果已经在场景树中,则立刻返回。 /// + /// 要等待其准备就绪的节点 + /// 表示异步操作的任务 public static async Task WaitUntilReady(this Node node) { if (!node.IsInsideTree()) await node.ToSignal(node, Node.SignalName.Ready); } + /// + /// 如果节点尚未进入场景树,则等待 ready 信号后执行回调函数。 + /// 如果已经在场景树中,则立即执行回调函数。 + /// + /// 要等待其准备就绪的节点 + /// 节点准备就绪后要执行的回调函数 + public static void WaitUntilReady(this Node node, Action callback) + { + // 检查节点是否已经在场景树中 + if (node.IsInsideTree()) + { + callback(); + return; + } + + _ = WaitAsync(); + return; + + // 异步等待节点准备就绪并执行回调 + async Task WaitAsync() + { + await node.ToSignal(node, Node.SignalName.Ready); + callback(); + } + } + + /// /// 检查节点是否有效: /// 1. 非 null