using System; using System.Collections.Generic; using Cysharp.Threading.Tasks.Internal; namespace Cysharp.Threading.Tasks { /// /// Lightweight IProgress[T] factory. /// public static class Progress { public static IProgress Create(Action handler) { if (handler == null) return NullProgress.Instance; return new AnonymousProgress(handler); } public static IProgress CreateOnlyValueChanged(Action handler, IEqualityComparer comparer = null) { if (handler == null) return NullProgress.Instance; #if UNITY_2018_3_OR_NEWER return new OnlyValueChangedProgress(handler, comparer ?? UnityEqualityComparer.GetDefault()); #else return new OnlyValueChangedProgress(handler, comparer ?? EqualityComparer.Default); #endif } sealed class NullProgress : IProgress { public static readonly IProgress Instance = new NullProgress(); NullProgress() { } public void Report(T value) { } } sealed class AnonymousProgress : IProgress { readonly Action action; public AnonymousProgress(Action action) { this.action = action; } public void Report(T value) { action(value); } } sealed class OnlyValueChangedProgress : IProgress { readonly Action action; readonly IEqualityComparer comparer; bool isFirstCall; T latestValue; public OnlyValueChangedProgress(Action action, IEqualityComparer comparer) { this.action = action; this.comparer = comparer; this.isFirstCall = true; } public void Report(T value) { if (isFirstCall) { isFirstCall = false; } else if (comparer.Equals(value, latestValue)) { return; } latestValue = value; action(value); } } } }