From 3654a9e2f98ab9d95762a15df54e4c3f4b9dad21 Mon Sep 17 00:00:00 2001 From: neuecc Date: Tue, 21 Apr 2020 13:36:23 +0900 Subject: [PATCH] WhenAll and WhenAny --- .../UniRx.Async/EnumeratorAsyncExtensions.cs | 14 +- Assets/UniRx.Async/Internal/ArrayPoolUtil.cs | 2 +- Assets/UniRx.Async/Internal/StatePool.cs | 52 + Assets/UniRx.Async/UniTask.Delay.cs | 50 +- Assets/UniRx.Async/UniTask.WaitUntil.cs | 437 +- .../UniRx.Async/UniTask.WhenAll.Generated.cs | 6738 ++++++++++++----- .../UniTask.WhenAll.Generated.cs.meta | 11 - .../UniRx.Async/UniTask.WhenAll.Generated.tt | 127 + Assets/UniRx.Async/UniTask.WhenAll.cs | 291 +- .../UniRx.Async/UniTask.WhenAny.Generated.cs | 6419 ++++++++++++---- .../UniTask.WhenAny.Generated.cs.meta | 11 - .../UniRx.Async/UniTask.WhenAny.Generated.tt | 122 + Assets/UniRx.Async/UniTask.WhenAny.cs | 519 +- Assets/UniRx.Async/UniTaskCompletionSource.cs | 121 +- Assets/UniRx.Async/UniTaskExtensions.cs | 22 +- Assets/UniRx.Async/UnityAsyncExtensions.cs | 4 +- 16 files changed, 11143 insertions(+), 3797 deletions(-) delete mode 100644 Assets/UniRx.Async/UniTask.WhenAll.Generated.cs.meta create mode 100644 Assets/UniRx.Async/UniTask.WhenAll.Generated.tt delete mode 100644 Assets/UniRx.Async/UniTask.WhenAny.Generated.cs.meta create mode 100644 Assets/UniRx.Async/UniTask.WhenAny.Generated.tt diff --git a/Assets/UniRx.Async/EnumeratorAsyncExtensions.cs b/Assets/UniRx.Async/EnumeratorAsyncExtensions.cs index d31388d..4438f5b 100644 --- a/Assets/UniRx.Async/EnumeratorAsyncExtensions.cs +++ b/Assets/UniRx.Async/EnumeratorAsyncExtensions.cs @@ -96,7 +96,7 @@ namespace UniRx.Async { if (cancellationToken.IsCancellationRequested) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); return false; } @@ -109,11 +109,11 @@ namespace UniRx.Async } catch (Exception ex) { - core.SetException(ex); + core.TrySetException(ex); return false; } - core.SetResult(null); + core.TrySetResult(null); return false; } @@ -126,6 +126,14 @@ namespace UniRx.Async exception = default; } + ~EnumeratorPromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } + // Unwrap YieldInstructions static IEnumerator ConsumeEnumerator(IEnumerator enumerator) diff --git a/Assets/UniRx.Async/Internal/ArrayPoolUtil.cs b/Assets/UniRx.Async/Internal/ArrayPoolUtil.cs index 127bb31..ee58010 100644 --- a/Assets/UniRx.Async/Internal/ArrayPoolUtil.cs +++ b/Assets/UniRx.Async/Internal/ArrayPoolUtil.cs @@ -40,7 +40,7 @@ namespace UniRx.Async.Internal return new RentArray(array, array.Length, null); } - var defaultCount = 4; + var defaultCount = 32; if (source is ICollection coll) { defaultCount = coll.Count; diff --git a/Assets/UniRx.Async/Internal/StatePool.cs b/Assets/UniRx.Async/Internal/StatePool.cs index b46f07b..7fe114b 100644 --- a/Assets/UniRx.Async/Internal/StatePool.cs +++ b/Assets/UniRx.Async/Internal/StatePool.cs @@ -10,6 +10,11 @@ namespace UniRx.Async.Internal { return StatePool.Create(item1, item2); } + + public static StateTuple Create(T1 item1, T2 item2, T3 item3) + { + return StatePool.Create(item1, item2, item3); + } } internal class StateTuple : IDisposable @@ -54,4 +59,51 @@ namespace UniRx.Async.Internal queue.Enqueue(tuple); } } + + internal class StateTuple : IDisposable + { + public T1 Item1; + public T2 Item2; + public T3 Item3; + + public void Deconstruct(out T1 item1, out T2 item2, out T3 item3) + { + item1 = this.Item1; + item2 = this.Item2; + item3 = this.Item3; + } + + public void Dispose() + { + StatePool.Return(this); + } + } + + internal static class StatePool + { + static readonly ConcurrentQueue> queue = new ConcurrentQueue>(); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static StateTuple Create(T1 item1, T2 item2, T3 item3) + { + if (queue.TryDequeue(out var value)) + { + value.Item1 = item1; + value.Item2 = item2; + value.Item3 = item3; + return value; + } + + return new StateTuple { Item1 = item1, Item2 = item2, Item3 = item3 }; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Return(StateTuple tuple) + { + tuple.Item1 = default; + tuple.Item2 = default; + tuple.Item3 = default; + queue.Enqueue(tuple); + } + } } diff --git a/Assets/UniRx.Async/UniTask.Delay.cs b/Assets/UniRx.Async/UniTask.Delay.cs index feb8074..df3f4ef 100644 --- a/Assets/UniRx.Async/UniTask.Delay.cs +++ b/Assets/UniRx.Async/UniTask.Delay.cs @@ -24,8 +24,6 @@ namespace UniRx.Async public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { - PlayerLoopHelper.Initialize( - if (delayFrameCount < 0) { throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount); @@ -121,11 +119,11 @@ namespace UniRx.Async { if (cancellationToken.IsCancellationRequested) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); return false; } - core.SetResult(null); + core.TrySetResult(null); return false; } @@ -134,6 +132,14 @@ namespace UniRx.Async core.Reset(); cancellationToken = default; } + + ~YieldPromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } } sealed class DelayFramePromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem @@ -202,13 +208,13 @@ namespace UniRx.Async { if (cancellationToken.IsCancellationRequested) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); return false; } if (currentFrameCount == delayFrameCount) { - core.SetResult(null); + core.TrySetResult(null); return false; } @@ -223,6 +229,14 @@ namespace UniRx.Async delayFrameCount = default; cancellationToken = default; } + + ~DelayFramePromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } } sealed class DelayPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem @@ -292,14 +306,14 @@ namespace UniRx.Async { if (cancellationToken.IsCancellationRequested) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); return false; } elapsed += Time.deltaTime; if (elapsed >= delayFrameTimeSpan) { - core.SetResult(null); + core.TrySetResult(null); return false; } @@ -313,6 +327,14 @@ namespace UniRx.Async elapsed = default; cancellationToken = default; } + + ~DelayPromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } } sealed class DelayIgnoreTimeScalePromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem @@ -382,14 +404,14 @@ namespace UniRx.Async { if (cancellationToken.IsCancellationRequested) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); return false; } elapsed += Time.unscaledDeltaTime; if (elapsed >= delayFrameTimeSpan) { - core.SetResult(null); + core.TrySetResult(null); return false; } @@ -403,6 +425,14 @@ namespace UniRx.Async elapsed = default; cancellationToken = default; } + + ~DelayIgnoreTimeScalePromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } } } diff --git a/Assets/UniRx.Async/UniTask.WaitUntil.cs b/Assets/UniRx.Async/UniTask.WaitUntil.cs index 7326201..554dc59 100644 --- a/Assets/UniRx.Async/UniTask.WaitUntil.cs +++ b/Assets/UniRx.Async/UniTask.WaitUntil.cs @@ -12,14 +12,12 @@ namespace UniRx.Async { public static UniTask WaitUntil(Func predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { - var promise = new WaitUntilPromise(predicate, timing, cancellationToken); - return promise.Task; + return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, out var token), token); } public static UniTask WaitWhile(Func predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) { - var promise = new WaitWhilePromise(predicate, timing, cancellationToken); - return promise.Task; + return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, out var token), token); } public static UniTask WaitUntilValueChanged(T target, Func monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -28,130 +26,293 @@ namespace UniRx.Async var unityObject = target as UnityEngine.Object; var isUnityObject = !object.ReferenceEquals(target, null); // don't use (unityObject == null) - return (isUnityObject) - ? new WaitUntilValueChangedUnityObjectPromise(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken).Task - : new WaitUntilValueChangedStandardObjectPromise(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken).Task; + return new UniTask(isUnityObject + ? WaitUntilValueChangedUnityObjectPromise.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out var token) + : WaitUntilValueChangedStandardObjectPromise.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out token), token); } - class WaitUntilPromise : PlayerLoopReusablePromiseBase + sealed class WaitUntilPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem { - readonly Func predicate; + static readonly PromisePool pool = new PromisePool(); - public WaitUntilPromise(Func predicate, PlayerLoopTiming timing, CancellationToken cancellationToken) - : base(timing, cancellationToken, 1) - { - this.predicate = predicate; - } + Func predicate; + CancellationToken cancellationToken; - protected override void OnRunningStart() + UniTaskCompletionSourceCore core; + + WaitUntilPromise() { } - public override bool MoveNext() + public static IUniTaskSource Create(Func predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) { if (cancellationToken.IsCancellationRequested) { - Complete(); - TrySetCanceled(); - return false; + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); } - bool result = default(bool); + var result = pool.TryRent() ?? new WaitUntilPromise(); + + result.predicate = predicate; + result.cancellationToken = cancellationToken; + + TaskTracker2.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { try { - result = predicate(); + TaskTracker2.RemoveTracking(this); + core.GetResult(token); } - catch (Exception ex) + finally { - Complete(); - TrySetException(ex); - return false; + pool.TryReturn(this); } - - if (result) - { - Complete(); - TrySetResult(); - return false; - } - - return true; } - } - class WaitWhilePromise : PlayerLoopReusablePromiseBase - { - readonly Func predicate; - - public WaitWhilePromise(Func predicate, PlayerLoopTiming timing, CancellationToken cancellationToken) - : base(timing, cancellationToken, 1) + public UniTaskStatus GetStatus(short token) { - this.predicate = predicate; + return core.GetStatus(token); } - protected override void OnRunningStart() + public UniTaskStatus UnsafeGetStatus() { + return core.UnsafeGetStatus(); } - public override bool MoveNext() + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() { if (cancellationToken.IsCancellationRequested) { - Complete(); - TrySetCanceled(); + core.TrySetCanceled(cancellationToken); return false; } - bool result = default(bool); try { - result = predicate(); + if (!predicate()) + { + return true; + } } catch (Exception ex) { - Complete(); - TrySetException(ex); + core.TrySetException(ex); return false; } - if (!result) + core.TrySetResult(null); + return false; + } + + public void Reset() + { + core.Reset(); + predicate = default; + cancellationToken = default; + } + + ~WaitUntilPromise() + { + if (pool.TryReturn(this)) { - Complete(); - TrySetResult(); + GC.ReRegisterForFinalize(this); + } + } + } + + sealed class WaitWhilePromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem + { + static readonly PromisePool pool = new PromisePool(); + + Func predicate; + CancellationToken cancellationToken; + + UniTaskCompletionSourceCore core; + + WaitWhilePromise() + { + } + + public static IUniTaskSource Create(Func predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + var result = pool.TryRent() ?? new WaitWhilePromise(); + + result.predicate = predicate; + result.cancellationToken = cancellationToken; + + TaskTracker2.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public void GetResult(short token) + { + try + { + TaskTracker2.RemoveTracking(this); + core.GetResult(token); + } + finally + { + pool.TryReturn(this); + } + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested) + { + core.TrySetCanceled(cancellationToken); return false; } - return true; + try + { + if (predicate()) + { + return true; + } + } + catch (Exception ex) + { + core.TrySetException(ex); + return false; + } + + core.TrySetResult(null); + return false; + } + + public void Reset() + { + core.Reset(); + predicate = default; + cancellationToken = default; + } + + ~WaitWhilePromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } } } // where T : UnityEngine.Object, can not add constraint - class WaitUntilValueChangedUnityObjectPromise : PlayerLoopReusablePromiseBase + sealed class WaitUntilValueChangedUnityObjectPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem { - readonly T target; - readonly Func monitorFunction; - readonly IEqualityComparer equalityComparer; + static readonly PromisePool> pool = new PromisePool>(); + + T target; U currentValue; + Func monitorFunction; + IEqualityComparer equalityComparer; + CancellationToken cancellationToken; - public WaitUntilValueChangedUnityObjectPromise(T target, Func monitorFunction, IEqualityComparer equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken) - : base(timing, cancellationToken, 1) - { - this.target = target; - this.monitorFunction = monitorFunction; - this.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); - this.currentValue = monitorFunction(target); - } + UniTaskCompletionSourceCore core; - protected override void OnRunningStart() + WaitUntilValueChangedUnityObjectPromise() { } - public override bool MoveNext() + public static IUniTaskSource Create(T target, Func monitorFunction, IEqualityComparer equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) + { + if (cancellationToken.IsCancellationRequested) + { + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + var result = pool.TryRent() ?? new WaitUntilValueChangedUnityObjectPromise(); + + result.target = target; + result.monitorFunction = monitorFunction; + result.currentValue = monitorFunction(target); + result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); + result.cancellationToken = cancellationToken; + + TaskTracker2.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public U GetResult(short token) + { + try + { + TaskTracker2.RemoveTracking(this); + return core.GetResult(token); + } + finally + { + pool.TryReturn(this); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() { if (cancellationToken.IsCancellationRequested || target == null) // destroyed = cancel. { - Complete(); - TrySetCanceled(); + core.TrySetCanceled(cancellationToken); return false; } @@ -166,45 +327,112 @@ namespace UniRx.Async } catch (Exception ex) { - Complete(); - TrySetException(ex); + core.TrySetException(ex); return false; } - Complete(); - currentValue = nextValue; - TrySetResult(nextValue); + core.TrySetResult(nextValue); return false; } + + public void Reset() + { + core.Reset(); + target = default; + currentValue = default; + monitorFunction = default; + equalityComparer = default; + cancellationToken = default; + } + + ~WaitUntilValueChangedUnityObjectPromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } } - class WaitUntilValueChangedStandardObjectPromise : PlayerLoopReusablePromiseBase + + sealed class WaitUntilValueChangedStandardObjectPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem where T : class { - readonly WeakReference target; - readonly Func monitorFunction; - readonly IEqualityComparer equalityComparer; + static readonly PromisePool> pool = new PromisePool>(); + + WeakReference target; U currentValue; + Func monitorFunction; + IEqualityComparer equalityComparer; + CancellationToken cancellationToken; - public WaitUntilValueChangedStandardObjectPromise(T target, Func monitorFunction, IEqualityComparer equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken) - : base(timing, cancellationToken, 1) - { - this.target = new WeakReference(target, false); // wrap in WeakReference. - this.monitorFunction = monitorFunction; - this.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); - this.currentValue = monitorFunction(target); - } + UniTaskCompletionSourceCore core; - protected override void OnRunningStart() + WaitUntilValueChangedStandardObjectPromise() { } - public override bool MoveNext() + public static IUniTaskSource Create(T target, Func monitorFunction, IEqualityComparer equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token) { - if (cancellationToken.IsCancellationRequested || !target.TryGetTarget(out var t)) + if (cancellationToken.IsCancellationRequested) { - Complete(); - TrySetCanceled(); + return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token); + } + + var result = pool.TryRent() ?? new WaitUntilValueChangedStandardObjectPromise(); + + result.target = new WeakReference(target, false); // wrap in WeakReference. + result.monitorFunction = monitorFunction; + result.currentValue = monitorFunction(target); + result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault(); + result.cancellationToken = cancellationToken; + + TaskTracker2.TrackActiveTask(result, 3); + + PlayerLoopHelper.AddAction(timing, result); + + token = result.core.Version; + return result; + } + + public U GetResult(short token) + { + try + { + TaskTracker2.RemoveTracking(this); + return core.GetResult(token); + } + finally + { + pool.TryReturn(this); + } + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public bool MoveNext() + { + if (cancellationToken.IsCancellationRequested || !target.TryGetTarget(out var t)) // doesn't find = cancel. + { + core.TrySetCanceled(cancellationToken); return false; } @@ -219,16 +447,31 @@ namespace UniRx.Async } catch (Exception ex) { - Complete(); - TrySetException(ex); + core.TrySetException(ex); return false; } - Complete(); - currentValue = nextValue; - TrySetResult(nextValue); + core.TrySetResult(nextValue); return false; } + + public void Reset() + { + core.Reset(); + target = default; + currentValue = default; + monitorFunction = default; + equalityComparer = default; + cancellationToken = default; + } + + ~WaitUntilValueChangedStandardObjectPromise() + { + if (pool.TryReturn(this)) + { + GC.ReRegisterForFinalize(this); + } + } } } } diff --git a/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs b/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs index bda09db..8652192 100644 --- a/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs +++ b/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs @@ -1,1863 +1,5081 @@ -#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6)) -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Threading; +using UniRx.Async.Internal; namespace UniRx.Async { public partial struct UniTask { - public static async UniTask<(T1 result1, T2 result2)> WhenAll(UniTask task1, UniTask task2) + + public static UniTask<(T1, T2)> WhenAll(UniTask task1, UniTask task2) { - return await new WhenAllPromise(task1, task2); + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2)>(new WhenAllPromise(task1, task2), 0); } - public static async UniTask<(T1 result1, T2 result2, T3 result3)> WhenAll(UniTask task1, UniTask task2, UniTask task3) + sealed class WhenAllPromise : IUniTaskSource<(T1, T2)> { - return await new WhenAllPromise(task1, task2, task3); - } - - public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4) - { - return await new WhenAllPromise(task1, task2, task3, task4); - } - - public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4, T5 result5)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) - { - return await new WhenAllPromise(task1, task2, task3, task4, task5); - } - - public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) - { - return await new WhenAllPromise(task1, task2, task3, task4, task5, task6); - } - - public static async UniTask<(T1 result1, T2 result2, T3 result3, T4 result4, T5 result5, T6 result6, T7 result7)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) - { - return await new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7); - } - - class WhenAllPromise - { - const int MaxCount = 2; - - T1 result1; - T2 result2; - ExceptionDispatchInfo exception; - int completeCount; - Action whenComplete; + T1 t1 = default; + T2 t2 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2)> core; public WhenAllPromise(UniTask task1, UniTask task2) { - this.completeCount = 0; - this.whenComplete = null; - this.result1 = default(T1); - this.result2 = default(T2); - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - RunTask1(task1); - RunTask2(task2); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } - - void RunTask1(UniTask task) - { - if (task.IsCompleted) - { - try + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) { - result1 = task.Result; + TryInvokeContinuationT1(this, awaiter); } - catch (Exception ex) + else { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask1Async(task).Forget(); - } - } - - async UniTaskVoid RunTask1Async(UniTask task) - { - try - { - result1 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask2(UniTask task) - { - if (task.IsCompleted) - { - try - { - result2 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask2Async(task).Forget(); - } - } - - async UniTaskVoid RunTask2Async(UniTask task) - { - try - { - result2 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAllPromise parent; - - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get - { - return parent.exception != null || parent.completeCount == MaxCount; - } - } - - public (T1, T2) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.result1, parent.result2); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 2) + { + self.core.TrySetResult((self.t1, self.t2)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 2) + { + self.core.TrySetResult((self.t1, self.t2)); + } + } + + + public (T1, T2) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); } } - - class WhenAllPromise + + public static UniTask<(T1, T2, T3)> WhenAll(UniTask task1, UniTask task2, UniTask task3) { - const int MaxCount = 3; + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult())); + } - T1 result1; - T2 result2; - T3 result3; - ExceptionDispatchInfo exception; - int completeCount; - Action whenComplete; + return new UniTask<(T1, T2, T3)>(new WhenAllPromise(task1, task2, task3), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3)> core; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3) { - this.completeCount = 0; - this.whenComplete = null; - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - RunTask1(task1); - RunTask2(task2); - RunTask3(task3); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } - - void RunTask1(UniTask task) - { - if (task.IsCompleted) - { - try + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) { - result1 = task.Result; + TryInvokeContinuationT1(this, awaiter); } - catch (Exception ex) + else { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask1Async(task).Forget(); - } - } - - async UniTaskVoid RunTask1Async(UniTask task) - { - try - { - result1 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask2(UniTask task) - { - if (task.IsCompleted) - { - try - { - result2 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask2Async(task).Forget(); - } - } - - async UniTaskVoid RunTask2Async(UniTask task) - { - try - { - result2 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask3(UniTask task) - { - if (task.IsCompleted) - { - try - { - result3 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask3Async(task).Forget(); - } - } - - async UniTaskVoid RunTask3Async(UniTask task) - { - try - { - result3 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAllPromise parent; - - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get - { - return parent.exception != null || parent.completeCount == MaxCount; - } - } - - public (T1, T2, T3) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.result1, parent.result2, parent.result3); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 3) + { + self.core.TrySetResult((self.t1, self.t2, self.t3)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 3) + { + self.core.TrySetResult((self.t1, self.t2, self.t3)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 3) + { + self.core.TrySetResult((self.t1, self.t2, self.t3)); + } + } + + + public (T1, T2, T3) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); } } - - class WhenAllPromise + + public static UniTask<(T1, T2, T3, T4)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4) { - const int MaxCount = 4; + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult())); + } - T1 result1; - T2 result2; - T3 result3; - T4 result4; - ExceptionDispatchInfo exception; - int completeCount; - Action whenComplete; + return new UniTask<(T1, T2, T3, T4)>(new WhenAllPromise(task1, task2, task3, task4), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4)> core; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4) { - this.completeCount = 0; - this.whenComplete = null; - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - RunTask1(task1); - RunTask2(task2); - RunTask3(task3); - RunTask4(task4); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } - - void RunTask1(UniTask task) - { - if (task.IsCompleted) - { - try + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) { - result1 = task.Result; + TryInvokeContinuationT1(this, awaiter); } - catch (Exception ex) + else { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask1Async(task).Forget(); - } - } - - async UniTaskVoid RunTask1Async(UniTask task) - { - try - { - result1 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask2(UniTask task) - { - if (task.IsCompleted) - { - try - { - result2 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask2Async(task).Forget(); - } - } - - async UniTaskVoid RunTask2Async(UniTask task) - { - try - { - result2 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask3(UniTask task) - { - if (task.IsCompleted) - { - try - { - result3 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask3Async(task).Forget(); - } - } - - async UniTaskVoid RunTask3Async(UniTask task) - { - try - { - result3 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask4(UniTask task) - { - if (task.IsCompleted) - { - try - { - result4 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask4Async(task).Forget(); - } - } - - async UniTaskVoid RunTask4Async(UniTask task) - { - try - { - result4 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAllPromise parent; - - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get - { - return parent.exception != null || parent.completeCount == MaxCount; - } - } - - public (T1, T2, T3, T4) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.result1, parent.result2, parent.result3, parent.result4); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 4) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4)); + } + } + + + public (T1, T2, T3, T4) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); } } - - class WhenAllPromise + + public static UniTask<(T1, T2, T3, T4, T5)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) { - const int MaxCount = 5; + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult())); + } - T1 result1; - T2 result2; - T3 result3; - T4 result4; - T5 result5; - ExceptionDispatchInfo exception; - int completeCount; - Action whenComplete; + return new UniTask<(T1, T2, T3, T4, T5)>(new WhenAllPromise(task1, task2, task3, task4, task5), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5)> core; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) { - this.completeCount = 0; - this.whenComplete = null; - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.result5 = default(T5); - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - RunTask1(task1); - RunTask2(task2); - RunTask3(task3); - RunTask4(task4); - RunTask5(task5); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } - - void RunTask1(UniTask task) - { - if (task.IsCompleted) - { - try + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) { - result1 = task.Result; + TryInvokeContinuationT1(this, awaiter); } - catch (Exception ex) + else { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask1Async(task).Forget(); - } - } - - async UniTaskVoid RunTask1Async(UniTask task) - { - try - { - result1 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask2(UniTask task) - { - if (task.IsCompleted) - { - try - { - result2 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask2Async(task).Forget(); - } - } - - async UniTaskVoid RunTask2Async(UniTask task) - { - try - { - result2 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask3(UniTask task) - { - if (task.IsCompleted) - { - try - { - result3 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask3Async(task).Forget(); - } - } - - async UniTaskVoid RunTask3Async(UniTask task) - { - try - { - result3 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask4(UniTask task) - { - if (task.IsCompleted) - { - try - { - result4 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask4Async(task).Forget(); - } - } - - async UniTaskVoid RunTask4Async(UniTask task) - { - try - { - result4 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask5(UniTask task) - { - if (task.IsCompleted) - { - try - { - result5 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask5Async(task).Forget(); - } - } - - async UniTaskVoid RunTask5Async(UniTask task) - { - try - { - result5 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAllPromise parent; - - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get - { - return parent.exception != null || parent.completeCount == MaxCount; - } - } - - public (T1, T2, T3, T4, T5) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.result1, parent.result2, parent.result3, parent.result4, parent.result5); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 5) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5)); + } + } + + + public (T1, T2, T3, T4, T5) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); } } - - class WhenAllPromise + + public static UniTask<(T1, T2, T3, T4, T5, T6)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) { - const int MaxCount = 6; + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult())); + } - T1 result1; - T2 result2; - T3 result3; - T4 result4; - T5 result5; - T6 result6; - ExceptionDispatchInfo exception; - int completeCount; - Action whenComplete; + return new UniTask<(T1, T2, T3, T4, T5, T6)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6)> core; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) { - this.completeCount = 0; - this.whenComplete = null; - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.result5 = default(T5); - this.result6 = default(T6); - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - RunTask1(task1); - RunTask2(task2); - RunTask3(task3); - RunTask4(task4); - RunTask5(task5); - RunTask6(task6); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } - - void RunTask1(UniTask task) - { - if (task.IsCompleted) - { - try + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) { - result1 = task.Result; + TryInvokeContinuationT1(this, awaiter); } - catch (Exception ex) + else { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask1Async(task).Forget(); - } - } - - async UniTaskVoid RunTask1Async(UniTask task) - { - try - { - result1 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask2(UniTask task) - { - if (task.IsCompleted) - { - try - { - result2 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask2Async(task).Forget(); - } - } - - async UniTaskVoid RunTask2Async(UniTask task) - { - try - { - result2 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask3(UniTask task) - { - if (task.IsCompleted) - { - try - { - result3 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask3Async(task).Forget(); - } - } - - async UniTaskVoid RunTask3Async(UniTask task) - { - try - { - result3 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask4(UniTask task) - { - if (task.IsCompleted) - { - try - { - result4 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask4Async(task).Forget(); - } - } - - async UniTaskVoid RunTask4Async(UniTask task) - { - try - { - result4 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask5(UniTask task) - { - if (task.IsCompleted) - { - try - { - result5 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask5Async(task).Forget(); - } - } - - async UniTaskVoid RunTask5Async(UniTask task) - { - try - { - result5 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask6(UniTask task) - { - if (task.IsCompleted) - { - try - { - result6 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask6Async(task).Forget(); - } - } - - async UniTaskVoid RunTask6Async(UniTask task) - { - try - { - result6 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAllPromise parent; - - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get - { - return parent.exception != null || parent.completeCount == MaxCount; - } - } - - public (T1, T2, T3, T4, T5, T6) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.result1, parent.result2, parent.result3, parent.result4, parent.result5, parent.result6); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 6) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6)); + } + } + + + public (T1, T2, T3, T4, T5, T6) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); } } - - class WhenAllPromise + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) { - const int MaxCount = 7; + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult())); + } - T1 result1; - T2 result2; - T3 result3; - T4 result4; - T5 result5; - T6 result6; - T7 result7; - ExceptionDispatchInfo exception; - int completeCount; - Action whenComplete; + return new UniTask<(T1, T2, T3, T4, T5, T6, T7)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7)> core; public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) { - this.completeCount = 0; - this.whenComplete = null; - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.result5 = default(T5); - this.result6 = default(T6); - this.result7 = default(T7); - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - RunTask1(task1); - RunTask2(task2); - RunTask3(task3); - RunTask4(task4); - RunTask5(task5); - RunTask6(task6); - RunTask7(task7); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } - - void RunTask1(UniTask task) - { - if (task.IsCompleted) - { - try + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) { - result1 = task.Result; + TryInvokeContinuationT1(this, awaiter); } - catch (Exception ex) + else { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask1Async(task).Forget(); - } - } - - async UniTaskVoid RunTask1Async(UniTask task) - { - try - { - result1 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask2(UniTask task) - { - if (task.IsCompleted) - { - try - { - result2 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask2Async(task).Forget(); - } - } - - async UniTaskVoid RunTask2Async(UniTask task) - { - try - { - result2 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask3(UniTask task) - { - if (task.IsCompleted) - { - try - { - result3 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask3Async(task).Forget(); - } - } - - async UniTaskVoid RunTask3Async(UniTask task) - { - try - { - result3 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask4(UniTask task) - { - if (task.IsCompleted) - { - try - { - result4 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask4Async(task).Forget(); - } - } - - async UniTaskVoid RunTask4Async(UniTask task) - { - try - { - result4 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask5(UniTask task) - { - if (task.IsCompleted) - { - try - { - result5 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask5Async(task).Forget(); - } - } - - async UniTaskVoid RunTask5Async(UniTask task) - { - try - { - result5 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask6(UniTask task) - { - if (task.IsCompleted) - { - try - { - result6 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask6Async(task).Forget(); - } - } - - async UniTaskVoid RunTask6Async(UniTask task) - { - try - { - result6 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - void RunTask7(UniTask task) - { - if (task.IsCompleted) - { - try - { - result7 = task.Result; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - else - { - RunTask7Async(task).Forget(); - } - } - - async UniTaskVoid RunTask7Async(UniTask task) - { - try - { - result7 = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == MaxCount) - { - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAllPromise parent; - - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get - { - return parent.exception != null || parent.completeCount == MaxCount; - } - } - - public (T1, T2, T3, T4, T5, T6, T7) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.result1, parent.result2, parent.result3, parent.result4, parent.result5, parent.result6, parent.result7); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 7) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); } } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult())); + } + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 8) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 9) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 10) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 11) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 12) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully() && task13.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult(), task13.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + T13 t13 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + static void TryInvokeContinuationT13(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t13 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 13) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully() && task13.Status.IsCompletedSuccessfully() && task14.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult(), task13.GetAwaiter().GetResult(), task14.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + T13 t13 = default; + T14 t14 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT13(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t13 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + static void TryInvokeContinuationT14(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t14 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 14) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } + + public static UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)> WhenAll(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + if (task1.Status.IsCompletedSuccessfully() && task2.Status.IsCompletedSuccessfully() && task3.Status.IsCompletedSuccessfully() && task4.Status.IsCompletedSuccessfully() && task5.Status.IsCompletedSuccessfully() && task6.Status.IsCompletedSuccessfully() && task7.Status.IsCompletedSuccessfully() && task8.Status.IsCompletedSuccessfully() && task9.Status.IsCompletedSuccessfully() && task10.Status.IsCompletedSuccessfully() && task11.Status.IsCompletedSuccessfully() && task12.Status.IsCompletedSuccessfully() && task13.Status.IsCompletedSuccessfully() && task14.Status.IsCompletedSuccessfully() && task15.Status.IsCompletedSuccessfully()) + { + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>((task1.GetAwaiter().GetResult(), task2.GetAwaiter().GetResult(), task3.GetAwaiter().GetResult(), task4.GetAwaiter().GetResult(), task5.GetAwaiter().GetResult(), task6.GetAwaiter().GetResult(), task7.GetAwaiter().GetResult(), task8.GetAwaiter().GetResult(), task9.GetAwaiter().GetResult(), task10.GetAwaiter().GetResult(), task11.GetAwaiter().GetResult(), task12.GetAwaiter().GetResult(), task13.GetAwaiter().GetResult(), task14.GetAwaiter().GetResult(), task15.GetAwaiter().GetResult())); + } + + return new UniTask<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)>(new WhenAllPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14, task15), 0); + } + + sealed class WhenAllPromise : IUniTaskSource<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)> + { + T1 t1 = default; + T2 t2 = default; + T3 t3 = default; + T4 t4 = default; + T5 t5 = default; + T6 t6 = default; + T7 t7 = default; + T8 t8 = default; + T9 t9 = default; + T10 t10 = default; + T11 t11 = default; + T12 t12 = default; + T13 t13 = default; + T14 t14 = default; + T15 t15 = default; + int completedCount; + UniTaskCompletionSourceCore<(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)> core; + + public WhenAllPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task15.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT15(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT15(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t1 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT2(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t2 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT3(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t3 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT4(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t4 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT5(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t5 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT6(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t6 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT7(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t7 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT8(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t8 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT9(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t9 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT10(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t10 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT11(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t11 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT12(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t12 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT13(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t13 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT14(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t14 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + static void TryInvokeContinuationT15(WhenAllPromise self, in UniTask.Awaiter awaiter) + { + try + { + self.t15 = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 15) + { + self.core.TrySetResult((self.t1, self.t2, self.t3, self.t4, self.t5, self.t6, self.t7, self.t8, self.t9, self.t10, self.t11, self.t12, self.t13, self.t14, self.t15)); + } + } + + + public (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs.meta b/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs.meta deleted file mode 100644 index 40ed46c..0000000 --- a/Assets/UniRx.Async/UniTask.WhenAll.Generated.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5110117231c8a6d4095fd0cbd3f4c142 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniRx.Async/UniTask.WhenAll.Generated.tt b/Assets/UniRx.Async/UniTask.WhenAll.Generated.tt new file mode 100644 index 0000000..5480dc0 --- /dev/null +++ b/Assets/UniRx.Async/UniTask.WhenAll.Generated.tt @@ -0,0 +1,127 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading; +using UniRx.Async.Internal; + +namespace UniRx.Async +{ + public partial struct UniTask + { +<# for(var i = 2; i <= 15; i++ ) { + var range = Enumerable.Range(1, i); + var t = string.Join(", ", range.Select(x => "T" + x)); + var args = string.Join(", ", range.Select(x => $"UniTask task{x}")); + var targs = string.Join(", ", range.Select(x => $"task{x}")); + var tresult = string.Join(", ", range.Select(x => $"task{x}.GetAwaiter().GetResult()")); + var completedSuccessfullyAnd = string.Join(" && ", range.Select(x => $"task{x}.Status.IsCompletedSuccessfully()")); + var tfield = string.Join(", ", range.Select(x => $"self.t{x}")); +#> + + public static UniTask<(<#= t #>)> WhenAll<<#= t #>>(<#= args #>) + { + if (<#= completedSuccessfullyAnd #>) + { + return new UniTask<(<#= t #>)>((<#= tresult #>)); + } + + return new UniTask<(<#= t #>)>(new WhenAllPromise<<#= t #>>(<#= targs #>), 0); + } + + sealed class WhenAllPromise<<#= t #>> : IUniTaskSource<(<#= t #>)> + { +<# for(var j = 1; j <= i; j++) { #> + T<#= j #> t<#= j #> = default; +<# } #> + int completedCount; + UniTaskCompletionSourceCore<(<#= t #>)> core; + + public WhenAllPromise(<#= args #>) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; +<# for(var j = 1; j <= i; j++) { #> + { + var awaiter = task<#= j #>.GetAwaiter(); + if (awaiter.IsCompleted) + { + TryInvokeContinuationT<#= j #>(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple>, UniTask>.Awaiter>)state) + { + TryInvokeContinuationT<#= j #>(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } +<# } #> + } + +<# for(var j = 1; j <= i; j++) { #> + static void TryInvokeContinuationT<#= j #>(WhenAllPromise<<#= t #>> self, in UniTask>.Awaiter awaiter) + { + try + { + self.t<#= j #> = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == <#= i #>) + { + self.core.TrySetResult((<#= tfield #>)); + } + } + +<# } #> + + public (<#= t #>) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + ~WhenAllPromise() + { + core.Reset(); + } + } +<# } #> + } +} \ No newline at end of file diff --git a/Assets/UniRx.Async/UniTask.WhenAll.cs b/Assets/UniRx.Async/UniTask.WhenAll.cs index 7b087d4..e9a83d7 100644 --- a/Assets/UniRx.Async/UniTask.WhenAll.cs +++ b/Assets/UniRx.Async/UniTask.WhenAll.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; using System.Threading; using UniRx.Async.Internal; @@ -12,285 +10,214 @@ namespace UniRx.Async { public partial struct UniTask { - // UniTask - - public static async UniTask WhenAll(params UniTask[] tasks) + public static UniTask WhenAll(params UniTask[] tasks) { - return await new WhenAllPromise(tasks, tasks.Length); + return new UniTask(new WhenAllPromise(tasks, tasks.Length), 0); } - public static async UniTask WhenAll(IEnumerable> tasks) + public static UniTask WhenAll(IEnumerable> tasks) { - WhenAllPromise promise; using (var span = ArrayPoolUtil.Materialize(tasks)) { - promise = new WhenAllPromise(span.Array, span.Length); + var promise = new WhenAllPromise(span.Array, span.Length); // consumed array in constructor. + return new UniTask(promise, 0); } - - return await promise; } - public static async UniTask WhenAll(params UniTask[] tasks) + public static UniTask WhenAll(params UniTask[] tasks) { - await new WhenAllPromise(tasks, tasks.Length); + return new UniTask(new WhenAllPromise(tasks, tasks.Length), 0); } - public static async UniTask WhenAll(IEnumerable tasks) + public static UniTask WhenAll(IEnumerable tasks) { - WhenAllPromise promise; using (var span = ArrayPoolUtil.Materialize(tasks)) { - promise = new WhenAllPromise(span.Array, span.Length); + var promise = new WhenAllPromise(span.Array, span.Length); // consumed array in constructor. + return new UniTask(promise, 0); } - - await promise; } - class WhenAllPromise + sealed class WhenAllPromise : IUniTaskSource { - readonly T[] result; + T[] result; int completeCount; - Action whenComplete; - ExceptionDispatchInfo exception; + UniTaskCompletionSourceCore core; // don't reset(called after GetResult, will invoke TrySetException.) public WhenAllPromise(UniTask[] tasks, int tasksLength) { + TaskTracker2.TrackActiveTask(this, 3); + this.completeCount = 0; - this.whenComplete = null; - this.exception = null; this.result = new T[tasksLength]; for (int i = 0; i < tasksLength; i++) { - if (tasks[i].Status.IsCompleted()) + UniTask.Awaiter awaiter; + try { - T value = default(T); - try - { - value = tasks[i].GetAwaiter().GetResult(); - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - continue; - } + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; + } - result[i] = value; - var count = Interlocked.Increment(ref completeCount); - if (count == result.Length) - { - TryCallContinuation(); - } + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter, i); } else { - RunTask(tasks[i], i).Forget(); + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter, int>)state) + { + TryInvokeContinuation(t.Item1, t.Item2, t.Item3); + } + }, StateTuple.Create(this, awaiter, i)); } } } - void TryCallContinuation() + static void TryInvokeContinuation(WhenAllPromise self, in UniTask.Awaiter awaiter, int i) { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask(UniTask task, int index) - { - T value = default(T); try { - value = await task; + self.result[i] = awaiter.GetResult(); } catch (Exception ex) { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); + self.core.TrySetException(ex); return; } - result[index] = value; - var count = Interlocked.Increment(ref completeCount); - if (count == result.Length) + if (Interlocked.Increment(ref self.completeCount) == self.result.Length) { - TryCallContinuation(); + self.core.TrySetResult(self.result); } } - public Awaiter GetAwaiter() + public T[] GetResult(short token) { - return new Awaiter(this); + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); } - public struct Awaiter : ICriticalNotifyCompletion + void IUniTaskSource.GetResult(short token) { - WhenAllPromise parent; + GetResult(token); + } - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } - public bool IsCompleted - { - get - { - return parent.exception != null || parent.result.Length == parent.completeCount; - } - } + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } - public T[] GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } - return parent.result; - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) - { - action(); - } - } - } + ~WhenAllPromise() + { + core.Reset(); } } - class WhenAllPromise + sealed class WhenAllPromise : IUniTaskSource { int completeCount; - int resultLength; - Action whenComplete; - ExceptionDispatchInfo exception; + int tasksLength; + UniTaskCompletionSourceCore core; // don't reset(called after GetResult, will invoke TrySetException.) public WhenAllPromise(UniTask[] tasks, int tasksLength) { + TaskTracker2.TrackActiveTask(this, 3); + + this.tasksLength = tasksLength; this.completeCount = 0; - this.whenComplete = null; - this.exception = null; - this.resultLength = tasksLength; for (int i = 0; i < tasksLength; i++) { - if (tasks[i].Status.IsCompleted()) + UniTask.Awaiter awaiter; + try { - try - { - tasks[i].GetAwaiter().GetResult(); - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - continue; - } + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; + } - var count = Interlocked.Increment(ref completeCount); - if (count == resultLength) - { - TryCallContinuation(); - } + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter); } else { - RunTask(tasks[i], i).Forget(); + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple)state) + { + TryInvokeContinuation(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } } - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask(UniTask task, int index) + static void TryInvokeContinuation(WhenAllPromise self, in UniTask.Awaiter awaiter) { try { - await task; + awaiter.GetResult(); } catch (Exception ex) { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); + self.core.TrySetException(ex); return; } - var count = Interlocked.Increment(ref completeCount); - if (count == resultLength) + if (Interlocked.Increment(ref self.completeCount) == self.tasksLength) { - TryCallContinuation(); + self.core.TrySetResult(AsyncUnit.Default); } } - public Awaiter GetAwaiter() + public void GetResult(short token) { - return new Awaiter(this); + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + core.GetResult(token); } - public struct Awaiter : ICriticalNotifyCompletion + public UniTaskStatus GetStatus(short token) { - WhenAllPromise parent; + return core.GetStatus(token); + } - public Awaiter(WhenAllPromise parent) - { - this.parent = parent; - } + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } - public bool IsCompleted - { - get - { - return parent.exception != null || parent.resultLength == parent.completeCount; - } - } + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } - public void GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) - { - action(); - } - } - } + ~WhenAllPromise() + { + core.Reset(); } } } diff --git a/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs b/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs index ebc0fe2..0773525 100644 --- a/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs +++ b/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs @@ -1,1527 +1,5130 @@ -#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6)) -#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member - +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; using System.Threading; +using UniRx.Async.Internal; namespace UniRx.Async { public partial struct UniTask { - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1))> WhenAny(UniTask task0, UniTask task1) + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2))> WhenAny(UniTask task1, UniTask task2) { - return await new WhenAnyPromise(task0, task1); + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2))>(new WhenAnyPromise(task1, task2), 0); } - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool hasResult, T2 result2))> WhenAny(UniTask task0, UniTask task1, UniTask task2) + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2))> { - return await new WhenAnyPromise(task0, task1, task2); - } + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2))> core; - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3))> WhenAny(UniTask task0, UniTask task1, UniTask task2, UniTask task3) - { - return await new WhenAnyPromise(task0, task1, task2, task3); - } - - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4))> WhenAny(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4) - { - return await new WhenAnyPromise(task0, task1, task2, task3, task4); - } - - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5))> WhenAny(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) - { - return await new WhenAnyPromise(task0, task1, task2, task3, task4, task5); - } - - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6))> WhenAny(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) - { - return await new WhenAnyPromise(task0, task1, task2, task3, task4, task5, task6); - } - - public static async UniTask<(int winArgumentIndex, (bool hasResult, T0 result0), (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7))> WhenAny(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) - { - return await new WhenAnyPromise(task0, task1, task2, task3, task4, task5, task6, task7); - } - - class WhenAnyPromise - { - T0 result0; - T1 result1; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; - - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; - - public WhenAnyPromise(UniTask task0, UniTask task1) + public WhenAnyPromise(UniTask task1, UniTask task2) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } + var awaiter = task1.GetAwaiter(); - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3))> WhenAny(UniTask task1, UniTask task2, UniTask task3) { - T0 result0; - T1 result1; - T2 result2; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3))>(new WhenAnyPromise(task1, task2, task3), 0); + } - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3))> core; - public WhenAnyPromise(UniTask task0, UniTask task1, UniTask task2) + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); - this.result2 = default(T2); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - RunTask2(task2).Forget(); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) + this.completedCount = 0; { - action.Invoke(); - } - } + var awaiter = task1.GetAwaiter(); - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask2(UniTask task) - { - T2 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result2 = value; - Volatile.Write(ref winArgumentIndex, 2); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1), (bool, T2)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1), (i == 2, parent.result2)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4) { - T0 result0; - T1 result1; - T2 result2; - T3 result3; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4))>(new WhenAnyPromise(task1, task2, task3, task4), 0); + } - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4))> core; - public WhenAnyPromise(UniTask task0, UniTask task1, UniTask task2, UniTask task3) + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - RunTask2(task2).Forget(); - RunTask3(task3).Forget(); - } + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask2(UniTask task) - { - T2 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result2 = value; - Volatile.Write(ref winArgumentIndex, 2); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask3(UniTask task) - { - T3 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result3 = value; - Volatile.Write(ref winArgumentIndex, 3); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1), (bool, T2), (bool, T3)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1), (i == 2, parent.result2), (i == 3, parent.result3)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) { - T0 result0; - T1 result1; - T2 result2; - T3 result3; - T4 result4; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5))>(new WhenAnyPromise(task1, task2, task3, task4, task5), 0); + } - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5))> core; - public WhenAnyPromise(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4) + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - RunTask2(task2).Forget(); - RunTask3(task3).Forget(); - RunTask4(task4).Forget(); - } + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask2(UniTask task) - { - T2 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result2 = value; - Volatile.Write(ref winArgumentIndex, 2); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask3(UniTask task) - { - T3 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result3 = value; - Volatile.Write(ref winArgumentIndex, 3); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask4(UniTask task) - { - T4 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result4 = value; - Volatile.Write(ref winArgumentIndex, 4); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1), (bool, T2), (bool, T3), (bool, T4)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1), (i == 2, parent.result2), (i == 3, parent.result3), (i == 4, parent.result4)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) { - T0 result0; - T1 result1; - T2 result2; - T3 result3; - T4 result4; - T5 result5; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6), 0); + } - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6))> core; - public WhenAnyPromise(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5) + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.result5 = default(T5); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - RunTask2(task2).Forget(); - RunTask3(task3).Forget(); - RunTask4(task4).Forget(); - RunTask5(task5).Forget(); - } + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask2(UniTask task) - { - T2 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result2 = value; - Volatile.Write(ref winArgumentIndex, 2); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask3(UniTask task) - { - T3 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result3 = value; - Volatile.Write(ref winArgumentIndex, 3); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask4(UniTask task) - { - T4 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result4 = value; - Volatile.Write(ref winArgumentIndex, 4); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask5(UniTask task) - { - T5 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result5 = value; - Volatile.Write(ref winArgumentIndex, 5); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1), (bool, T2), (bool, T3), (bool, T4), (bool, T5)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1), (i == 2, parent.result2), (i == 3, parent.result3), (i == 4, parent.result4), (i == 5, parent.result5)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) { - T0 result0; - T1 result1; - T2 result2; - T3 result3; - T4 result4; - T5 result5; - T6 result6; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7), 0); + } - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7))> core; - public WhenAnyPromise(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6) + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.result5 = default(T5); - this.result6 = default(T6); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - RunTask2(task2).Forget(); - RunTask3(task3).Forget(); - RunTask4(task4).Forget(); - RunTask5(task5).Forget(); - RunTask6(task6).Forget(); - } + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask2(UniTask task) - { - T2 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result2 = value; - Volatile.Write(ref winArgumentIndex, 2); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask3(UniTask task) - { - T3 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result3 = value; - Volatile.Write(ref winArgumentIndex, 3); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask4(UniTask task) - { - T4 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result4 = value; - Volatile.Write(ref winArgumentIndex, 4); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask5(UniTask task) - { - T5 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result5 = value; - Volatile.Write(ref winArgumentIndex, 5); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask6(UniTask task) - { - T6 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result6 = value; - Volatile.Write(ref winArgumentIndex, 6); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1), (bool, T2), (bool, T3), (bool, T4), (bool, T5), (bool, T6)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1), (i == 2, parent.result2), (i == 3, parent.result3), (i == 4, parent.result4), (i == 5, parent.result5), (i == 6, parent.result6)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) { - T0 result0; - T1 result1; - T2 result2; - T3 result3; - T4 result4; - T5 result5; - T6 result6; - T7 result7; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; - int winArgumentIndex; + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8), 0); + } - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8))> core; - public WhenAnyPromise(UniTask task0, UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7) + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); - this.result1 = default(T1); - this.result2 = default(T2); - this.result3 = default(T3); - this.result4 = default(T4); - this.result5 = default(T5); - this.result6 = default(T6); - this.result7 = default(T7); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - RunTask2(task2).Forget(); - RunTask3(task3).Forget(); - RunTask4(task4).Forget(); - RunTask5(task5).Forget(); - RunTask6(task6).Forget(); - RunTask7(task7).Forget(); - } + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } - } - - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - T1 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result1 = value; - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask2(UniTask task) - { - T2 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result2 = value; - Volatile.Write(ref winArgumentIndex, 2); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask3(UniTask task) - { - T3 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result3 = value; - Volatile.Write(ref winArgumentIndex, 3); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask4(UniTask task) - { - T4 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result4 = value; - Volatile.Write(ref winArgumentIndex, 4); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask5(UniTask task) - { - T5 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result5 = value; - Volatile.Write(ref winArgumentIndex, 5); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask6(UniTask task) - { - T6 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result6 = value; - Volatile.Write(ref winArgumentIndex, 6); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask7(UniTask task) - { - T7 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result7 = value; - Volatile.Write(ref winArgumentIndex, 7); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - WhenAnyPromise parent; - - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + if (awaiter.IsCompleted) { - return parent.IsCompleted; + TryInvokeContinuationT1(this, awaiter); } - } - - public (int, (bool, T0), (bool, T1), (bool, T2), (bool, T3), (bool, T4), (bool, T5), (bool, T6), (bool, T7)) GetResult() - { - if (parent.exception != null) + else { - parent.exception.Throw(); - } - - var i = parent.winArgumentIndex; - return (i, (i == 0, parent.result0), (i == 1, parent.result1), (i == 2, parent.result2), (i == 3, parent.result3), (i == 4, parent.result4), (i == 5, parent.result5), (i == 6, parent.result6), (i == 7, parent.result7)); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT13(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T13 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((12, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT13(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T13 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((12, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT14(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T14 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((13, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + + public static UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14), (bool hasResult, T15 result15))> WhenAny(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + return new UniTask<(int winArgumentIndex, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14), (bool hasResult, T15 result15))>(new WhenAnyPromise(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10, task11, task12, task13, task14, task15), 0); + } + + sealed class WhenAnyPromise : IUniTaskSource<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14), (bool hasResult, T15 result15))> + { + int completedCount; + UniTaskCompletionSourceCore<(int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14), (bool hasResult, T15 result15))> core; + + public WhenAnyPromise(UniTask task1, UniTask task2, UniTask task3, UniTask task4, UniTask task5, UniTask task6, UniTask task7, UniTask task8, UniTask task9, UniTask task10, UniTask task11, UniTask task12, UniTask task13, UniTask task14, UniTask task15) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; + { + var awaiter = task1.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT1(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT1(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task2.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT2(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT2(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task3.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT3(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT3(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task4.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT4(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT4(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task5.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT5(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT5(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task6.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT6(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT6(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task7.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT7(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT7(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task8.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT8(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT8(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task9.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT9(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT9(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task10.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT10(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT10(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task11.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT11(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT11(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task12.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT12(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT12(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task13.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT13(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT13(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task14.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT14(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT14(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + { + var awaiter = task15.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT15(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryInvokeContinuationT15(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryInvokeContinuationT1(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T1 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((0, (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT2(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T2 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((1, (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT3(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T3 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((2, (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT4(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T4 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((3, (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT5(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T5 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((4, (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT6(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T6 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((5, (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT7(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T7 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((6, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT8(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T8 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((7, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT9(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T9 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((8, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT10(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T10 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((9, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT11(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T11 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((10, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT12(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T12 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((11, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT13(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T13 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((12, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default), (false, default))); + } + } + + static void TryInvokeContinuationT14(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T14 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((13, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result), (false, default))); + } + } + + static void TryInvokeContinuationT15(WhenAnyPromise self, in UniTask.Awaiter awaiter) + { + T15 result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((14, (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (false, default), (true, result))); + } + } + + + public (int, (bool hasResult, T1 result1), (bool hasResult, T2 result2), (bool hasResult, T3 result3), (bool hasResult, T4 result4), (bool hasResult, T5 result5), (bool hasResult, T6 result6), (bool hasResult, T7 result7), (bool hasResult, T8 result8), (bool hasResult, T9 result9), (bool hasResult, T10 result10), (bool hasResult, T11 result11), (bool hasResult, T12 result12), (bool hasResult, T13 result13), (bool hasResult, T14 result14), (bool hasResult, T15 result15)) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); } } } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs.meta b/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs.meta deleted file mode 100644 index 49a2c3f..0000000 --- a/Assets/UniRx.Async/UniTask.WhenAny.Generated.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 13d604ac281570c4eac9962429f19ca9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniRx.Async/UniTask.WhenAny.Generated.tt b/Assets/UniRx.Async/UniTask.WhenAny.Generated.tt new file mode 100644 index 0000000..3d50260 --- /dev/null +++ b/Assets/UniRx.Async/UniTask.WhenAny.Generated.tt @@ -0,0 +1,122 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using System; +using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; +using System.Threading; +using UniRx.Async.Internal; + +namespace UniRx.Async +{ + public partial struct UniTask + { +<# for(var i = 2; i <= 15; i++ ) { + var range = Enumerable.Range(1, i); + var t = string.Join(", ", range.Select(x => "T" + x)); + var args = string.Join(", ", range.Select(x => $"UniTask task{x}")); + var targs = string.Join(", ", range.Select(x => $"task{x}")); + var tresult = string.Join(", ", range.Select(x => $"task{x}.GetAwaiter().GetResult()")); + var tBool = string.Join(", ", range.Select(x => $"(bool hasResult, T{x} result{x})")); + var tfield = string.Join(", ", range.Select(x => $"self.t{x}")); + Func getResult = j => string.Join(", ", range.Select(x => (x == j) ? "(true, result)" : "(false, default)")); +#> + public static UniTask<(int winArgumentIndex, <#= tBool #>)> WhenAny<<#= t #>>(<#= args #>) + { + return new UniTask<(int winArgumentIndex, <#= tBool #>)>(new WhenAnyPromise<<#= t #>>(<#= targs #>), 0); + } + + sealed class WhenAnyPromise<<#= t #>> : IUniTaskSource<(int, <#= tBool #>)> + { + int completedCount; + UniTaskCompletionSourceCore<(int, <#= tBool #>)> core; + + public WhenAnyPromise(<#= args #>) + { + TaskTracker2.TrackActiveTask(this, 3); + + this.completedCount = 0; +<# for(var j = 1; j <= i; j++) { #> + { + var awaiter = task<#= j #>.GetAwaiter(); + + if (awaiter.IsCompleted) + { + TryInvokeContinuationT<#= j #>(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple>, UniTask>.Awaiter>)state) + { + TryInvokeContinuationT<#= j #>(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } +<# } #> + } + +<# for(var j = 1; j <= i; j++) { #> + static void TryInvokeContinuationT<#= j #>(WhenAnyPromise<<#= t #>> self, in UniTask>.Awaiter awaiter) + { + T<#= j #> result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((<#= j - 1 #>, <#= getResult(j) #>)); + } + } + +<# } #> + + public (int, <#= tBool #>) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyPromise() + { + core.Reset(); + } + } + +<# } #> + } +} \ No newline at end of file diff --git a/Assets/UniRx.Async/UniTask.WhenAny.cs b/Assets/UniRx.Async/UniTask.WhenAny.cs index 2c5049b..3bfe25c 100644 --- a/Assets/UniRx.Async/UniTask.WhenAny.cs +++ b/Assets/UniRx.Async/UniTask.WhenAny.cs @@ -2,370 +2,365 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; -using System.Runtime.CompilerServices; -using System.Runtime.ExceptionServices; +using System.Collections.Generic; using System.Threading; +using UniRx.Async.Internal; namespace UniRx.Async { public partial struct UniTask { - // UniTask - - public static async UniTask<(bool hasResultLeft, T0 result)> WhenAny(UniTask task0, UniTask task1) + public static UniTask<(bool hasResultLeft, T result)> WhenAny(UniTask leftTask, UniTask rightTask) { - return await new UnitWhenAnyPromise(task0, task1); + return new UniTask<(bool, T)>(new WhenAnyLRPromise(leftTask, rightTask), 0); } - public static async UniTask<(int winArgumentIndex, T result)> WhenAny(params UniTask[] tasks) + public static UniTask<(int winArgumentIndex, T result)> WhenAny(params UniTask[] tasks) { - return await new WhenAnyPromise(tasks); + return new UniTask<(int, T)>(new WhenAnyPromise(tasks, tasks.Length), 0); + } + + public static UniTask<(int winArgumentIndex, T result)> WhenAny(IEnumerable> tasks) + { + using (var span = ArrayPoolUtil.Materialize(tasks)) + { + return new UniTask<(int, T)>(new WhenAnyPromise(span.Array, span.Length), 0); + } } /// Return value is winArgumentIndex - public static async UniTask WhenAny(params UniTask[] tasks) + public static UniTask WhenAny(params UniTask[] tasks) { - return await new WhenAnyPromise(tasks); + return new UniTask(new WhenAnyPromise(tasks, tasks.Length), 0); } - class UnitWhenAnyPromise + /// Return value is winArgumentIndex + public static UniTask WhenAny(IEnumerable tasks) { - T0 result0; - ExceptionDispatchInfo exception; - Action whenComplete; - int completeCount; + using (var span = ArrayPoolUtil.Materialize(tasks)) + { + return new UniTask(new WhenAnyPromise(span.Array, span.Length), 0); + } + } + + sealed class WhenAnyLRPromise : IUniTaskSource<(bool, T)> + { + int completedCount; int winArgumentIndex; + UniTaskCompletionSourceCore<(bool, T)> core; - bool IsCompleted => exception != null || Volatile.Read(ref winArgumentIndex) != -1; - - public UnitWhenAnyPromise(UniTask task0, UniTask task1) + public WhenAnyLRPromise(UniTask leftTask, UniTask rightTask) { - this.whenComplete = null; - this.exception = null; - this.completeCount = 0; - this.winArgumentIndex = -1; - this.result0 = default(T0); + TaskTracker2.TrackActiveTask(this, 3); - RunTask0(task0).Forget(); - RunTask1(task1).Forget(); - } - - void TryCallContinuation() - { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) { - action.Invoke(); - } - } - - async UniTaskVoid RunTask0(UniTask task) - { - T0 value; - try - { - value = await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - result0 = value; - Volatile.Write(ref winArgumentIndex, 0); - TryCallContinuation(); - } - } - - async UniTaskVoid RunTask1(UniTask task) - { - try - { - await task; - } - catch (Exception ex) - { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); - return; - } - - var count = Interlocked.Increment(ref completeCount); - if (count == 1) - { - Volatile.Write(ref winArgumentIndex, 1); - TryCallContinuation(); - } - } - - - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - public struct Awaiter : ICriticalNotifyCompletion - { - UnitWhenAnyPromise parent; - - public Awaiter(UnitWhenAnyPromise parent) - { - this.parent = parent; - } - - public bool IsCompleted - { - get + UniTask.Awaiter awaiter; + try { - return parent.IsCompleted; + awaiter = leftTask.GetAwaiter(); } - } - - public (bool, T0) GetResult() - { - if (parent.exception != null) + catch (Exception ex) { - parent.exception.Throw(); + core.TrySetException(ex); + goto RIGHT; } - return (parent.winArgumentIndex == 0, parent.result0); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) + if (awaiter.IsCompleted) { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) + TryLeftInvokeContinuation(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => { - action(); - } + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryLeftInvokeContinuation(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); } } + RIGHT: + { + UniTask.Awaiter awaiter; + try + { + awaiter = rightTask.GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + return; + } + + if (awaiter.IsCompleted) + { + TryRightInvokeContinuation(this, awaiter); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter>)state) + { + TryRightInvokeContinuation(t.Item1, t.Item2); + } + }, StateTuple.Create(this, awaiter)); + } + } + } + + static void TryLeftInvokeContinuation(WhenAnyLRPromise self, in UniTask.Awaiter awaiter) + { + T result; + try + { + result = awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((true, result)); + } + } + + static void TryRightInvokeContinuation(WhenAnyLRPromise self, in UniTask.Awaiter awaiter) + { + try + { + awaiter.GetResult(); + } + catch (Exception ex) + { + self.core.TrySetException(ex); + return; + } + + if (Interlocked.Increment(ref self.completedCount) == 1) + { + self.core.TrySetResult((false, default)); + } + } + + public (bool, T) GetResult(short token) + { + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); + } + + public UniTaskStatus GetStatus(short token) + { + return core.GetStatus(token); + } + + public void OnCompleted(Action continuation, object state, short token) + { + core.OnCompleted(continuation, state, token); + } + + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } + + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } + + ~WhenAnyLRPromise() + { + core.Reset(); } } - class WhenAnyPromise + sealed class WhenAnyPromise : IUniTaskSource<(int, T)> { - T result; - int completeCount; + int completedCount; int winArgumentIndex; - Action whenComplete; - ExceptionDispatchInfo exception; + UniTaskCompletionSourceCore<(int, T)> core; - public bool IsComplete => exception != null || Volatile.Read(ref winArgumentIndex) != -1; - - public WhenAnyPromise(UniTask[] tasks) + public WhenAnyPromise(UniTask[] tasks, int tasksLength) { - this.completeCount = 0; - this.winArgumentIndex = -1; - this.whenComplete = null; - this.exception = null; - this.result = default(T); + TaskTracker2.TrackActiveTask(this, 3); - for (int i = 0; i < tasks.Length; i++) + for (int i = 0; i < tasksLength; i++) { - RunTask(tasks[i], i).Forget(); + UniTask.Awaiter awaiter; + try + { + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; // consume others. + } + + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter, i); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple, UniTask.Awaiter, int>)state) + { + TryInvokeContinuation(t.Item1, t.Item2, t.Item3); + } + }, StateTuple.Create(this, awaiter, i)); + } } } - async UniTaskVoid RunTask(UniTask task, int index) + static void TryInvokeContinuation(WhenAnyPromise self, in UniTask.Awaiter awaiter, int i) { - T value; + T result; try { - value = await task; + result = awaiter.GetResult(); } catch (Exception ex) { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); + self.core.TrySetException(ex); return; } - var count = Interlocked.Increment(ref completeCount); - if (count == 1) + if (Interlocked.Increment(ref self.completedCount) == 1) { - result = value; - Volatile.Write(ref winArgumentIndex, index); - TryCallContinuation(); + self.core.TrySetResult((i, result)); } } - void TryCallContinuation() + public (int, T) GetResult(short token) { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); } - public Awaiter GetAwaiter() + public UniTaskStatus GetStatus(short token) { - return new Awaiter(this); + return core.GetStatus(token); } - public struct Awaiter : ICriticalNotifyCompletion + public void OnCompleted(Action continuation, object state, short token) { - WhenAnyPromise parent; + core.OnCompleted(continuation, state, token); + } - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } - public bool IsCompleted - { - get - { - return parent.IsComplete; - } - } + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } - public (int, T) GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return (parent.winArgumentIndex, parent.result); - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) - { - action(); - } - } - } + ~WhenAnyPromise() + { + core.Reset(); } } - class WhenAnyPromise + sealed class WhenAnyPromise : IUniTaskSource { - int completeCount; + int completedCount; int winArgumentIndex; - Action whenComplete; - ExceptionDispatchInfo exception; + UniTaskCompletionSourceCore core; - public bool IsComplete => exception != null || Volatile.Read(ref winArgumentIndex) != -1; - - public WhenAnyPromise(UniTask[] tasks) + public WhenAnyPromise(UniTask[] tasks, int tasksLength) { - this.completeCount = 0; - this.winArgumentIndex = -1; - this.whenComplete = null; - this.exception = null; + TaskTracker2.TrackActiveTask(this, 3); - for (int i = 0; i < tasks.Length; i++) + for (int i = 0; i < tasksLength; i++) { - RunTask(tasks[i], i).Forget(); + UniTask.Awaiter awaiter; + try + { + awaiter = tasks[i].GetAwaiter(); + } + catch (Exception ex) + { + core.TrySetException(ex); + continue; // consume others. + } + + if (awaiter.IsCompleted) + { + TryInvokeContinuation(this, awaiter, i); + } + else + { + awaiter.SourceOnCompleted(state => + { + using (var t = (StateTuple)state) + { + TryInvokeContinuation(t.Item1, t.Item2, t.Item3); + } + }, StateTuple.Create(this, awaiter, i)); + } } } - async UniTaskVoid RunTask(UniTask task, int index) + static void TryInvokeContinuation(WhenAnyPromise self, in UniTask.Awaiter awaiter, int i) { try { - await task; + awaiter.GetResult(); } catch (Exception ex) { - exception = ExceptionDispatchInfo.Capture(ex); - TryCallContinuation(); + self.core.TrySetException(ex); return; } - var count = Interlocked.Increment(ref completeCount); - if (count == 1) + if (Interlocked.Increment(ref self.completedCount) == 1) { - Volatile.Write(ref winArgumentIndex, index); - TryCallContinuation(); + self.core.TrySetResult(i); } } - void TryCallContinuation() + public int GetResult(short token) { - var action = Interlocked.Exchange(ref whenComplete, null); - if (action != null) - { - action.Invoke(); - } + TaskTracker2.RemoveTracking(this); + GC.SuppressFinalize(this); + return core.GetResult(token); } - public Awaiter GetAwaiter() + public UniTaskStatus GetStatus(short token) { - return new Awaiter(this); + return core.GetStatus(token); } - public struct Awaiter : ICriticalNotifyCompletion + public void OnCompleted(Action continuation, object state, short token) { - WhenAnyPromise parent; + core.OnCompleted(continuation, state, token); + } - public Awaiter(WhenAnyPromise parent) - { - this.parent = parent; - } + public UniTaskStatus UnsafeGetStatus() + { + return core.UnsafeGetStatus(); + } - public bool IsCompleted - { - get - { - return parent.IsComplete; - } - } + void IUniTaskSource.GetResult(short token) + { + GetResult(token); + } - public int GetResult() - { - if (parent.exception != null) - { - parent.exception.Throw(); - } - - return parent.winArgumentIndex; - } - - public void OnCompleted(Action continuation) - { - UnsafeOnCompleted(continuation); - } - - public void UnsafeOnCompleted(Action continuation) - { - parent.whenComplete = continuation; - if (IsCompleted) - { - var action = Interlocked.Exchange(ref parent.whenComplete, null); - if (action != null) - { - action(); - } - } - } + ~WhenAnyPromise() + { + core.Reset(); } } } diff --git a/Assets/UniRx.Async/UniTaskCompletionSource.cs b/Assets/UniRx.Async/UniTaskCompletionSource.cs index 0ef9906..89d700d 100644 --- a/Assets/UniRx.Async/UniTaskCompletionSource.cs +++ b/Assets/UniRx.Async/UniTaskCompletionSource.cs @@ -47,9 +47,8 @@ namespace UniRx.Async TResult result; object error; // ExceptionDispatchInfo or OperationCanceledException short version; - bool completed; bool hasUnhandledError; - + int completedCount; // 0: completed == false Action continuation; object continuationState; @@ -61,7 +60,7 @@ namespace UniRx.Async { version += 1; // incr version. } - completed = false; + completedCount = 0; result = default; error = null; hasUnhandledError = false; @@ -92,25 +91,59 @@ namespace UniRx.Async /// Completes with a successful result. /// The result. - public void SetResult(TResult result) + public bool TrySetResult(TResult result) { - this.result = result; - SignalCompletion(); + if (Interlocked.Increment(ref completedCount) == 1) + { + // setup result + this.result = result; + + if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) + { + continuation(continuationState); + return true; + } + } + + return false; } /// Completes with an error. /// The exception. - public void SetException(Exception error) + public bool TrySetException(Exception error) { - this.hasUnhandledError = true; - this.error = ExceptionDispatchInfo.Capture(error); - SignalCompletion(); + if (Interlocked.Increment(ref completedCount) == 1) + { + // setup result + this.hasUnhandledError = true; + this.error = ExceptionDispatchInfo.Capture(error); + + if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) + { + continuation(continuationState); + return true; + } + } + + return false; } - public void SetCanceled(CancellationToken cancellationToken = default) + public bool TrySetCanceled(CancellationToken cancellationToken = default) { - this.error = new OperationCanceledException(cancellationToken); - SignalCompletion(); + if (Interlocked.Increment(ref completedCount) == 1) + { + // setup result + this.hasUnhandledError = true; + this.error = new OperationCanceledException(cancellationToken); + + if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) + { + continuation(continuationState); + return true; + } + } + + return false; } /// Gets the operation version. @@ -122,7 +155,7 @@ namespace UniRx.Async public UniTaskStatus GetStatus(short token) { ValidateToken(token); - return (continuation == null || !completed) ? UniTaskStatus.Pending + return (continuation == null || (completedCount == 0)) ? UniTaskStatus.Pending : (error == null) ? UniTaskStatus.Succeeded : (error is OperationCanceledException) ? UniTaskStatus.Canceled : UniTaskStatus.Faulted; @@ -132,7 +165,7 @@ namespace UniRx.Async [MethodImpl(MethodImplOptions.AggressiveInlining)] public UniTaskStatus UnsafeGetStatus() { - return (continuation == null || !completed) ? UniTaskStatus.Pending + return (continuation == null || (completedCount == 0)) ? UniTaskStatus.Pending : (error == null) ? UniTaskStatus.Succeeded : (error is OperationCanceledException) ? UniTaskStatus.Canceled : UniTaskStatus.Faulted; @@ -145,7 +178,7 @@ namespace UniRx.Async public TResult GetResult(short token) { ValidateToken(token); - if (!completed) + if (!(completedCount == 0)) { throw new InvalidOperationException("not yet completed."); } @@ -183,6 +216,15 @@ namespace UniRx.Async /* no use ValueTaskSourceOnCOmpletedFlags, always no capture ExecutionContext and SynchronizationContext. */ + /* + PatternA: GetStatus=Pending => OnCompleted => TrySet*** => GetResult + PatternB: TrySet*** => GetStatus=!Pending => GetResult + PatternC: GetStatus=Pending => TrySet/OnCompleted(race condition) => GetResult + C.1: win OnCompleted -> TrySet invoke saved continuation + C.2: win TrySet -> should invoke continuation here. + */ + + // not set continuation yet. object oldContinuation = this.continuation; if (oldContinuation == null) { @@ -192,10 +234,11 @@ namespace UniRx.Async if (oldContinuation != null) { - // Operation already completed, so we need to queue the supplied callback. + // already running continuation in TrySet. + // It will cause call OnCompleted multiple time, invalid. if (!ReferenceEquals(oldContinuation, UniTaskCompletionSourceCoreShared.s_sentinel)) { - throw new InvalidOperationException("already completed."); + throw new InvalidOperationException(); } continuation(state); @@ -210,23 +253,6 @@ namespace UniRx.Async throw new InvalidOperationException("token version is not matched."); } } - - /// Signals that the operation has completed. Invoked after the result or error has been set. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SignalCompletion() - { - if (completed) - { - throw new InvalidOperationException(); - } - - completed = true; - - if (continuation != null || Interlocked.CompareExchange(ref this.continuation, UniTaskCompletionSourceCoreShared.s_sentinel, null) != null) - { - continuation(continuationState); - } - } } internal static class UniTaskCompletionSourceCoreShared // separated out of generic to avoid unnecessary duplication @@ -277,17 +303,17 @@ namespace UniRx.Async public void SetResult() { - core.SetResult(AsyncUnit.Default); + core.TrySetResult(AsyncUnit.Default); } public void SetCanceled(CancellationToken cancellationToken = default) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); } public void SetException(Exception exception) { - core.SetException(exception); + core.TrySetException(exception); } public void GetResult(short token) @@ -369,17 +395,17 @@ namespace UniRx.Async public void SetResult() { - core.SetResult(AsyncUnit.Default); + core.TrySetResult(AsyncUnit.Default); } public void SetCanceled(CancellationToken cancellationToken = default) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); } public void SetException(Exception exception) { - core.SetException(exception); + core.TrySetException(exception); } public void GetResult(short token) @@ -463,17 +489,17 @@ namespace UniRx.Async public void SetResult(T result) { - core.SetResult(result); + core.TrySetResult(result); } public void SetCanceled(CancellationToken cancellationToken = default) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); } public void SetException(Exception exception) { - core.SetException(exception); + core.TrySetException(exception); } public T GetResult(short token) @@ -560,17 +586,17 @@ namespace UniRx.Async public void SetResult(T result) { - core.SetResult(result); + core.TrySetResult(result); } public void SetCanceled(CancellationToken cancellationToken = default) { - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); } public void SetException(Exception exception) { - core.SetException(exception); + core.TrySetException(exception); } public T GetResult(short token) @@ -616,7 +642,6 @@ namespace UniRx.Async if (pool.TryReturn(this)) { GC.ReRegisterForFinalize(this); - return; } } } diff --git a/Assets/UniRx.Async/UniTaskExtensions.cs b/Assets/UniRx.Async/UniTaskExtensions.cs index d643bc3..6115478 100644 --- a/Assets/UniRx.Async/UniTaskExtensions.cs +++ b/Assets/UniRx.Async/UniTaskExtensions.cs @@ -76,7 +76,16 @@ namespace UniRx.Async { try { - var awaiter = task.GetAwaiter(); + UniTask.Awaiter awaiter; + try + { + awaiter = task.GetAwaiter(); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + if (awaiter.IsCompleted) { try @@ -121,7 +130,16 @@ namespace UniRx.Async { try { - var awaiter = task.GetAwaiter(); + UniTask.Awaiter awaiter; + try + { + awaiter = task.GetAwaiter(); + } + catch (Exception ex) + { + return Task.FromException(ex); + } + if (awaiter.IsCompleted) { try diff --git a/Assets/UniRx.Async/UnityAsyncExtensions.cs b/Assets/UniRx.Async/UnityAsyncExtensions.cs index 9bf78bb..cec9a2f 100644 --- a/Assets/UniRx.Async/UnityAsyncExtensions.cs +++ b/Assets/UniRx.Async/UnityAsyncExtensions.cs @@ -573,7 +573,7 @@ namespace UniRx.Async { // TODO:Remove Tracking // TaskTracker.RemoveTracking(); - core.SetCanceled(cancellationToken); + core.TrySetCanceled(cancellationToken); return false; } @@ -586,7 +586,7 @@ namespace UniRx.Async { // TODO:Remove Tracking // TaskTracker.RemoveTracking(); - core.SetResult(asyncOperation.asset); + core.TrySetResult(asyncOperation.asset); return false; }