using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Threading; namespace Cysharp.Threading.Tasks { public interface IUniTaskAsyncEnumerable { IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default); } public interface IUniTaskAsyncEnumerator : IUniTaskAsyncDisposable { T Current { get; } UniTask MoveNextAsync(); } public interface IUniTaskAsyncDisposable { UniTask DisposeAsync(); } public interface IUniTaskOrderedAsyncEnumerable : IUniTaskAsyncEnumerable { IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func keySelector, IComparer comparer, bool descending); IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func> keySelector, IComparer comparer, bool descending); IUniTaskOrderedAsyncEnumerable CreateOrderedEnumerable(Func> keySelector, IComparer comparer, bool descending); } public interface IConnectableUniTaskAsyncEnumerable : IUniTaskAsyncEnumerable { IDisposable Connect(); } // don't use AsyncGrouping. //public interface IUniTaskAsyncGrouping : IUniTaskAsyncEnumerable //{ // TKey Key { get; } //} public static class UniTaskAsyncEnumerableExtensions { public static UniTaskCancelableAsyncEnumerable WithCancellation(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) { return new UniTaskCancelableAsyncEnumerable(source, cancellationToken); } } [StructLayout(LayoutKind.Auto)] public readonly struct UniTaskCancelableAsyncEnumerable { private readonly IUniTaskAsyncEnumerable enumerable; private readonly CancellationToken cancellationToken; internal UniTaskCancelableAsyncEnumerable(IUniTaskAsyncEnumerable enumerable, CancellationToken cancellationToken) { this.enumerable = enumerable; this.cancellationToken = cancellationToken; } public Enumerator GetAsyncEnumerator() { return new Enumerator(enumerable.GetAsyncEnumerator(cancellationToken)); } [StructLayout(LayoutKind.Auto)] public readonly struct Enumerator { private readonly IUniTaskAsyncEnumerator enumerator; internal Enumerator(IUniTaskAsyncEnumerator enumerator) { this.enumerator = enumerator; } public T Current => enumerator.Current; public UniTask MoveNextAsync() { return enumerator.MoveNextAsync(); } public UniTask DisposeAsync() { return enumerator.DisposeAsync(); } } } }