using System.Threading; namespace Cysharp.Threading.Tasks.Linq { public static partial class UniTaskAsyncEnumerable { public static IUniTaskAsyncEnumerable EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) { return new EveryUpdate(updateTiming); } } internal class EveryUpdate : IUniTaskAsyncEnumerable { readonly PlayerLoopTiming updateTiming; public EveryUpdate(PlayerLoopTiming updateTiming) { this.updateTiming = updateTiming; } public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) { return new _EveryUpdate(updateTiming, cancellationToken); } class _EveryUpdate : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem { readonly PlayerLoopTiming updateTiming; CancellationToken cancellationToken; bool disposed; public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken) { this.updateTiming = updateTiming; this.cancellationToken = cancellationToken; TaskTracker.TrackActiveTask(this, 2); PlayerLoopHelper.AddAction(updateTiming, this); } public AsyncUnit Current => default; public UniTask MoveNextAsync() { // return false instead of throw if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False; completionSource.Reset(); return new UniTask(this, completionSource.Version); } public UniTask DisposeAsync() { if (!disposed) { disposed = true; TaskTracker.RemoveTracking(this); } return default; } public bool MoveNext() { if (disposed || cancellationToken.IsCancellationRequested) { completionSource.TrySetResult(false); return false; } completionSource.TrySetResult(true); return true; } } } }