|
- using Cysharp.Threading.Tasks.Internal;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
-
- namespace Cysharp.Threading.Tasks.Linq
- {
- public static partial class UniTaskAsyncEnumerable
- {
- // Ix-Async returns IGrouping but it is competely waste, use standard IGrouping.
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- return new GroupBy<TSource, TKey, TSource>(source, keySelector, x => x, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupBy<TSource, TKey, TSource>(source, keySelector, x => x, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- return new GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- return new GroupBy<TSource, TKey, TSource, TResult>(source, keySelector, x => x, resultSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupBy<TSource, TKey, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TKey, IEnumerable<TSource>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupBy<TSource, TKey, TSource, TResult>(source, keySelector, x => x, resultSelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- return new GroupBy<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, EqualityComparer<TKey>.Default);
- }
- public static IUniTaskAsyncEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupBy<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, comparer);
- }
-
- // await
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TSource>> GroupByAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- return new GroupByAwait<TSource, TKey, TSource>(source, keySelector, x => UniTask.FromResult(x), EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TSource>> GroupByAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwait<TSource, TKey, TSource>(source, keySelector, x => UniTask.FromResult(x), comparer);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>> GroupByAwait<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- return new GroupByAwait<TSource, TKey, TElement>(source, keySelector, elementSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>> GroupByAwait<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwait<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwait<TSource, TKey, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TKey, IEnumerable<TSource>, UniTask<TResult>> resultSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- return new GroupByAwait<TSource, TKey, TSource, TResult>(source, keySelector, x => UniTask.FromResult(x), resultSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwait<TSource, TKey, TElement, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, UniTask<TResult>> resultSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- return new GroupByAwait<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwait<TSource, TKey, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TKey, IEnumerable<TSource>, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwait<TSource, TKey, TSource, TResult>(source, keySelector, x => UniTask.FromResult(x), resultSelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwait<TSource, TKey, TElement, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwait<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, comparer);
- }
-
- // with ct
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TSource>> GroupByAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- return new GroupByAwaitWithCancellation<TSource, TKey, TSource>(source, keySelector, (x, _) => UniTask.FromResult(x), EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TSource>> GroupByAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwaitWithCancellation<TSource, TKey, TSource>(source, keySelector, (x, _) => UniTask.FromResult(x), comparer);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>> GroupByAwaitWithCancellation<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- return new GroupByAwaitWithCancellation<TSource, TKey, TElement>(source, keySelector, elementSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>> GroupByAwaitWithCancellation<TSource, TKey, TElement>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwaitWithCancellation<TSource, TKey, TElement>(source, keySelector, elementSelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwaitWithCancellation<TSource, TKey, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TKey, IEnumerable<TSource>, CancellationToken, UniTask<TResult>> resultSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- return new GroupByAwaitWithCancellation<TSource, TKey, TSource, TResult>(source, keySelector, (x, _) => UniTask.FromResult(x), resultSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwaitWithCancellation<TSource, TKey, TElement, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, CancellationToken, UniTask<TResult>> resultSelector)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- return new GroupByAwaitWithCancellation<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, EqualityComparer<TKey>.Default);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwaitWithCancellation<TSource, TKey, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TKey, IEnumerable<TSource>, CancellationToken, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwaitWithCancellation<TSource, TKey, TSource, TResult>(source, keySelector, (x, _) => UniTask.FromResult(x), resultSelector, comparer);
- }
-
- public static IUniTaskAsyncEnumerable<TResult> GroupByAwaitWithCancellation<TSource, TKey, TElement, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, CancellationToken, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer)
- {
- Error.ThrowArgumentNullException(source, nameof(source));
- Error.ThrowArgumentNullException(keySelector, nameof(keySelector));
- Error.ThrowArgumentNullException(elementSelector, nameof(elementSelector));
- Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
- Error.ThrowArgumentNullException(comparer, nameof(comparer));
- return new GroupByAwaitWithCancellation<TSource, TKey, TElement, TResult>(source, keySelector, elementSelector, resultSelector, comparer);
- }
- }
-
- internal sealed class GroupBy<TSource, TKey, TElement> : IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, TKey> keySelector;
- readonly Func<TSource, TElement> elementSelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public GroupBy(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<IGrouping<TKey, TElement>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _GroupBy(source, keySelector, elementSelector, comparer, cancellationToken);
- }
-
- sealed class _GroupBy : MoveNextSource, IUniTaskAsyncEnumerator<IGrouping<TKey, TElement>>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, TKey> keySelector;
- readonly Func<TSource, TElement> elementSelector;
- readonly IEqualityComparer<TKey> comparer;
- CancellationToken cancellationToken;
-
- IEnumerator<IGrouping<TKey, TElement>> groupEnumerator;
-
- public _GroupBy(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.comparer = comparer;
- this.cancellationToken = cancellationToken;
- TaskTracker.TrackActiveTask(this, 3);
- }
-
- public IGrouping<TKey, TElement> Current { get; private set; }
-
- public UniTask<bool> MoveNextAsync()
- {
- cancellationToken.ThrowIfCancellationRequested();
- completionSource.Reset();
-
- if (groupEnumerator == null)
- {
- CreateLookup().Forget();
- }
- else
- {
- SourceMoveNext();
- }
- return new UniTask<bool>(this, completionSource.Version);
- }
-
- async UniTaskVoid CreateLookup()
- {
- try
- {
- var lookup = await source.ToLookupAsync(keySelector, elementSelector, comparer, cancellationToken);
- groupEnumerator = lookup.GetEnumerator();
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- SourceMoveNext();
- }
-
- void SourceMoveNext()
- {
- try
- {
- if (groupEnumerator.MoveNext())
- {
- Current = groupEnumerator.Current as IGrouping<TKey, TElement>;
- completionSource.TrySetResult(true);
- }
- else
- {
- completionSource.TrySetResult(false);
- }
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- }
-
- public UniTask DisposeAsync()
- {
- TaskTracker.RemoveTracking(this);
- if (groupEnumerator != null)
- {
- groupEnumerator.Dispose();
- }
-
- return default;
- }
- }
- }
-
- internal sealed class GroupBy<TSource, TKey, TElement, TResult> : IUniTaskAsyncEnumerable<TResult>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, TKey> keySelector;
- readonly Func<TSource, TElement> elementSelector;
- readonly Func<TKey, IEnumerable<TElement>, TResult> resultSelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public GroupBy(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.resultSelector = resultSelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _GroupBy(source, keySelector, elementSelector, resultSelector, comparer, cancellationToken);
- }
-
- sealed class _GroupBy : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, TKey> keySelector;
- readonly Func<TSource, TElement> elementSelector;
- readonly Func<TKey, IEnumerable<TElement>, TResult> resultSelector;
- readonly IEqualityComparer<TKey> comparer;
- CancellationToken cancellationToken;
-
- IEnumerator<IGrouping<TKey, TElement>> groupEnumerator;
-
- public _GroupBy(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, Func<TKey, IEnumerable<TElement>, TResult> resultSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.resultSelector = resultSelector;
- this.comparer = comparer;
- this.cancellationToken = cancellationToken;
- TaskTracker.TrackActiveTask(this, 3);
- }
-
- public TResult Current { get; private set; }
-
- public UniTask<bool> MoveNextAsync()
- {
- cancellationToken.ThrowIfCancellationRequested();
- completionSource.Reset();
-
- if (groupEnumerator == null)
- {
- CreateLookup().Forget();
- }
- else
- {
- SourceMoveNext();
- }
- return new UniTask<bool>(this, completionSource.Version);
- }
-
- async UniTaskVoid CreateLookup()
- {
- try
- {
- var lookup = await source.ToLookupAsync(keySelector, elementSelector, comparer, cancellationToken);
- groupEnumerator = lookup.GetEnumerator();
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- SourceMoveNext();
- }
-
- void SourceMoveNext()
- {
- try
- {
- if (groupEnumerator.MoveNext())
- {
- var current = groupEnumerator.Current;
- Current = resultSelector(current.Key, current);
- completionSource.TrySetResult(true);
- }
- else
- {
- completionSource.TrySetResult(false);
- }
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- }
-
- public UniTask DisposeAsync()
- {
- TaskTracker.RemoveTracking(this);
- if (groupEnumerator != null)
- {
- groupEnumerator.Dispose();
- }
-
- return default;
- }
- }
- }
-
- internal sealed class GroupByAwait<TSource, TKey, TElement> : IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, UniTask<TKey>> keySelector;
- readonly Func<TSource, UniTask<TElement>> elementSelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public GroupByAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<IGrouping<TKey, TElement>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _GroupByAwait(source, keySelector, elementSelector, comparer, cancellationToken);
- }
-
- sealed class _GroupByAwait : MoveNextSource, IUniTaskAsyncEnumerator<IGrouping<TKey, TElement>>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, UniTask<TKey>> keySelector;
- readonly Func<TSource, UniTask<TElement>> elementSelector;
- readonly IEqualityComparer<TKey> comparer;
- CancellationToken cancellationToken;
-
- IEnumerator<IGrouping<TKey, TElement>> groupEnumerator;
-
- public _GroupByAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.comparer = comparer;
- this.cancellationToken = cancellationToken;
- TaskTracker.TrackActiveTask(this, 3);
- }
-
- public IGrouping<TKey, TElement> Current { get; private set; }
-
- public UniTask<bool> MoveNextAsync()
- {
- cancellationToken.ThrowIfCancellationRequested();
- completionSource.Reset();
-
- if (groupEnumerator == null)
- {
- CreateLookup().Forget();
- }
- else
- {
- SourceMoveNext();
- }
- return new UniTask<bool>(this, completionSource.Version);
- }
-
- async UniTaskVoid CreateLookup()
- {
- try
- {
- var lookup = await source.ToLookupAwaitAsync(keySelector, elementSelector, comparer, cancellationToken);
- groupEnumerator = lookup.GetEnumerator();
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- SourceMoveNext();
- }
-
- void SourceMoveNext()
- {
- try
- {
- if (groupEnumerator.MoveNext())
- {
- Current = groupEnumerator.Current as IGrouping<TKey, TElement>;
- completionSource.TrySetResult(true);
- }
- else
- {
- completionSource.TrySetResult(false);
- }
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- }
-
- public UniTask DisposeAsync()
- {
- TaskTracker.RemoveTracking(this);
- if (groupEnumerator != null)
- {
- groupEnumerator.Dispose();
- }
-
- return default;
- }
- }
- }
-
- internal sealed class GroupByAwait<TSource, TKey, TElement, TResult> : IUniTaskAsyncEnumerable<TResult>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, UniTask<TKey>> keySelector;
- readonly Func<TSource, UniTask<TElement>> elementSelector;
- readonly Func<TKey, IEnumerable<TElement>, UniTask<TResult>> resultSelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public GroupByAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.resultSelector = resultSelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _GroupByAwait(source, keySelector, elementSelector, resultSelector, comparer, cancellationToken);
- }
-
- sealed class _GroupByAwait : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
- {
- readonly static Action<object> ResultSelectCoreDelegate = ResultSelectCore;
-
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, UniTask<TKey>> keySelector;
- readonly Func<TSource, UniTask<TElement>> elementSelector;
- readonly Func<TKey, IEnumerable<TElement>, UniTask<TResult>> resultSelector;
- readonly IEqualityComparer<TKey> comparer;
- CancellationToken cancellationToken;
-
- IEnumerator<IGrouping<TKey, TElement>> groupEnumerator;
- UniTask<TResult>.Awaiter awaiter;
-
- public _GroupByAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, Func<TSource, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.resultSelector = resultSelector;
- this.comparer = comparer;
- this.cancellationToken = cancellationToken;
- TaskTracker.TrackActiveTask(this, 3);
- }
-
- public TResult Current { get; private set; }
-
- public UniTask<bool> MoveNextAsync()
- {
- cancellationToken.ThrowIfCancellationRequested();
- completionSource.Reset();
-
- if (groupEnumerator == null)
- {
- CreateLookup().Forget();
- }
- else
- {
- SourceMoveNext();
- }
- return new UniTask<bool>(this, completionSource.Version);
- }
-
- async UniTaskVoid CreateLookup()
- {
- try
- {
- var lookup = await source.ToLookupAwaitAsync(keySelector, elementSelector, comparer, cancellationToken);
- groupEnumerator = lookup.GetEnumerator();
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- SourceMoveNext();
- }
-
- void SourceMoveNext()
- {
- try
- {
- if (groupEnumerator.MoveNext())
- {
- var current = groupEnumerator.Current;
-
- awaiter = resultSelector(current.Key, current).GetAwaiter();
- if (awaiter.IsCompleted)
- {
- ResultSelectCore(this);
- }
- else
- {
- awaiter.SourceOnCompleted(ResultSelectCoreDelegate, this);
- }
- return;
- }
- else
- {
- completionSource.TrySetResult(false);
- }
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- }
-
- static void ResultSelectCore(object state)
- {
- var self = (_GroupByAwait)state;
-
- if (self.TryGetResult(self.awaiter, out var result))
- {
- self.Current = result;
- self.completionSource.TrySetResult(true);
- }
- }
-
- public UniTask DisposeAsync()
- {
- TaskTracker.RemoveTracking(this);
- if (groupEnumerator != null)
- {
- groupEnumerator.Dispose();
- }
-
- return default;
- }
- }
- }
-
- internal sealed class GroupByAwaitWithCancellation<TSource, TKey, TElement> : IUniTaskAsyncEnumerable<IGrouping<TKey, TElement>>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, CancellationToken, UniTask<TKey>> keySelector;
- readonly Func<TSource, CancellationToken, UniTask<TElement>> elementSelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<IGrouping<TKey, TElement>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _GroupByAwaitWithCancellation(source, keySelector, elementSelector, comparer, cancellationToken);
- }
-
- sealed class _GroupByAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator<IGrouping<TKey, TElement>>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, CancellationToken, UniTask<TKey>> keySelector;
- readonly Func<TSource, CancellationToken, UniTask<TElement>> elementSelector;
- readonly IEqualityComparer<TKey> comparer;
- CancellationToken cancellationToken;
-
- IEnumerator<IGrouping<TKey, TElement>> groupEnumerator;
-
- public _GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.comparer = comparer;
- this.cancellationToken = cancellationToken;
- TaskTracker.TrackActiveTask(this, 3);
- }
-
- public IGrouping<TKey, TElement> Current { get; private set; }
-
- public UniTask<bool> MoveNextAsync()
- {
- cancellationToken.ThrowIfCancellationRequested();
- completionSource.Reset();
-
- if (groupEnumerator == null)
- {
- CreateLookup().Forget();
- }
- else
- {
- SourceMoveNext();
- }
- return new UniTask<bool>(this, completionSource.Version);
- }
-
- async UniTaskVoid CreateLookup()
- {
- try
- {
- var lookup = await source.ToLookupAwaitWithCancellationAsync(keySelector, elementSelector, comparer, cancellationToken);
- groupEnumerator = lookup.GetEnumerator();
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- SourceMoveNext();
- }
-
- void SourceMoveNext()
- {
- try
- {
- if (groupEnumerator.MoveNext())
- {
- Current = groupEnumerator.Current as IGrouping<TKey, TElement>;
- completionSource.TrySetResult(true);
- }
- else
- {
- completionSource.TrySetResult(false);
- }
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- }
-
- public UniTask DisposeAsync()
- {
- TaskTracker.RemoveTracking(this);
- if (groupEnumerator != null)
- {
- groupEnumerator.Dispose();
- }
-
- return default;
- }
- }
- }
-
- internal sealed class GroupByAwaitWithCancellation<TSource, TKey, TElement, TResult> : IUniTaskAsyncEnumerable<TResult>
- {
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, CancellationToken, UniTask<TKey>> keySelector;
- readonly Func<TSource, CancellationToken, UniTask<TElement>> elementSelector;
- readonly Func<TKey, IEnumerable<TElement>, CancellationToken, UniTask<TResult>> resultSelector;
- readonly IEqualityComparer<TKey> comparer;
-
- public GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, CancellationToken, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.resultSelector = resultSelector;
- this.comparer = comparer;
- }
-
- public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
- {
- return new _GroupByAwaitWithCancellation(source, keySelector, elementSelector, resultSelector, comparer, cancellationToken);
- }
-
- sealed class _GroupByAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
- {
- readonly static Action<object> ResultSelectCoreDelegate = ResultSelectCore;
-
- readonly IUniTaskAsyncEnumerable<TSource> source;
- readonly Func<TSource, CancellationToken, UniTask<TKey>> keySelector;
- readonly Func<TSource, CancellationToken, UniTask<TElement>> elementSelector;
- readonly Func<TKey, IEnumerable<TElement>, CancellationToken, UniTask<TResult>> resultSelector;
- readonly IEqualityComparer<TKey> comparer;
- CancellationToken cancellationToken;
-
- IEnumerator<IGrouping<TKey, TElement>> groupEnumerator;
- UniTask<TResult>.Awaiter awaiter;
-
- public _GroupByAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, Func<TSource, CancellationToken, UniTask<TElement>> elementSelector, Func<TKey, IEnumerable<TElement>, CancellationToken, UniTask<TResult>> resultSelector, IEqualityComparer<TKey> comparer, CancellationToken cancellationToken)
- {
- this.source = source;
- this.keySelector = keySelector;
- this.elementSelector = elementSelector;
- this.resultSelector = resultSelector;
- this.comparer = comparer;
- this.cancellationToken = cancellationToken;
- TaskTracker.TrackActiveTask(this, 3);
- }
-
- public TResult Current { get; private set; }
-
- public UniTask<bool> MoveNextAsync()
- {
- cancellationToken.ThrowIfCancellationRequested();
- completionSource.Reset();
-
- if (groupEnumerator == null)
- {
- CreateLookup().Forget();
- }
- else
- {
- SourceMoveNext();
- }
- return new UniTask<bool>(this, completionSource.Version);
- }
-
- async UniTaskVoid CreateLookup()
- {
- try
- {
- var lookup = await source.ToLookupAwaitWithCancellationAsync(keySelector, elementSelector, comparer, cancellationToken);
- groupEnumerator = lookup.GetEnumerator();
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- SourceMoveNext();
- }
-
- void SourceMoveNext()
- {
- try
- {
- if (groupEnumerator.MoveNext())
- {
- var current = groupEnumerator.Current;
-
- awaiter = resultSelector(current.Key, current, cancellationToken).GetAwaiter();
- if (awaiter.IsCompleted)
- {
- ResultSelectCore(this);
- }
- else
- {
- awaiter.SourceOnCompleted(ResultSelectCoreDelegate, this);
- }
- return;
- }
- else
- {
- completionSource.TrySetResult(false);
- }
- }
- catch (Exception ex)
- {
- completionSource.TrySetException(ex);
- return;
- }
- }
-
- static void ResultSelectCore(object state)
- {
- var self = (_GroupByAwaitWithCancellation)state;
-
- if (self.TryGetResult(self.awaiter, out var result))
- {
- self.Current = result;
- self.completionSource.TrySetResult(true);
- }
- }
-
- public UniTask DisposeAsync()
- {
- TaskTracker.RemoveTracking(this);
- if (groupEnumerator != null)
- {
- groupEnumerator.Dispose();
- }
-
- return default;
- }
- }
- }
- }
|