You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CrowdControl/Assets/Plugins/UniTask/Runtime/Linq/CombineLatest.cs

11372 lines
431 KiB
C#

2 months ago
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, Func<T1, T2, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, TResult>(source1, source2, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, Func<T1, T2, T3, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, TResult>(source1, source2, source3, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, TResult>(source1, source2, source3, source4, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, TResult>(source1, source2, source3, source4, source5, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, TResult>(source1, source2, source3, source4, source5, source6, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult>(source1, source2, source3, source4, source5, source6, source7, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(source10, nameof(source10));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(source10, nameof(source10));
Error.ThrowArgumentNullException(source11, nameof(source11));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(source10, nameof(source10));
Error.ThrowArgumentNullException(source11, nameof(source11));
Error.ThrowArgumentNullException(source12, nameof(source12));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(source10, nameof(source10));
Error.ThrowArgumentNullException(source11, nameof(source11));
Error.ThrowArgumentNullException(source12, nameof(source12));
Error.ThrowArgumentNullException(source13, nameof(source13));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, IUniTaskAsyncEnumerable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(source10, nameof(source10));
Error.ThrowArgumentNullException(source11, nameof(source11));
Error.ThrowArgumentNullException(source12, nameof(source12));
Error.ThrowArgumentNullException(source13, nameof(source13));
Error.ThrowArgumentNullException(source14, nameof(source14));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector);
}
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(this IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, IUniTaskAsyncEnumerable<T14> source14, IUniTaskAsyncEnumerable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector)
{
Error.ThrowArgumentNullException(source1, nameof(source1));
Error.ThrowArgumentNullException(source2, nameof(source2));
Error.ThrowArgumentNullException(source3, nameof(source3));
Error.ThrowArgumentNullException(source4, nameof(source4));
Error.ThrowArgumentNullException(source5, nameof(source5));
Error.ThrowArgumentNullException(source6, nameof(source6));
Error.ThrowArgumentNullException(source7, nameof(source7));
Error.ThrowArgumentNullException(source8, nameof(source8));
Error.ThrowArgumentNullException(source9, nameof(source9));
Error.ThrowArgumentNullException(source10, nameof(source10));
Error.ThrowArgumentNullException(source11, nameof(source11));
Error.ThrowArgumentNullException(source12, nameof(source12));
Error.ThrowArgumentNullException(source13, nameof(source13));
Error.ThrowArgumentNullException(source14, nameof(source14));
Error.ThrowArgumentNullException(source15, nameof(source15));
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
return new CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector);
}
}
internal class CombineLatest<T1, T2, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly Func<T1, T2, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, Func<T1, T2, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
const int CompleteCount = 2;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly Func<T1, T2, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, Func<T1, T2, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running1 || !running2)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2)
{
result = resultSelector(current1, current2);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly Func<T1, T2, T3, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, Func<T1, T2, T3, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
const int CompleteCount = 3;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly Func<T1, T2, T3, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, Func<T1, T2, T3, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running1 || !running2 || !running3)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3)
{
result = resultSelector(current1, current2, current3);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly Func<T1, T2, T3, T4, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
const int CompleteCount = 4;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly Func<T1, T2, T3, T4, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, Func<T1, T2, T3, T4, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4)
{
result = resultSelector(current1, current2, current3, current4);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly Func<T1, T2, T3, T4, T5, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
const int CompleteCount = 5;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly Func<T1, T2, T3, T4, T5, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, Func<T1, T2, T3, T4, T5, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5)
{
result = resultSelector(current1, current2, current3, current4, current5);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
const int CompleteCount = 6;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, Func<T1, T2, T3, T4, T5, T6, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6)
{
result = resultSelector(current1, current2, current3, current4, current5, current6);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
const int CompleteCount = 7;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, Func<T1, T2, T3, T4, T5, T6, T7, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
const int CompleteCount = 8;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
const int CompleteCount = 9;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
static readonly Action<object> Completed10Delegate = Completed10;
const int CompleteCount = 10;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
IUniTaskAsyncEnumerator<T10> enumerator10;
UniTask<bool>.Awaiter awaiter10;
bool hasCurrent10;
bool running10;
T10 current10;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
enumerator10 = source10.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running10)
{
running10 = true;
awaiter10 = enumerator10.MoveNextAsync().GetAwaiter();
if (awaiter10.IsCompleted)
{
Completed10(this);
}
else
{
awaiter10.SourceOnCompleted(Completed10Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed10(object state)
{
var self = (_CombineLatest)state;
self.running10 = false;
try
{
if (self.awaiter10.GetResult())
{
self.hasCurrent10 = true;
self.current10 = self.enumerator10.Current;
goto SUCCESS;
}
else
{
self.running10 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running10 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running10 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter10.SourceOnCompleted(Completed10Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
if (enumerator10 != null)
{
await enumerator10.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
static readonly Action<object> Completed10Delegate = Completed10;
static readonly Action<object> Completed11Delegate = Completed11;
const int CompleteCount = 11;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
IUniTaskAsyncEnumerator<T10> enumerator10;
UniTask<bool>.Awaiter awaiter10;
bool hasCurrent10;
bool running10;
T10 current10;
IUniTaskAsyncEnumerator<T11> enumerator11;
UniTask<bool>.Awaiter awaiter11;
bool hasCurrent11;
bool running11;
T11 current11;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
enumerator10 = source10.GetAsyncEnumerator(cancellationToken);
enumerator11 = source11.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running10)
{
running10 = true;
awaiter10 = enumerator10.MoveNextAsync().GetAwaiter();
if (awaiter10.IsCompleted)
{
Completed10(this);
}
else
{
awaiter10.SourceOnCompleted(Completed10Delegate, this);
}
}
if (!running11)
{
running11 = true;
awaiter11 = enumerator11.MoveNextAsync().GetAwaiter();
if (awaiter11.IsCompleted)
{
Completed11(this);
}
else
{
awaiter11.SourceOnCompleted(Completed11Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed10(object state)
{
var self = (_CombineLatest)state;
self.running10 = false;
try
{
if (self.awaiter10.GetResult())
{
self.hasCurrent10 = true;
self.current10 = self.enumerator10.Current;
goto SUCCESS;
}
else
{
self.running10 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running10 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running10 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter10.SourceOnCompleted(Completed10Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed11(object state)
{
var self = (_CombineLatest)state;
self.running11 = false;
try
{
if (self.awaiter11.GetResult())
{
self.hasCurrent11 = true;
self.current11 = self.enumerator11.Current;
goto SUCCESS;
}
else
{
self.running11 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running11 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running11 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter11.SourceOnCompleted(Completed11Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
if (enumerator10 != null)
{
await enumerator10.DisposeAsync();
}
if (enumerator11 != null)
{
await enumerator11.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
static readonly Action<object> Completed10Delegate = Completed10;
static readonly Action<object> Completed11Delegate = Completed11;
static readonly Action<object> Completed12Delegate = Completed12;
const int CompleteCount = 12;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
IUniTaskAsyncEnumerator<T10> enumerator10;
UniTask<bool>.Awaiter awaiter10;
bool hasCurrent10;
bool running10;
T10 current10;
IUniTaskAsyncEnumerator<T11> enumerator11;
UniTask<bool>.Awaiter awaiter11;
bool hasCurrent11;
bool running11;
T11 current11;
IUniTaskAsyncEnumerator<T12> enumerator12;
UniTask<bool>.Awaiter awaiter12;
bool hasCurrent12;
bool running12;
T12 current12;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
enumerator10 = source10.GetAsyncEnumerator(cancellationToken);
enumerator11 = source11.GetAsyncEnumerator(cancellationToken);
enumerator12 = source12.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running10)
{
running10 = true;
awaiter10 = enumerator10.MoveNextAsync().GetAwaiter();
if (awaiter10.IsCompleted)
{
Completed10(this);
}
else
{
awaiter10.SourceOnCompleted(Completed10Delegate, this);
}
}
if (!running11)
{
running11 = true;
awaiter11 = enumerator11.MoveNextAsync().GetAwaiter();
if (awaiter11.IsCompleted)
{
Completed11(this);
}
else
{
awaiter11.SourceOnCompleted(Completed11Delegate, this);
}
}
if (!running12)
{
running12 = true;
awaiter12 = enumerator12.MoveNextAsync().GetAwaiter();
if (awaiter12.IsCompleted)
{
Completed12(this);
}
else
{
awaiter12.SourceOnCompleted(Completed12Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed10(object state)
{
var self = (_CombineLatest)state;
self.running10 = false;
try
{
if (self.awaiter10.GetResult())
{
self.hasCurrent10 = true;
self.current10 = self.enumerator10.Current;
goto SUCCESS;
}
else
{
self.running10 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running10 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running10 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter10.SourceOnCompleted(Completed10Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed11(object state)
{
var self = (_CombineLatest)state;
self.running11 = false;
try
{
if (self.awaiter11.GetResult())
{
self.hasCurrent11 = true;
self.current11 = self.enumerator11.Current;
goto SUCCESS;
}
else
{
self.running11 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running11 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running11 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter11.SourceOnCompleted(Completed11Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed12(object state)
{
var self = (_CombineLatest)state;
self.running12 = false;
try
{
if (self.awaiter12.GetResult())
{
self.hasCurrent12 = true;
self.current12 = self.enumerator12.Current;
goto SUCCESS;
}
else
{
self.running12 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running12 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running12 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter12.SourceOnCompleted(Completed12Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
if (enumerator10 != null)
{
await enumerator10.DisposeAsync();
}
if (enumerator11 != null)
{
await enumerator11.DisposeAsync();
}
if (enumerator12 != null)
{
await enumerator12.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly IUniTaskAsyncEnumerable<T13> source13;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.source13 = source13;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
static readonly Action<object> Completed10Delegate = Completed10;
static readonly Action<object> Completed11Delegate = Completed11;
static readonly Action<object> Completed12Delegate = Completed12;
static readonly Action<object> Completed13Delegate = Completed13;
const int CompleteCount = 13;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly IUniTaskAsyncEnumerable<T13> source13;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
IUniTaskAsyncEnumerator<T10> enumerator10;
UniTask<bool>.Awaiter awaiter10;
bool hasCurrent10;
bool running10;
T10 current10;
IUniTaskAsyncEnumerator<T11> enumerator11;
UniTask<bool>.Awaiter awaiter11;
bool hasCurrent11;
bool running11;
T11 current11;
IUniTaskAsyncEnumerator<T12> enumerator12;
UniTask<bool>.Awaiter awaiter12;
bool hasCurrent12;
bool running12;
T12 current12;
IUniTaskAsyncEnumerator<T13> enumerator13;
UniTask<bool>.Awaiter awaiter13;
bool hasCurrent13;
bool running13;
T13 current13;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.source13 = source13;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
enumerator10 = source10.GetAsyncEnumerator(cancellationToken);
enumerator11 = source11.GetAsyncEnumerator(cancellationToken);
enumerator12 = source12.GetAsyncEnumerator(cancellationToken);
enumerator13 = source13.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running10)
{
running10 = true;
awaiter10 = enumerator10.MoveNextAsync().GetAwaiter();
if (awaiter10.IsCompleted)
{
Completed10(this);
}
else
{
awaiter10.SourceOnCompleted(Completed10Delegate, this);
}
}
if (!running11)
{
running11 = true;
awaiter11 = enumerator11.MoveNextAsync().GetAwaiter();
if (awaiter11.IsCompleted)
{
Completed11(this);
}
else
{
awaiter11.SourceOnCompleted(Completed11Delegate, this);
}
}
if (!running12)
{
running12 = true;
awaiter12 = enumerator12.MoveNextAsync().GetAwaiter();
if (awaiter12.IsCompleted)
{
Completed12(this);
}
else
{
awaiter12.SourceOnCompleted(Completed12Delegate, this);
}
}
if (!running13)
{
running13 = true;
awaiter13 = enumerator13.MoveNextAsync().GetAwaiter();
if (awaiter13.IsCompleted)
{
Completed13(this);
}
else
{
awaiter13.SourceOnCompleted(Completed13Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12 || !running13)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed10(object state)
{
var self = (_CombineLatest)state;
self.running10 = false;
try
{
if (self.awaiter10.GetResult())
{
self.hasCurrent10 = true;
self.current10 = self.enumerator10.Current;
goto SUCCESS;
}
else
{
self.running10 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running10 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running10 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter10.SourceOnCompleted(Completed10Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed11(object state)
{
var self = (_CombineLatest)state;
self.running11 = false;
try
{
if (self.awaiter11.GetResult())
{
self.hasCurrent11 = true;
self.current11 = self.enumerator11.Current;
goto SUCCESS;
}
else
{
self.running11 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running11 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running11 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter11.SourceOnCompleted(Completed11Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed12(object state)
{
var self = (_CombineLatest)state;
self.running12 = false;
try
{
if (self.awaiter12.GetResult())
{
self.hasCurrent12 = true;
self.current12 = self.enumerator12.Current;
goto SUCCESS;
}
else
{
self.running12 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running12 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running12 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter12.SourceOnCompleted(Completed12Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed13(object state)
{
var self = (_CombineLatest)state;
self.running13 = false;
try
{
if (self.awaiter13.GetResult())
{
self.hasCurrent13 = true;
self.current13 = self.enumerator13.Current;
goto SUCCESS;
}
else
{
self.running13 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running13 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running13 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter13 = self.enumerator13.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter13.SourceOnCompleted(Completed13Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12 && hasCurrent13)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12, current13);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
if (enumerator10 != null)
{
await enumerator10.DisposeAsync();
}
if (enumerator11 != null)
{
await enumerator11.DisposeAsync();
}
if (enumerator12 != null)
{
await enumerator12.DisposeAsync();
}
if (enumerator13 != null)
{
await enumerator13.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly IUniTaskAsyncEnumerable<T13> source13;
readonly IUniTaskAsyncEnumerable<T14> source14;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, IUniTaskAsyncEnumerable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.source13 = source13;
this.source14 = source14;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
static readonly Action<object> Completed10Delegate = Completed10;
static readonly Action<object> Completed11Delegate = Completed11;
static readonly Action<object> Completed12Delegate = Completed12;
static readonly Action<object> Completed13Delegate = Completed13;
static readonly Action<object> Completed14Delegate = Completed14;
const int CompleteCount = 14;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly IUniTaskAsyncEnumerable<T13> source13;
readonly IUniTaskAsyncEnumerable<T14> source14;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
IUniTaskAsyncEnumerator<T10> enumerator10;
UniTask<bool>.Awaiter awaiter10;
bool hasCurrent10;
bool running10;
T10 current10;
IUniTaskAsyncEnumerator<T11> enumerator11;
UniTask<bool>.Awaiter awaiter11;
bool hasCurrent11;
bool running11;
T11 current11;
IUniTaskAsyncEnumerator<T12> enumerator12;
UniTask<bool>.Awaiter awaiter12;
bool hasCurrent12;
bool running12;
T12 current12;
IUniTaskAsyncEnumerator<T13> enumerator13;
UniTask<bool>.Awaiter awaiter13;
bool hasCurrent13;
bool running13;
T13 current13;
IUniTaskAsyncEnumerator<T14> enumerator14;
UniTask<bool>.Awaiter awaiter14;
bool hasCurrent14;
bool running14;
T14 current14;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, IUniTaskAsyncEnumerable<T14> source14, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.source13 = source13;
this.source14 = source14;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
enumerator10 = source10.GetAsyncEnumerator(cancellationToken);
enumerator11 = source11.GetAsyncEnumerator(cancellationToken);
enumerator12 = source12.GetAsyncEnumerator(cancellationToken);
enumerator13 = source13.GetAsyncEnumerator(cancellationToken);
enumerator14 = source14.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running10)
{
running10 = true;
awaiter10 = enumerator10.MoveNextAsync().GetAwaiter();
if (awaiter10.IsCompleted)
{
Completed10(this);
}
else
{
awaiter10.SourceOnCompleted(Completed10Delegate, this);
}
}
if (!running11)
{
running11 = true;
awaiter11 = enumerator11.MoveNextAsync().GetAwaiter();
if (awaiter11.IsCompleted)
{
Completed11(this);
}
else
{
awaiter11.SourceOnCompleted(Completed11Delegate, this);
}
}
if (!running12)
{
running12 = true;
awaiter12 = enumerator12.MoveNextAsync().GetAwaiter();
if (awaiter12.IsCompleted)
{
Completed12(this);
}
else
{
awaiter12.SourceOnCompleted(Completed12Delegate, this);
}
}
if (!running13)
{
running13 = true;
awaiter13 = enumerator13.MoveNextAsync().GetAwaiter();
if (awaiter13.IsCompleted)
{
Completed13(this);
}
else
{
awaiter13.SourceOnCompleted(Completed13Delegate, this);
}
}
if (!running14)
{
running14 = true;
awaiter14 = enumerator14.MoveNextAsync().GetAwaiter();
if (awaiter14.IsCompleted)
{
Completed14(this);
}
else
{
awaiter14.SourceOnCompleted(Completed14Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12 || !running13 || !running14)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed10(object state)
{
var self = (_CombineLatest)state;
self.running10 = false;
try
{
if (self.awaiter10.GetResult())
{
self.hasCurrent10 = true;
self.current10 = self.enumerator10.Current;
goto SUCCESS;
}
else
{
self.running10 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running10 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running10 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter10.SourceOnCompleted(Completed10Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed11(object state)
{
var self = (_CombineLatest)state;
self.running11 = false;
try
{
if (self.awaiter11.GetResult())
{
self.hasCurrent11 = true;
self.current11 = self.enumerator11.Current;
goto SUCCESS;
}
else
{
self.running11 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running11 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running11 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter11.SourceOnCompleted(Completed11Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed12(object state)
{
var self = (_CombineLatest)state;
self.running12 = false;
try
{
if (self.awaiter12.GetResult())
{
self.hasCurrent12 = true;
self.current12 = self.enumerator12.Current;
goto SUCCESS;
}
else
{
self.running12 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running12 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running12 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter12.SourceOnCompleted(Completed12Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed13(object state)
{
var self = (_CombineLatest)state;
self.running13 = false;
try
{
if (self.awaiter13.GetResult())
{
self.hasCurrent13 = true;
self.current13 = self.enumerator13.Current;
goto SUCCESS;
}
else
{
self.running13 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running13 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running13 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter13 = self.enumerator13.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter13.SourceOnCompleted(Completed13Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed14(object state)
{
var self = (_CombineLatest)state;
self.running14 = false;
try
{
if (self.awaiter14.GetResult())
{
self.hasCurrent14 = true;
self.current14 = self.enumerator14.Current;
goto SUCCESS;
}
else
{
self.running14 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running14 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running14 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter14 = self.enumerator14.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter14.SourceOnCompleted(Completed14Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12 && hasCurrent13 && hasCurrent14)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12, current13, current14);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
if (enumerator10 != null)
{
await enumerator10.DisposeAsync();
}
if (enumerator11 != null)
{
await enumerator11.DisposeAsync();
}
if (enumerator12 != null)
{
await enumerator12.DisposeAsync();
}
if (enumerator13 != null)
{
await enumerator13.DisposeAsync();
}
if (enumerator14 != null)
{
await enumerator14.DisposeAsync();
}
}
}
}
internal class CombineLatest<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> : IUniTaskAsyncEnumerable<TResult>
{
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly IUniTaskAsyncEnumerable<T13> source13;
readonly IUniTaskAsyncEnumerable<T14> source14;
readonly IUniTaskAsyncEnumerable<T15> source15;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector;
public CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, IUniTaskAsyncEnumerable<T14> source14, IUniTaskAsyncEnumerable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.source13 = source13;
this.source14 = source14;
this.source15 = source15;
this.resultSelector = resultSelector;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new _CombineLatest(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, source15, resultSelector, cancellationToken);
}
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
{
static readonly Action<object> Completed1Delegate = Completed1;
static readonly Action<object> Completed2Delegate = Completed2;
static readonly Action<object> Completed3Delegate = Completed3;
static readonly Action<object> Completed4Delegate = Completed4;
static readonly Action<object> Completed5Delegate = Completed5;
static readonly Action<object> Completed6Delegate = Completed6;
static readonly Action<object> Completed7Delegate = Completed7;
static readonly Action<object> Completed8Delegate = Completed8;
static readonly Action<object> Completed9Delegate = Completed9;
static readonly Action<object> Completed10Delegate = Completed10;
static readonly Action<object> Completed11Delegate = Completed11;
static readonly Action<object> Completed12Delegate = Completed12;
static readonly Action<object> Completed13Delegate = Completed13;
static readonly Action<object> Completed14Delegate = Completed14;
static readonly Action<object> Completed15Delegate = Completed15;
const int CompleteCount = 15;
readonly IUniTaskAsyncEnumerable<T1> source1;
readonly IUniTaskAsyncEnumerable<T2> source2;
readonly IUniTaskAsyncEnumerable<T3> source3;
readonly IUniTaskAsyncEnumerable<T4> source4;
readonly IUniTaskAsyncEnumerable<T5> source5;
readonly IUniTaskAsyncEnumerable<T6> source6;
readonly IUniTaskAsyncEnumerable<T7> source7;
readonly IUniTaskAsyncEnumerable<T8> source8;
readonly IUniTaskAsyncEnumerable<T9> source9;
readonly IUniTaskAsyncEnumerable<T10> source10;
readonly IUniTaskAsyncEnumerable<T11> source11;
readonly IUniTaskAsyncEnumerable<T12> source12;
readonly IUniTaskAsyncEnumerable<T13> source13;
readonly IUniTaskAsyncEnumerable<T14> source14;
readonly IUniTaskAsyncEnumerable<T15> source15;
readonly Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector;
CancellationToken cancellationToken;
IUniTaskAsyncEnumerator<T1> enumerator1;
UniTask<bool>.Awaiter awaiter1;
bool hasCurrent1;
bool running1;
T1 current1;
IUniTaskAsyncEnumerator<T2> enumerator2;
UniTask<bool>.Awaiter awaiter2;
bool hasCurrent2;
bool running2;
T2 current2;
IUniTaskAsyncEnumerator<T3> enumerator3;
UniTask<bool>.Awaiter awaiter3;
bool hasCurrent3;
bool running3;
T3 current3;
IUniTaskAsyncEnumerator<T4> enumerator4;
UniTask<bool>.Awaiter awaiter4;
bool hasCurrent4;
bool running4;
T4 current4;
IUniTaskAsyncEnumerator<T5> enumerator5;
UniTask<bool>.Awaiter awaiter5;
bool hasCurrent5;
bool running5;
T5 current5;
IUniTaskAsyncEnumerator<T6> enumerator6;
UniTask<bool>.Awaiter awaiter6;
bool hasCurrent6;
bool running6;
T6 current6;
IUniTaskAsyncEnumerator<T7> enumerator7;
UniTask<bool>.Awaiter awaiter7;
bool hasCurrent7;
bool running7;
T7 current7;
IUniTaskAsyncEnumerator<T8> enumerator8;
UniTask<bool>.Awaiter awaiter8;
bool hasCurrent8;
bool running8;
T8 current8;
IUniTaskAsyncEnumerator<T9> enumerator9;
UniTask<bool>.Awaiter awaiter9;
bool hasCurrent9;
bool running9;
T9 current9;
IUniTaskAsyncEnumerator<T10> enumerator10;
UniTask<bool>.Awaiter awaiter10;
bool hasCurrent10;
bool running10;
T10 current10;
IUniTaskAsyncEnumerator<T11> enumerator11;
UniTask<bool>.Awaiter awaiter11;
bool hasCurrent11;
bool running11;
T11 current11;
IUniTaskAsyncEnumerator<T12> enumerator12;
UniTask<bool>.Awaiter awaiter12;
bool hasCurrent12;
bool running12;
T12 current12;
IUniTaskAsyncEnumerator<T13> enumerator13;
UniTask<bool>.Awaiter awaiter13;
bool hasCurrent13;
bool running13;
T13 current13;
IUniTaskAsyncEnumerator<T14> enumerator14;
UniTask<bool>.Awaiter awaiter14;
bool hasCurrent14;
bool running14;
T14 current14;
IUniTaskAsyncEnumerator<T15> enumerator15;
UniTask<bool>.Awaiter awaiter15;
bool hasCurrent15;
bool running15;
T15 current15;
int completedCount;
bool syncRunning;
TResult result;
public _CombineLatest(IUniTaskAsyncEnumerable<T1> source1, IUniTaskAsyncEnumerable<T2> source2, IUniTaskAsyncEnumerable<T3> source3, IUniTaskAsyncEnumerable<T4> source4, IUniTaskAsyncEnumerable<T5> source5, IUniTaskAsyncEnumerable<T6> source6, IUniTaskAsyncEnumerable<T7> source7, IUniTaskAsyncEnumerable<T8> source8, IUniTaskAsyncEnumerable<T9> source9, IUniTaskAsyncEnumerable<T10> source10, IUniTaskAsyncEnumerable<T11> source11, IUniTaskAsyncEnumerable<T12> source12, IUniTaskAsyncEnumerable<T13> source13, IUniTaskAsyncEnumerable<T14> source14, IUniTaskAsyncEnumerable<T15> source15, Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult> resultSelector, CancellationToken cancellationToken)
{
this.source1 = source1;
this.source2 = source2;
this.source3 = source3;
this.source4 = source4;
this.source5 = source5;
this.source6 = source6;
this.source7 = source7;
this.source8 = source8;
this.source9 = source9;
this.source10 = source10;
this.source11 = source11;
this.source12 = source12;
this.source13 = source13;
this.source14 = source14;
this.source15 = source15;
this.resultSelector = resultSelector;
this.cancellationToken = cancellationToken;
TaskTracker.TrackActiveTask(this, 3);
}
public TResult Current => result;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (completedCount == CompleteCount) return CompletedTasks.False;
if (enumerator1 == null)
{
enumerator1 = source1.GetAsyncEnumerator(cancellationToken);
enumerator2 = source2.GetAsyncEnumerator(cancellationToken);
enumerator3 = source3.GetAsyncEnumerator(cancellationToken);
enumerator4 = source4.GetAsyncEnumerator(cancellationToken);
enumerator5 = source5.GetAsyncEnumerator(cancellationToken);
enumerator6 = source6.GetAsyncEnumerator(cancellationToken);
enumerator7 = source7.GetAsyncEnumerator(cancellationToken);
enumerator8 = source8.GetAsyncEnumerator(cancellationToken);
enumerator9 = source9.GetAsyncEnumerator(cancellationToken);
enumerator10 = source10.GetAsyncEnumerator(cancellationToken);
enumerator11 = source11.GetAsyncEnumerator(cancellationToken);
enumerator12 = source12.GetAsyncEnumerator(cancellationToken);
enumerator13 = source13.GetAsyncEnumerator(cancellationToken);
enumerator14 = source14.GetAsyncEnumerator(cancellationToken);
enumerator15 = source15.GetAsyncEnumerator(cancellationToken);
}
completionSource.Reset();
AGAIN:
syncRunning = true;
if (!running1)
{
running1 = true;
awaiter1 = enumerator1.MoveNextAsync().GetAwaiter();
if (awaiter1.IsCompleted)
{
Completed1(this);
}
else
{
awaiter1.SourceOnCompleted(Completed1Delegate, this);
}
}
if (!running2)
{
running2 = true;
awaiter2 = enumerator2.MoveNextAsync().GetAwaiter();
if (awaiter2.IsCompleted)
{
Completed2(this);
}
else
{
awaiter2.SourceOnCompleted(Completed2Delegate, this);
}
}
if (!running3)
{
running3 = true;
awaiter3 = enumerator3.MoveNextAsync().GetAwaiter();
if (awaiter3.IsCompleted)
{
Completed3(this);
}
else
{
awaiter3.SourceOnCompleted(Completed3Delegate, this);
}
}
if (!running4)
{
running4 = true;
awaiter4 = enumerator4.MoveNextAsync().GetAwaiter();
if (awaiter4.IsCompleted)
{
Completed4(this);
}
else
{
awaiter4.SourceOnCompleted(Completed4Delegate, this);
}
}
if (!running5)
{
running5 = true;
awaiter5 = enumerator5.MoveNextAsync().GetAwaiter();
if (awaiter5.IsCompleted)
{
Completed5(this);
}
else
{
awaiter5.SourceOnCompleted(Completed5Delegate, this);
}
}
if (!running6)
{
running6 = true;
awaiter6 = enumerator6.MoveNextAsync().GetAwaiter();
if (awaiter6.IsCompleted)
{
Completed6(this);
}
else
{
awaiter6.SourceOnCompleted(Completed6Delegate, this);
}
}
if (!running7)
{
running7 = true;
awaiter7 = enumerator7.MoveNextAsync().GetAwaiter();
if (awaiter7.IsCompleted)
{
Completed7(this);
}
else
{
awaiter7.SourceOnCompleted(Completed7Delegate, this);
}
}
if (!running8)
{
running8 = true;
awaiter8 = enumerator8.MoveNextAsync().GetAwaiter();
if (awaiter8.IsCompleted)
{
Completed8(this);
}
else
{
awaiter8.SourceOnCompleted(Completed8Delegate, this);
}
}
if (!running9)
{
running9 = true;
awaiter9 = enumerator9.MoveNextAsync().GetAwaiter();
if (awaiter9.IsCompleted)
{
Completed9(this);
}
else
{
awaiter9.SourceOnCompleted(Completed9Delegate, this);
}
}
if (!running10)
{
running10 = true;
awaiter10 = enumerator10.MoveNextAsync().GetAwaiter();
if (awaiter10.IsCompleted)
{
Completed10(this);
}
else
{
awaiter10.SourceOnCompleted(Completed10Delegate, this);
}
}
if (!running11)
{
running11 = true;
awaiter11 = enumerator11.MoveNextAsync().GetAwaiter();
if (awaiter11.IsCompleted)
{
Completed11(this);
}
else
{
awaiter11.SourceOnCompleted(Completed11Delegate, this);
}
}
if (!running12)
{
running12 = true;
awaiter12 = enumerator12.MoveNextAsync().GetAwaiter();
if (awaiter12.IsCompleted)
{
Completed12(this);
}
else
{
awaiter12.SourceOnCompleted(Completed12Delegate, this);
}
}
if (!running13)
{
running13 = true;
awaiter13 = enumerator13.MoveNextAsync().GetAwaiter();
if (awaiter13.IsCompleted)
{
Completed13(this);
}
else
{
awaiter13.SourceOnCompleted(Completed13Delegate, this);
}
}
if (!running14)
{
running14 = true;
awaiter14 = enumerator14.MoveNextAsync().GetAwaiter();
if (awaiter14.IsCompleted)
{
Completed14(this);
}
else
{
awaiter14.SourceOnCompleted(Completed14Delegate, this);
}
}
if (!running15)
{
running15 = true;
awaiter15 = enumerator15.MoveNextAsync().GetAwaiter();
if (awaiter15.IsCompleted)
{
Completed15(this);
}
else
{
awaiter15.SourceOnCompleted(Completed15Delegate, this);
}
}
if (!running1 || !running2 || !running3 || !running4 || !running5 || !running6 || !running7 || !running8 || !running9 || !running10 || !running11 || !running12 || !running13 || !running14 || !running15)
{
goto AGAIN;
}
syncRunning = false;
return new UniTask<bool>(this, completionSource.Version);
}
static void Completed1(object state)
{
var self = (_CombineLatest)state;
self.running1 = false;
try
{
if (self.awaiter1.GetResult())
{
self.hasCurrent1 = true;
self.current1 = self.enumerator1.Current;
goto SUCCESS;
}
else
{
self.running1 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running1 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running1 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter1 = self.enumerator1.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter1.SourceOnCompleted(Completed1Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed2(object state)
{
var self = (_CombineLatest)state;
self.running2 = false;
try
{
if (self.awaiter2.GetResult())
{
self.hasCurrent2 = true;
self.current2 = self.enumerator2.Current;
goto SUCCESS;
}
else
{
self.running2 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running2 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running2 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter2 = self.enumerator2.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter2.SourceOnCompleted(Completed2Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed3(object state)
{
var self = (_CombineLatest)state;
self.running3 = false;
try
{
if (self.awaiter3.GetResult())
{
self.hasCurrent3 = true;
self.current3 = self.enumerator3.Current;
goto SUCCESS;
}
else
{
self.running3 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running3 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running3 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter3 = self.enumerator3.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter3.SourceOnCompleted(Completed3Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed4(object state)
{
var self = (_CombineLatest)state;
self.running4 = false;
try
{
if (self.awaiter4.GetResult())
{
self.hasCurrent4 = true;
self.current4 = self.enumerator4.Current;
goto SUCCESS;
}
else
{
self.running4 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running4 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running4 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter4 = self.enumerator4.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter4.SourceOnCompleted(Completed4Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed5(object state)
{
var self = (_CombineLatest)state;
self.running5 = false;
try
{
if (self.awaiter5.GetResult())
{
self.hasCurrent5 = true;
self.current5 = self.enumerator5.Current;
goto SUCCESS;
}
else
{
self.running5 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running5 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running5 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter5 = self.enumerator5.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter5.SourceOnCompleted(Completed5Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed6(object state)
{
var self = (_CombineLatest)state;
self.running6 = false;
try
{
if (self.awaiter6.GetResult())
{
self.hasCurrent6 = true;
self.current6 = self.enumerator6.Current;
goto SUCCESS;
}
else
{
self.running6 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running6 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running6 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter6 = self.enumerator6.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter6.SourceOnCompleted(Completed6Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed7(object state)
{
var self = (_CombineLatest)state;
self.running7 = false;
try
{
if (self.awaiter7.GetResult())
{
self.hasCurrent7 = true;
self.current7 = self.enumerator7.Current;
goto SUCCESS;
}
else
{
self.running7 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running7 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running7 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter7 = self.enumerator7.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter7.SourceOnCompleted(Completed7Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed8(object state)
{
var self = (_CombineLatest)state;
self.running8 = false;
try
{
if (self.awaiter8.GetResult())
{
self.hasCurrent8 = true;
self.current8 = self.enumerator8.Current;
goto SUCCESS;
}
else
{
self.running8 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running8 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running8 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter8 = self.enumerator8.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter8.SourceOnCompleted(Completed8Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed9(object state)
{
var self = (_CombineLatest)state;
self.running9 = false;
try
{
if (self.awaiter9.GetResult())
{
self.hasCurrent9 = true;
self.current9 = self.enumerator9.Current;
goto SUCCESS;
}
else
{
self.running9 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running9 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running9 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter9 = self.enumerator9.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter9.SourceOnCompleted(Completed9Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed10(object state)
{
var self = (_CombineLatest)state;
self.running10 = false;
try
{
if (self.awaiter10.GetResult())
{
self.hasCurrent10 = true;
self.current10 = self.enumerator10.Current;
goto SUCCESS;
}
else
{
self.running10 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running10 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running10 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter10 = self.enumerator10.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter10.SourceOnCompleted(Completed10Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed11(object state)
{
var self = (_CombineLatest)state;
self.running11 = false;
try
{
if (self.awaiter11.GetResult())
{
self.hasCurrent11 = true;
self.current11 = self.enumerator11.Current;
goto SUCCESS;
}
else
{
self.running11 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running11 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running11 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter11 = self.enumerator11.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter11.SourceOnCompleted(Completed11Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed12(object state)
{
var self = (_CombineLatest)state;
self.running12 = false;
try
{
if (self.awaiter12.GetResult())
{
self.hasCurrent12 = true;
self.current12 = self.enumerator12.Current;
goto SUCCESS;
}
else
{
self.running12 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running12 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running12 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter12 = self.enumerator12.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter12.SourceOnCompleted(Completed12Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed13(object state)
{
var self = (_CombineLatest)state;
self.running13 = false;
try
{
if (self.awaiter13.GetResult())
{
self.hasCurrent13 = true;
self.current13 = self.enumerator13.Current;
goto SUCCESS;
}
else
{
self.running13 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running13 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running13 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter13 = self.enumerator13.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter13.SourceOnCompleted(Completed13Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed14(object state)
{
var self = (_CombineLatest)state;
self.running14 = false;
try
{
if (self.awaiter14.GetResult())
{
self.hasCurrent14 = true;
self.current14 = self.enumerator14.Current;
goto SUCCESS;
}
else
{
self.running14 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running14 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running14 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter14 = self.enumerator14.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter14.SourceOnCompleted(Completed14Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
static void Completed15(object state)
{
var self = (_CombineLatest)state;
self.running15 = false;
try
{
if (self.awaiter15.GetResult())
{
self.hasCurrent15 = true;
self.current15 = self.enumerator15.Current;
goto SUCCESS;
}
else
{
self.running15 = true; // as complete, no more call MoveNextAsync.
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
{
goto COMPLETE;
}
return;
}
}
catch (Exception ex)
{
self.running15 = true; // as complete, no more call MoveNextAsync.
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
SUCCESS:
if (!self.TrySetResult())
{
if (self.syncRunning) return;
self.running15 = true; // as complete, no more call MoveNextAsync.
try
{
self.awaiter15 = self.enumerator15.MoveNextAsync().GetAwaiter();
}
catch (Exception ex)
{
self.completedCount = CompleteCount;
self.completionSource.TrySetException(ex);
return;
}
self.awaiter15.SourceOnCompleted(Completed15Delegate, self);
}
return;
COMPLETE:
self.completionSource.TrySetResult(false);
return;
}
bool TrySetResult()
{
if (hasCurrent1 && hasCurrent2 && hasCurrent3 && hasCurrent4 && hasCurrent5 && hasCurrent6 && hasCurrent7 && hasCurrent8 && hasCurrent9 && hasCurrent10 && hasCurrent11 && hasCurrent12 && hasCurrent13 && hasCurrent14 && hasCurrent15)
{
result = resultSelector(current1, current2, current3, current4, current5, current6, current7, current8, current9, current10, current11, current12, current13, current14, current15);
completionSource.TrySetResult(true);
return true;
}
else
{
return false;
}
}
public async UniTask DisposeAsync()
{
TaskTracker.RemoveTracking(this);
if (enumerator1 != null)
{
await enumerator1.DisposeAsync();
}
if (enumerator2 != null)
{
await enumerator2.DisposeAsync();
}
if (enumerator3 != null)
{
await enumerator3.DisposeAsync();
}
if (enumerator4 != null)
{
await enumerator4.DisposeAsync();
}
if (enumerator5 != null)
{
await enumerator5.DisposeAsync();
}
if (enumerator6 != null)
{
await enumerator6.DisposeAsync();
}
if (enumerator7 != null)
{
await enumerator7.DisposeAsync();
}
if (enumerator8 != null)
{
await enumerator8.DisposeAsync();
}
if (enumerator9 != null)
{
await enumerator9.DisposeAsync();
}
if (enumerator10 != null)
{
await enumerator10.DisposeAsync();
}
if (enumerator11 != null)
{
await enumerator11.DisposeAsync();
}
if (enumerator12 != null)
{
await enumerator12.DisposeAsync();
}
if (enumerator13 != null)
{
await enumerator13.DisposeAsync();
}
if (enumerator14 != null)
{
await enumerator14.DisposeAsync();
}
if (enumerator15 != null)
{
await enumerator15.DisposeAsync();
}
}
}
}
}