diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs index 55de21e0..1b4f7d4d 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/External/Addressables/AddressablesAsyncExtensions.cs @@ -21,17 +21,12 @@ public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle handle) return ToUniTask(handle).GetAwaiter(); } - public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) + public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCancelled = false) { - return ToUniTask(handle, cancellationToken: cancellationToken); + return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCancelled: autoReleaseWhenCancelled); } - public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately) - { - return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); - } - - public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) + public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCancelled = false) { if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); @@ -50,7 +45,7 @@ public static UniTask WithCancellation(this AsyncOperationHandle handle, Cancell return UniTask.CompletedTask; } - return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, out var token), token); + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCancelled, out var token), token); } public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion @@ -114,6 +109,7 @@ static AsyncOperationHandleConfiguredSource() CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; IProgress progress; + bool autoReleaseWhenCancelled; bool completed; UniTaskCompletionSourceCore core; @@ -123,7 +119,7 @@ static AsyncOperationHandleConfiguredSource() completedCallback = HandleCompleted; } - public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) + public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCancelled, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -139,13 +135,14 @@ public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTimin result.progress = progress; result.cancellationToken = cancellationToken; result.completed = false; + result.autoReleaseWhenCancelled = autoReleaseWhenCancelled; if (cancelImmediately && cancellationToken.CanBeCanceled) { result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { var promise = (AsyncOperationHandleConfiguredSource)state; - if (promise.handle.IsValid()) + if (autoReleaseWhenCancelled && promise.handle.IsValid()) { Addressables.Release(promise.handle); } @@ -179,7 +176,7 @@ void HandleCompleted(AsyncOperationHandle _) completed = true; if (cancellationToken.IsCancellationRequested) { - if (handle.IsValid()) + if (autoReleaseWhenCancelled && handle.IsValid()) { Addressables.Release(handle); } @@ -227,7 +224,7 @@ public bool MoveNext() if (cancellationToken.IsCancellationRequested) { completed = true; - if (handle.IsValid()) + if (autoReleaseWhenCancelled && handle.IsValid()) { Addressables.Release(handle); } @@ -264,17 +261,12 @@ public static UniTask.Awaiter GetAwaiter(this AsyncOperationHandle hand return ToUniTask(handle).GetAwaiter(); } - public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken) - { - return ToUniTask(handle, cancellationToken: cancellationToken); - } - - public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately) + public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCancelled = false) { - return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately); + return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCancelled: autoReleaseWhenCancelled); } - public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false) + public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCancelled = false) { if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken); @@ -292,7 +284,7 @@ public static UniTask WithCancellation(this AsyncOperationHandle handle return UniTask.FromResult(handle.Result); } - return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, out var token), token); + return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCancelled, out var token), token); } sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode> @@ -311,6 +303,7 @@ static AsyncOperationHandleConfiguredSource() CancellationToken cancellationToken; CancellationTokenRegistration cancellationTokenRegistration; IProgress progress; + bool autoReleaseWhenCancelled; bool completed; UniTaskCompletionSourceCore core; @@ -320,7 +313,7 @@ static AsyncOperationHandleConfiguredSource() completedCallback = HandleCompleted; } - public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, out short token) + public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCancelled, out short token) { if (cancellationToken.IsCancellationRequested) { @@ -336,13 +329,14 @@ public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoo result.cancellationToken = cancellationToken; result.completed = false; result.progress = progress; + result.autoReleaseWhenCancelled = autoReleaseWhenCancelled; if (cancelImmediately && cancellationToken.CanBeCanceled) { result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state => { var promise = (AsyncOperationHandleConfiguredSource)state; - if (promise.handle.IsValid()) + if (promise.autoReleaseWhenCancelled && promise.handle.IsValid()) { Addressables.Release(promise.handle); } @@ -376,7 +370,7 @@ void HandleCompleted(AsyncOperationHandle argHandle) completed = true; if (cancellationToken.IsCancellationRequested) { - if (handle.IsValid()) + if (autoReleaseWhenCancelled && handle.IsValid()) { Addressables.Release(handle); } @@ -429,7 +423,7 @@ public bool MoveNext() if (cancellationToken.IsCancellationRequested) { completed = true; - if (handle.IsValid()) + if (autoReleaseWhenCancelled && handle.IsValid()) { Addressables.Release(handle); }