From 116a3d86ba6f6864f823f9d63f87f537a54a273d Mon Sep 17 00:00:00 2001 From: Atlinx Date: Thu, 28 Mar 2024 16:31:21 -0400 Subject: [PATCH] Remove AwakeMonitor Awake monitor is only necessary for UniTask due to how Unity Monobehaviours functioned. Specifically, MonoBehaviours would not call OnDestroy if they were not awaked first. Therefore UniTask had to rely on checking if the MonoBehaviour was set to null to detect if the MonoBehavior was destroyed. However in Godot, Predelete is always called when a node is freed, so there's no need to handle any edge cases. See https://github.com/Cysharp/UniTask/issues/435 the use of AwakeMonitor in UniTask. --- addons/GDTask/Triggers/AsyncDestroyTrigger.cs | 34 ++-------- .../GDTask/Triggers/AsyncEnterTreeTrigger.cs | 7 +- addons/GDTask/Triggers/AsyncReadyTrigger.cs | 4 +- addons/GDTask/Triggers/AsyncTriggerBase.cs | 35 +--------- .../GDTask/Triggers/AsyncTriggerExtensions.cs | 64 +++++++++---------- 5 files changed, 43 insertions(+), 101 deletions(-) diff --git a/addons/GDTask/Triggers/AsyncDestroyTrigger.cs b/addons/GDTask/Triggers/AsyncDestroyTrigger.cs index 9973596..35852bb 100644 --- a/addons/GDTask/Triggers/AsyncDestroyTrigger.cs +++ b/addons/GDTask/Triggers/AsyncDestroyTrigger.cs @@ -1,5 +1,5 @@ -using System.Threading; -using Godot; +using Godot; +using System.Threading; namespace Fractural.Tasks.Triggers { @@ -13,7 +13,7 @@ public static AsyncDestroyTrigger GetAsyncDestroyTrigger(this Node node) public sealed partial class AsyncDestroyTrigger : Node { - bool awakeCalled = false; + bool enterTreeCalled = false; bool called = false; CancellationTokenSource cancellationTokenSource; @@ -26,18 +26,13 @@ public CancellationToken CancellationToken cancellationTokenSource = new CancellationTokenSource(); } - if (!awakeCalled) - { - GDTaskPlayerLoopAutoload.AddAction(PlayerLoopTiming.Process, new AwakeMonitor(this)); - } - return cancellationTokenSource.Token; } } public override void _EnterTree() { - awakeCalled = true; + enterTreeCalled = true; } public override void _Notification(int what) @@ -69,27 +64,6 @@ public GDTask OnDestroyAsync() return tcs.Task; } - - class AwakeMonitor : IPlayerLoopItem - { - readonly AsyncDestroyTrigger trigger; - - public AwakeMonitor(AsyncDestroyTrigger trigger) - { - this.trigger = trigger; - } - - public bool MoveNext() - { - if (trigger.called) return false; - if (trigger == null) - { - trigger.OnDestroy(); - return false; - } - return true; - } - } } } diff --git a/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs b/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs index 5d6ed7b..601177a 100644 --- a/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs +++ b/addons/GDTask/Triggers/AsyncEnterTreeTrigger.cs @@ -1,11 +1,10 @@ -using System.Threading; -using Godot; +using Godot; namespace Fractural.Tasks.Triggers { public static partial class AsyncTriggerExtensions { - public static AsyncEnterTreeTrigger GetAsyncAwakeTrigger(this Node node) + public static AsyncEnterTreeTrigger GetAsyncEnterTreeTrigger(this Node node) { return node.GetOrAddImmediateChild(); } @@ -19,7 +18,7 @@ public override void _EnterTree() RaiseEvent(AsyncUnit.Default); } - public GDTask AwakeAsync() + public GDTask EnterTreeAsync() { if (calledEnterTree) return GDTask.CompletedTask; diff --git a/addons/GDTask/Triggers/AsyncReadyTrigger.cs b/addons/GDTask/Triggers/AsyncReadyTrigger.cs index c0a2415..1678fd3 100644 --- a/addons/GDTask/Triggers/AsyncReadyTrigger.cs +++ b/addons/GDTask/Triggers/AsyncReadyTrigger.cs @@ -4,7 +4,7 @@ namespace Fractural.Tasks.Triggers { public static partial class AsyncTriggerExtensions { - public static AsyncReadyTrigger GetAsyncStartTrigger(this Node node) + public static AsyncReadyTrigger GetAsyncReadyTrigger(this Node node) { return node.GetOrAddImmediateChild(); } @@ -21,7 +21,7 @@ public override void _Ready() RaiseEvent(AsyncUnit.Default); } - public GDTask StartAsync() + public GDTask ReadyAsync() { if (called) return GDTask.CompletedTask; diff --git a/addons/GDTask/Triggers/AsyncTriggerBase.cs b/addons/GDTask/Triggers/AsyncTriggerBase.cs index 4b5af21..e76e5f4 100644 --- a/addons/GDTask/Triggers/AsyncTriggerBase.cs +++ b/addons/GDTask/Triggers/AsyncTriggerBase.cs @@ -1,6 +1,6 @@ -using System; +using Godot; +using System; using System.Threading; -using Godot; namespace Fractural.Tasks.Triggers { @@ -32,21 +32,11 @@ void OnDestroy() internal void AddHandler(ITriggerHandler handler) { - if (!calledEnterTree) - { - GDTaskPlayerLoopAutoload.AddAction(PlayerLoopTiming.Process, new AwakeMonitor(this)); - } - triggerEvent.Add(handler); } internal void RemoveHandler(ITriggerHandler handler) { - if (!calledEnterTree) - { - GDTaskPlayerLoopAutoload.AddAction(PlayerLoopTiming.Process, new AwakeMonitor(this)); - } - triggerEvent.Remove(handler); } @@ -54,27 +44,6 @@ protected void RaiseEvent(T value) { triggerEvent.SetResult(value); } - - class AwakeMonitor : IPlayerLoopItem - { - readonly AsyncTriggerBase trigger; - - public AwakeMonitor(AsyncTriggerBase trigger) - { - this.trigger = trigger; - } - - public bool MoveNext() - { - if (trigger.calledEnterTree) return false; - if (trigger == null) - { - trigger.OnDestroy(); - return false; - } - return true; - } - } } public interface IAsyncOneShotTrigger diff --git a/addons/GDTask/Triggers/AsyncTriggerExtensions.cs b/addons/GDTask/Triggers/AsyncTriggerExtensions.cs index 6e0d82a..ba06dc5 100644 --- a/addons/GDTask/Triggers/AsyncTriggerExtensions.cs +++ b/addons/GDTask/Triggers/AsyncTriggerExtensions.cs @@ -1,7 +1,7 @@ -using System; -using System.Threading; -using Fractural.Tasks.Triggers; +using Fractural.Tasks.Triggers; using Godot; +using System; +using System.Threading; namespace Fractural.Tasks { @@ -20,33 +20,33 @@ namespace Fractural.Tasks.Triggers public static partial class AsyncTriggerExtensions { // Special for single operation. - public static T GetImmediateChild(this Node node, bool includeRoot = true) - { - if (node == null) throw new ArgumentNullException(nameof(node)); - if (includeRoot && node is T castedRoot) - return castedRoot; - else - { - foreach (Node child in node.GetChildren()) - if (child is T castedChild) return castedChild; - } - return default(T); - } + public static T GetImmediateChild(this Node node, bool includeRoot = true) + { + if (node == null) throw new ArgumentNullException(nameof(node)); + if (includeRoot && node is T castedRoot) + return castedRoot; + else + { + foreach (Node child in node.GetChildren()) + if (child is T castedChild) return castedChild; + } + return default(T); + } - public static T AddImmediateChild(this Node node) where T : Node, new() - { - T child = new T(); - node.AddChild(child); - return child; - } + public static T AddImmediateChild(this Node node) where T : Node, new() + { + T child = new T(); + node.AddChild(child); + return child; + } - public static T GetOrAddImmediateChild(this Node node) where T : Node, new() - { - T child = GetImmediateChild(node); - if (child == null) - child = AddImmediateChild(node); - return child; - } + public static T GetOrAddImmediateChild(this Node node) where T : Node, new() + { + T child = GetImmediateChild(node); + if (child == null) + child = AddImmediateChild(node); + return child; + } /// This function is called when the Node will be destroyed. public static GDTask OnDestroyAsync(this Node node) @@ -54,14 +54,14 @@ public static GDTask OnDestroyAsync(this Node node) return node.GetAsyncDestroyTrigger().OnDestroyAsync(); } - public static GDTask StartAsync(this Node node) + public static GDTask ReadyAsync(this Node node) { - return node.GetAsyncStartTrigger().StartAsync(); + return node.GetAsyncReadyTrigger().ReadyAsync(); } - public static GDTask AwakeAsync(this Node node) + public static GDTask EnterTreeAsync(this Node node) { - return node.GetAsyncAwakeTrigger().AwakeAsync(); + return node.GetAsyncEnterTreeTrigger().EnterTreeAsync(); } } }