From 05799843556811a5c7ed33666857d4697dc324d6 Mon Sep 17 00:00:00 2001 From: hadashiA Date: Thu, 2 Nov 2023 12:01:51 +0900 Subject: [PATCH] Use AsyncOperation.completed callback usually --- .../UniTask/Runtime/UnityAsyncExtensions.cs | 162 ++++++++++-------- .../UniTask/Runtime/UnityAsyncExtensions.tt | 34 ++-- 2 files changed, 104 insertions(+), 92 deletions(-) diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs index 915d55d..fb84fca 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.cs @@ -26,17 +26,17 @@ namespace Cysharp.Threading.Tasks return ToUniTask(asyncOperation, cancellationToken: cancellationToken); } - public static UniTask WithCancellation(this AsyncOperation asyncOperation, bool handleImmediately, CancellationToken cancellationToken) + public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately) { - return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); + return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); } - public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) + public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); if (asyncOperation.isDone) return UniTask.CompletedTask; - return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); + return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); } public struct AsyncOperationAwaiter : ICriticalNotifyCompletion @@ -105,7 +105,7 @@ namespace Cysharp.Threading.Tasks continuationAction = Continuation; } - public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress progress, bool handleImmediately, CancellationToken cancellationToken, out short token) + public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -121,19 +121,16 @@ namespace Cysharp.Threading.Tasks result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + + asyncOperation.completed += result.continuationAction; - if (handleImmediately) + if (cancelImmediately && cancellationToken.CanBeCanceled) { - asyncOperation.completed += result.continuationAction; - - if (cancellationToken.CanBeCanceled) + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { - result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => - { - var source = (AsyncOperationConfiguredSource)state; - source.core.TrySetCanceled(source.cancellationToken); - }, result); - } + var source = (AsyncOperationConfiguredSource)state; + source.core.TrySetCanceled(source.cancellationToken); + }, result); } TaskTracker.TrackActiveTask(result, 3); @@ -180,6 +177,11 @@ namespace Cysharp.Threading.Tasks return false; } + if (asyncOperation == null) + { + return false; + } + if (progress != null) { progress.Report(asyncOperation.progress); @@ -242,17 +244,17 @@ namespace Cysharp.Threading.Tasks return ToUniTask(asyncOperation, cancellationToken: cancellationToken); } - public static UniTask WithCancellation(this ResourceRequest asyncOperation, bool handleImmediately, CancellationToken cancellationToken) + public static UniTask WithCancellation(this ResourceRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately) { - return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); + return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); } - public static UniTask ToUniTask(this ResourceRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) + public static UniTask ToUniTask(this ResourceRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); - return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); + return new UniTask(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); } public struct ResourceRequestAwaiter : ICriticalNotifyCompletion @@ -325,7 +327,7 @@ namespace Cysharp.Threading.Tasks continuationAction = Continuation; } - public static IUniTaskSource Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, bool handleImmediately, CancellationToken cancellationToken, out short token) + public static IUniTaskSource Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -341,19 +343,16 @@ namespace Cysharp.Threading.Tasks result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + + asyncOperation.completed += result.continuationAction; - if (handleImmediately) + if (cancelImmediately && cancellationToken.CanBeCanceled) { - asyncOperation.completed += result.continuationAction; - - if (cancellationToken.CanBeCanceled) + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { - result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => - { - var source = (ResourceRequestConfiguredSource)state; - source.core.TrySetCanceled(source.cancellationToken); - }, result); - } + var source = (ResourceRequestConfiguredSource)state; + source.core.TrySetCanceled(source.cancellationToken); + }, result); } TaskTracker.TrackActiveTask(result, 3); @@ -404,6 +403,11 @@ namespace Cysharp.Threading.Tasks return false; } + if (asyncOperation == null) + { + return false; + } + if (progress != null) { progress.Report(asyncOperation.progress); @@ -467,17 +471,17 @@ namespace Cysharp.Threading.Tasks return ToUniTask(asyncOperation, cancellationToken: cancellationToken); } - public static UniTask WithCancellation(this AssetBundleRequest asyncOperation, bool handleImmediately, CancellationToken cancellationToken) + public static UniTask WithCancellation(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately) { - return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); + return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); } - public static UniTask ToUniTask(this AssetBundleRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) + public static UniTask ToUniTask(this AssetBundleRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset); - return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); + return new UniTask(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); } public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion @@ -550,7 +554,7 @@ namespace Cysharp.Threading.Tasks continuationAction = Continuation; } - public static IUniTaskSource Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, bool handleImmediately, CancellationToken cancellationToken, out short token) + public static IUniTaskSource Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -566,19 +570,16 @@ namespace Cysharp.Threading.Tasks result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + + asyncOperation.completed += result.continuationAction; - if (handleImmediately) + if (cancelImmediately && cancellationToken.CanBeCanceled) { - asyncOperation.completed += result.continuationAction; - - if (cancellationToken.CanBeCanceled) + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { - result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => - { - var source = (AssetBundleRequestConfiguredSource)state; - source.core.TrySetCanceled(source.cancellationToken); - }, result); - } + var source = (AssetBundleRequestConfiguredSource)state; + source.core.TrySetCanceled(source.cancellationToken); + }, result); } TaskTracker.TrackActiveTask(result, 3); @@ -629,6 +630,11 @@ namespace Cysharp.Threading.Tasks return false; } + if (asyncOperation == null) + { + return false; + } + if (progress != null) { progress.Report(asyncOperation.progress); @@ -693,17 +699,17 @@ namespace Cysharp.Threading.Tasks return ToUniTask(asyncOperation, cancellationToken: cancellationToken); } - public static UniTask WithCancellation(this AssetBundleCreateRequest asyncOperation, bool handleImmediately, CancellationToken cancellationToken) + public static UniTask WithCancellation(this AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately) { - return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); + return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); } - public static UniTask ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) + public static UniTask ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle); - return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); + return new UniTask(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); } public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion @@ -776,7 +782,7 @@ namespace Cysharp.Threading.Tasks continuationAction = Continuation; } - public static IUniTaskSource Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, bool handleImmediately, CancellationToken cancellationToken, out short token) + public static IUniTaskSource Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -792,19 +798,16 @@ namespace Cysharp.Threading.Tasks result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + + asyncOperation.completed += result.continuationAction; - if (handleImmediately) + if (cancelImmediately && cancellationToken.CanBeCanceled) { - asyncOperation.completed += result.continuationAction; - - if (cancellationToken.CanBeCanceled) + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { - result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => - { - var source = (AssetBundleCreateRequestConfiguredSource)state; - source.core.TrySetCanceled(source.cancellationToken); - }, result); - } + var source = (AssetBundleCreateRequestConfiguredSource)state; + source.core.TrySetCanceled(source.cancellationToken); + }, result); } TaskTracker.TrackActiveTask(result, 3); @@ -855,6 +858,11 @@ namespace Cysharp.Threading.Tasks return false; } + if (asyncOperation == null) + { + return false; + } + if (progress != null) { progress.Report(asyncOperation.progress); @@ -919,12 +927,12 @@ namespace Cysharp.Threading.Tasks return ToUniTask(asyncOperation, cancellationToken: cancellationToken); } - public static UniTask WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, bool handleImmediately, CancellationToken cancellationToken) + public static UniTask WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately) { - return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); + return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); } - public static UniTask ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) + public static UniTask ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); @@ -936,7 +944,7 @@ namespace Cysharp.Threading.Tasks } return UniTask.FromResult(asyncOperation.webRequest); } - return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); + return new UniTask(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); } public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion @@ -1017,7 +1025,7 @@ namespace Cysharp.Threading.Tasks continuationAction = Continuation; } - public static IUniTaskSource Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress progress, bool handleImmediately, CancellationToken cancellationToken, out short token) + public static IUniTaskSource Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -1033,20 +1041,17 @@ namespace Cysharp.Threading.Tasks result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + + asyncOperation.completed += result.continuationAction; - if (handleImmediately) + if (cancelImmediately && cancellationToken.CanBeCanceled) { - asyncOperation.completed += result.continuationAction; - - if (cancellationToken.CanBeCanceled) + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { - result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => - { - var source = (UnityWebRequestAsyncOperationConfiguredSource)state; - source.asyncOperation.webRequest.Abort(); - source.core.TrySetCanceled(source.cancellationToken); - }, result); - } + var source = (UnityWebRequestAsyncOperationConfiguredSource)state; + source.asyncOperation.webRequest.Abort(); + source.core.TrySetCanceled(source.cancellationToken); + }, result); } TaskTracker.TrackActiveTask(result, 3); @@ -1098,6 +1103,11 @@ namespace Cysharp.Threading.Tasks return false; } + if (asyncOperation == null) + { + return false; + } + if (progress != null) { progress.Report(asyncOperation.progress); diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt index e3e57d4..86dd72a 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UnityAsyncExtensions.tt @@ -54,12 +54,12 @@ namespace Cysharp.Threading.Tasks return ToUniTask(asyncOperation, cancellationToken: cancellationToken); } - public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, bool handleImmediately, CancellationToken cancellationToken) + public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken, bool cancelImmediately) { - return ToUniTask(asyncOperation, handleImmediately: handleImmediately, cancellationToken: cancellationToken); + return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); } - public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool handleImmediately = false, CancellationToken cancellationToken = default(CancellationToken)) + public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) { Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation)); if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<#= IsVoid(t) ? "" : "<" + t.returnType + ">" #>(cancellationToken); @@ -75,7 +75,7 @@ namespace Cysharp.Threading.Tasks <# } else { #> if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>; <# } #> - return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, handleImmediately, cancellationToken, out var token), token); + return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token); } public struct <#= t.typeName #>Awaiter : ICriticalNotifyCompletion @@ -168,7 +168,7 @@ namespace Cysharp.Threading.Tasks continuationAction = Continuation; } - public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress progress, bool handleImmediately, CancellationToken cancellationToken, out short token) + public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -184,22 +184,19 @@ namespace Cysharp.Threading.Tasks result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + + asyncOperation.completed += result.continuationAction; - if (handleImmediately) + if (cancelImmediately && cancellationToken.CanBeCanceled) { - asyncOperation.completed += result.continuationAction; - - if (cancellationToken.CanBeCanceled) + result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { - result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => - { - var source = (<#= t.typeName #>ConfiguredSource)state; + var source = (<#= t.typeName #>ConfiguredSource)state; <# if(IsUnityWebRequest(t)) { #> - source.asyncOperation.webRequest.Abort(); + source.asyncOperation.webRequest.Abort(); <# } #> - source.core.TrySetCanceled(source.cancellationToken); - }, result); - } + source.core.TrySetCanceled(source.cancellationToken); + }, result); } TaskTracker.TrackActiveTask(result, 3); @@ -259,6 +256,11 @@ namespace Cysharp.Threading.Tasks return false; } + if (asyncOperation == null) + { + return false; + } + if (progress != null) { progress.Report(asyncOperation.progress);