You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
558 lines
26 KiB
558 lines
26 KiB
using Cysharp.Threading.Tasks; |
|
using Cysharp.Threading.Tasks.Internal; |
|
using System; |
|
using System.Collections.Generic; |
|
using System.Threading; |
|
|
|
namespace Cysharp.Threading.Tasks.Linq |
|
{ |
|
public static partial class UniTaskAsyncEnumerable |
|
{ |
|
#region OrderBy_OrderByDescending |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, false, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderBy<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer, false, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, false, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, comparer, false, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, false, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, comparer, false, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescending<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, true, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescending<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return new OrderedAsyncEnumerable<TSource, TKey>(source, keySelector, comparer, true, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, true, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwait<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return new OrderedAsyncEnumerableAwait<TSource, TKey>(source, keySelector, comparer, true, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, Comparer<TKey>.Default, true, null); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> OrderByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return new OrderedAsyncEnumerableAwaitWithCancellation<TSource, TKey>(source, keySelector, comparer, true, null); |
|
} |
|
|
|
#endregion |
|
|
|
#region ThenBy_ThenByDescending |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenBy<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, false); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenBy<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, comparer, false); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, false); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, comparer, false); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, false); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, comparer, false); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescending<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, true); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescending<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, comparer, true); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, true); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwait<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, comparer, true); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, Comparer<TKey>.Default, true); |
|
} |
|
|
|
public static IUniTaskOrderedAsyncEnumerable<TSource> ThenByDescendingAwaitWithCancellation<TSource, TKey>(this IUniTaskOrderedAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer) |
|
{ |
|
Error.ThrowArgumentNullException(source, nameof(source)); |
|
Error.ThrowArgumentNullException(keySelector, nameof(keySelector)); |
|
Error.ThrowArgumentNullException(comparer, nameof(comparer)); |
|
|
|
return source.CreateOrderedEnumerable(keySelector, comparer, true); |
|
} |
|
|
|
#endregion |
|
} |
|
|
|
internal abstract class AsyncEnumerableSorter<TElement> |
|
{ |
|
internal abstract UniTask ComputeKeysAsync(TElement[] elements, int count); |
|
|
|
internal abstract int CompareKeys(int index1, int index2); |
|
|
|
internal async UniTask<int[]> SortAsync(TElement[] elements, int count) |
|
{ |
|
await ComputeKeysAsync(elements, count); |
|
|
|
int[] map = new int[count]; |
|
for (int i = 0; i < count; i++) map[i] = i; |
|
QuickSort(map, 0, count - 1); |
|
return map; |
|
} |
|
|
|
void QuickSort(int[] map, int left, int right) |
|
{ |
|
do |
|
{ |
|
int i = left; |
|
int j = right; |
|
int x = map[i + ((j - i) >> 1)]; |
|
do |
|
{ |
|
while (i < map.Length && CompareKeys(x, map[i]) > 0) i++; |
|
while (j >= 0 && CompareKeys(x, map[j]) < 0) j--; |
|
if (i > j) break; |
|
if (i < j) |
|
{ |
|
int temp = map[i]; |
|
map[i] = map[j]; |
|
map[j] = temp; |
|
} |
|
i++; |
|
j--; |
|
} while (i <= j); |
|
if (j - left <= right - i) |
|
{ |
|
if (left < j) QuickSort(map, left, j); |
|
left = i; |
|
} |
|
else |
|
{ |
|
if (i < right) QuickSort(map, i, right); |
|
right = j; |
|
} |
|
} while (left < right); |
|
} |
|
} |
|
|
|
internal class SyncSelectorAsyncEnumerableSorter<TElement, TKey> : AsyncEnumerableSorter<TElement> |
|
{ |
|
readonly Func<TElement, TKey> keySelector; |
|
readonly IComparer<TKey> comparer; |
|
readonly bool descending; |
|
readonly AsyncEnumerableSorter<TElement> next; |
|
TKey[] keys; |
|
|
|
internal SyncSelectorAsyncEnumerableSorter(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, AsyncEnumerableSorter<TElement> next) |
|
{ |
|
this.keySelector = keySelector; |
|
this.comparer = comparer; |
|
this.descending = descending; |
|
this.next = next; |
|
} |
|
|
|
internal override async UniTask ComputeKeysAsync(TElement[] elements, int count) |
|
{ |
|
keys = new TKey[count]; |
|
for (int i = 0; i < count; i++) keys[i] = keySelector(elements[i]); |
|
if (next != null) await next.ComputeKeysAsync(elements, count); |
|
} |
|
|
|
internal override int CompareKeys(int index1, int index2) |
|
{ |
|
int c = comparer.Compare(keys[index1], keys[index2]); |
|
if (c == 0) |
|
{ |
|
if (next == null) return index1 - index2; |
|
return next.CompareKeys(index1, index2); |
|
} |
|
return descending ? -c : c; |
|
} |
|
} |
|
|
|
internal class AsyncSelectorEnumerableSorter<TElement, TKey> : AsyncEnumerableSorter<TElement> |
|
{ |
|
readonly Func<TElement, UniTask<TKey>> keySelector; |
|
readonly IComparer<TKey> comparer; |
|
readonly bool descending; |
|
readonly AsyncEnumerableSorter<TElement> next; |
|
TKey[] keys; |
|
|
|
internal AsyncSelectorEnumerableSorter(Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, AsyncEnumerableSorter<TElement> next) |
|
{ |
|
this.keySelector = keySelector; |
|
this.comparer = comparer; |
|
this.descending = descending; |
|
this.next = next; |
|
} |
|
|
|
internal override async UniTask ComputeKeysAsync(TElement[] elements, int count) |
|
{ |
|
keys = new TKey[count]; |
|
for (int i = 0; i < count; i++) keys[i] = await keySelector(elements[i]); |
|
if (next != null) await next.ComputeKeysAsync(elements, count); |
|
} |
|
|
|
internal override int CompareKeys(int index1, int index2) |
|
{ |
|
int c = comparer.Compare(keys[index1], keys[index2]); |
|
if (c == 0) |
|
{ |
|
if (next == null) return index1 - index2; |
|
return next.CompareKeys(index1, index2); |
|
} |
|
return descending ? -c : c; |
|
} |
|
} |
|
|
|
internal class AsyncSelectorWithCancellationEnumerableSorter<TElement, TKey> : AsyncEnumerableSorter<TElement> |
|
{ |
|
readonly Func<TElement, CancellationToken, UniTask<TKey>> keySelector; |
|
readonly IComparer<TKey> comparer; |
|
readonly bool descending; |
|
readonly AsyncEnumerableSorter<TElement> next; |
|
CancellationToken cancellationToken; |
|
TKey[] keys; |
|
|
|
internal AsyncSelectorWithCancellationEnumerableSorter(Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken) |
|
{ |
|
this.keySelector = keySelector; |
|
this.comparer = comparer; |
|
this.descending = descending; |
|
this.next = next; |
|
this.cancellationToken = cancellationToken; |
|
} |
|
|
|
internal override async UniTask ComputeKeysAsync(TElement[] elements, int count) |
|
{ |
|
keys = new TKey[count]; |
|
for (int i = 0; i < count; i++) keys[i] = await keySelector(elements[i], cancellationToken); |
|
if (next != null) await next.ComputeKeysAsync(elements, count); |
|
} |
|
|
|
internal override int CompareKeys(int index1, int index2) |
|
{ |
|
int c = comparer.Compare(keys[index1], keys[index2]); |
|
if (c == 0) |
|
{ |
|
if (next == null) return index1 - index2; |
|
return next.CompareKeys(index1, index2); |
|
} |
|
return descending ? -c : c; |
|
} |
|
} |
|
|
|
internal abstract class OrderedAsyncEnumerable<TElement> : IUniTaskOrderedAsyncEnumerable<TElement> |
|
{ |
|
protected readonly IUniTaskAsyncEnumerable<TElement> source; |
|
|
|
public OrderedAsyncEnumerable(IUniTaskAsyncEnumerable<TElement> source) |
|
{ |
|
this.source = source; |
|
} |
|
|
|
public IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending) |
|
{ |
|
return new OrderedAsyncEnumerable<TElement, TKey>(source, keySelector, comparer, descending, this); |
|
} |
|
|
|
public IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending) |
|
{ |
|
return new OrderedAsyncEnumerableAwait<TElement, TKey>(source, keySelector, comparer, descending, this); |
|
} |
|
|
|
public IUniTaskOrderedAsyncEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending) |
|
{ |
|
return new OrderedAsyncEnumerableAwaitWithCancellation<TElement, TKey>(source, keySelector, comparer, descending, this); |
|
} |
|
|
|
internal abstract AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken); |
|
|
|
public IUniTaskAsyncEnumerator<TElement> GetAsyncEnumerator(CancellationToken cancellationToken = default) |
|
{ |
|
return new _OrderedAsyncEnumerator(this, cancellationToken); |
|
} |
|
|
|
class _OrderedAsyncEnumerator : MoveNextSource, IUniTaskAsyncEnumerator<TElement> |
|
{ |
|
protected readonly OrderedAsyncEnumerable<TElement> parent; |
|
CancellationToken cancellationToken; |
|
TElement[] buffer; |
|
int[] map; |
|
int index; |
|
|
|
public _OrderedAsyncEnumerator(OrderedAsyncEnumerable<TElement> parent, CancellationToken cancellationToken) |
|
{ |
|
this.parent = parent; |
|
this.cancellationToken = cancellationToken; |
|
TaskTracker.TrackActiveTask(this, 3); |
|
} |
|
|
|
public TElement Current { get; private set; } |
|
|
|
public UniTask<bool> MoveNextAsync() |
|
{ |
|
cancellationToken.ThrowIfCancellationRequested(); |
|
|
|
if (map == null) |
|
{ |
|
completionSource.Reset(); |
|
CreateSortSource().Forget(); |
|
return new UniTask<bool>(this, completionSource.Version); |
|
} |
|
|
|
if (index < buffer.Length) |
|
{ |
|
Current = buffer[map[index++]]; |
|
return CompletedTasks.True; |
|
} |
|
else |
|
{ |
|
return CompletedTasks.False; |
|
} |
|
} |
|
|
|
async UniTaskVoid CreateSortSource() |
|
{ |
|
try |
|
{ |
|
buffer = await parent.source.ToArrayAsync(); |
|
if (buffer.Length == 0) |
|
{ |
|
completionSource.TrySetResult(false); |
|
return; |
|
} |
|
|
|
var sorter = parent.GetAsyncEnumerableSorter(null, cancellationToken); |
|
map = await sorter.SortAsync(buffer, buffer.Length); |
|
sorter = null; |
|
|
|
// set first value |
|
Current = buffer[map[index++]]; |
|
} |
|
catch (Exception ex) |
|
{ |
|
completionSource.TrySetException(ex); |
|
return; |
|
} |
|
|
|
completionSource.TrySetResult(true); |
|
} |
|
|
|
public UniTask DisposeAsync() |
|
{ |
|
TaskTracker.RemoveTracking(this); |
|
return default; |
|
} |
|
} |
|
} |
|
|
|
internal class OrderedAsyncEnumerable<TElement, TKey> : OrderedAsyncEnumerable<TElement> |
|
{ |
|
readonly Func<TElement, TKey> keySelector; |
|
readonly IComparer<TKey> comparer; |
|
readonly bool descending; |
|
readonly OrderedAsyncEnumerable<TElement> parent; |
|
|
|
public OrderedAsyncEnumerable(IUniTaskAsyncEnumerable<TElement> source, Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending, OrderedAsyncEnumerable<TElement> parent) |
|
: base(source) |
|
{ |
|
this.keySelector = keySelector; |
|
this.comparer = comparer; |
|
this.descending = descending; |
|
this.parent = parent; |
|
} |
|
|
|
internal override AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken) |
|
{ |
|
AsyncEnumerableSorter<TElement> sorter = new SyncSelectorAsyncEnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next); |
|
if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken); |
|
return sorter; |
|
} |
|
} |
|
|
|
internal class OrderedAsyncEnumerableAwait<TElement, TKey> : OrderedAsyncEnumerable<TElement> |
|
{ |
|
readonly Func<TElement, UniTask<TKey>> keySelector; |
|
readonly IComparer<TKey> comparer; |
|
readonly bool descending; |
|
readonly OrderedAsyncEnumerable<TElement> parent; |
|
|
|
public OrderedAsyncEnumerableAwait(IUniTaskAsyncEnumerable<TElement> source, Func<TElement, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, OrderedAsyncEnumerable<TElement> parent) |
|
: base(source) |
|
{ |
|
this.keySelector = keySelector; |
|
this.comparer = comparer; |
|
this.descending = descending; |
|
this.parent = parent; |
|
} |
|
|
|
internal override AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken) |
|
{ |
|
AsyncEnumerableSorter<TElement> sorter = new AsyncSelectorEnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next); |
|
if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken); |
|
return sorter; |
|
} |
|
} |
|
|
|
internal class OrderedAsyncEnumerableAwaitWithCancellation<TElement, TKey> : OrderedAsyncEnumerable<TElement> |
|
{ |
|
readonly Func<TElement, CancellationToken, UniTask<TKey>> keySelector; |
|
readonly IComparer<TKey> comparer; |
|
readonly bool descending; |
|
readonly OrderedAsyncEnumerable<TElement> parent; |
|
|
|
public OrderedAsyncEnumerableAwaitWithCancellation(IUniTaskAsyncEnumerable<TElement> source, Func<TElement, CancellationToken, UniTask<TKey>> keySelector, IComparer<TKey> comparer, bool descending, OrderedAsyncEnumerable<TElement> parent) |
|
: base(source) |
|
{ |
|
this.keySelector = keySelector; |
|
this.comparer = comparer; |
|
this.descending = descending; |
|
this.parent = parent; |
|
} |
|
|
|
internal override AsyncEnumerableSorter<TElement> GetAsyncEnumerableSorter(AsyncEnumerableSorter<TElement> next, CancellationToken cancellationToken) |
|
{ |
|
AsyncEnumerableSorter<TElement> sorter = new AsyncSelectorWithCancellationEnumerableSorter<TElement, TKey>(keySelector, comparer, descending, next, cancellationToken); |
|
if (parent != null) sorter = parent.GetAsyncEnumerableSorter(sorter, cancellationToken); |
|
return sorter; |
|
} |
|
} |
|
} |