diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Interval.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Interval.cs deleted file mode 100644 index 8b9e529..0000000 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Interval.cs +++ /dev/null @@ -1,275 +0,0 @@ -using System; -using System.Threading; - -namespace Cysharp.Threading.Tasks.Linq -{ - public static partial class UniTaskAsyncEnumerable - { - public static IUniTaskAsyncEnumerable Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) - { - return new Timer(dueTime, null, updateTiming, ignoreTimeScale); - } - - public static IUniTaskAsyncEnumerable Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) - { - return new Timer(dueTime, period, updateTiming, ignoreTimeScale); - } - - public static IUniTaskAsyncEnumerable Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) - { - return new Timer(period, period, updateTiming, ignoreTimeScale); - } - - public static IUniTaskAsyncEnumerable TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) - { - return new TimerFrame(dueTimeFrameCount, null, updateTiming); - } - - public static IUniTaskAsyncEnumerable TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) - { - return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming); - } - - public static IUniTaskAsyncEnumerable IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) - { - return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming); - } - } - - internal class Timer : IUniTaskAsyncEnumerable - { - readonly PlayerLoopTiming updateTiming; - readonly TimeSpan dueTime; - readonly TimeSpan? period; - readonly bool ignoreTimeScale; - - public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale) - { - this.updateTiming = updateTiming; - this.dueTime = dueTime; - this.period = period; - this.ignoreTimeScale = ignoreTimeScale; - } - - public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) - { - return new Enumerator(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken); - } - - class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem - { - readonly float dueTime; - readonly float? period; - readonly PlayerLoopTiming updateTiming; - readonly bool ignoreTimeScale; - CancellationToken cancellationToken; - - float elapsed; - bool dueTimePhase; - bool disposed; - - public Enumerator(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken) - { - this.dueTime = (float)dueTime.TotalSeconds; - this.period = (period == null) ? null : (float?)period.Value.TotalSeconds; - - if (this.dueTime <= 0) this.dueTime = 0; - if (this.period != null) - { - if (this.period <= 0) this.period = 1; - } - - this.dueTimePhase = true; - this.updateTiming = updateTiming; - this.ignoreTimeScale = ignoreTimeScale; - 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; - } - - AddElapsed(); - if (dueTimePhase) - { - if (elapsed >= dueTime) - { - dueTimePhase = false; - elapsed = 0; - completionSource.TrySetResult(true); - } - } - else - { - if (period == null) - { - completionSource.TrySetResult(false); - return false; - } - - if (elapsed >= period) - { - elapsed = 0; - completionSource.TrySetResult(true); - } - } - - return true; - } - - void AddElapsed() - { - if (updateTiming == PlayerLoopTiming.FixedUpdate) - { - if (ignoreTimeScale) - { - elapsed += UnityEngine.Time.fixedUnscaledDeltaTime; - } - else - { - elapsed += UnityEngine.Time.fixedDeltaTime; - } - } - else - { - if (ignoreTimeScale) - { - elapsed += UnityEngine.Time.unscaledDeltaTime; - } - else - { - elapsed += UnityEngine.Time.deltaTime; - } - } - } - } - } - - internal class TimerFrame : IUniTaskAsyncEnumerable - { - readonly PlayerLoopTiming updateTiming; - readonly int dueTimeFrameCount; - readonly int? periodFrameCount; - - public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming) - { - this.updateTiming = updateTiming; - this.dueTimeFrameCount = dueTimeFrameCount; - this.periodFrameCount = periodFrameCount; - } - - public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) - { - return new Enumerator(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken); - } - - class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem - { - readonly int dueTimeFrameCount; - readonly int? periodFrameCount; - CancellationToken cancellationToken; - - int currentFrame; - bool dueTimePhase; - bool disposed; - - public Enumerator(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken) - { - if (dueTimeFrameCount <= 0) dueTimeFrameCount = 0; - if (periodFrameCount != null) - { - if (periodFrameCount <= 0) periodFrameCount = 1; - } - - this.dueTimePhase = true; - this.dueTimeFrameCount = dueTimeFrameCount; - this.periodFrameCount = periodFrameCount; - - 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; - } - - if (dueTimePhase) - { - if (currentFrame++ == dueTimeFrameCount) - { - dueTimePhase = false; - completionSource.TrySetResult(true); - currentFrame = -1; - } - } - else - { - if (periodFrameCount == null) - { - completionSource.TrySetResult(false); - return false; - } - - if (++currentFrame == periodFrameCount) - { - completionSource.TrySetResult(true); - currentFrame = 0; - } - } - - return true; - } - } - } -} \ No newline at end of file diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Interval.cs.meta b/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Interval.cs.meta deleted file mode 100644 index ffb5f6d..0000000 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Interval.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 14e8116614488eb43b1428191cef8fe5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs index 32993c1..0cf8539 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/Linq/UnityExtensions/Timer.cs @@ -1,76 +1,249 @@ -//using Cysharp.Threading.Tasks.Internal; -//using System; -//using System.Collections.Generic; -//using System.Threading; +using System; +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); -// } -// } +namespace Cysharp.Threading.Tasks.Linq +{ + public static partial class UniTaskAsyncEnumerable + { + public static IUniTaskAsyncEnumerable Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) + { + return new Timer(dueTime, null, updateTiming, ignoreTimeScale); + } -// internal class EveryUpdate : IUniTaskAsyncEnumerable -// { -// readonly PlayerLoopTiming updateTiming; + public static IUniTaskAsyncEnumerable Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) + { + return new Timer(dueTime, period, updateTiming, ignoreTimeScale); + } -// public EveryUpdate(PlayerLoopTiming updateTiming) -// { -// this.updateTiming = updateTiming; -// } + public static IUniTaskAsyncEnumerable Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false) + { + return new Timer(period, period, updateTiming, ignoreTimeScale); + } -// public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) -// { -// return new Enumerator(updateTiming, cancellationToken); -// } + public static IUniTaskAsyncEnumerable TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + return new TimerFrame(dueTimeFrameCount, null, updateTiming); + } -// class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem -// { -// readonly PlayerLoopTiming updateTiming; -// CancellationToken cancellationToken; + public static IUniTaskAsyncEnumerable TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming); + } -// bool disposed; + public static IUniTaskAsyncEnumerable IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update) + { + return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming); + } + } -// public Enumerator(PlayerLoopTiming updateTiming, CancellationToken cancellationToken) -// { -// this.updateTiming = updateTiming; + internal class Timer : IUniTaskAsyncEnumerable + { + readonly PlayerLoopTiming updateTiming; + readonly TimeSpan dueTime; + readonly TimeSpan? period; + readonly bool ignoreTimeScale; -// TaskTracker.TrackActiveTask(this, 2); -// PlayerLoopHelper.AddAction(updateTiming, this); -// } + public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale) + { + this.updateTiming = updateTiming; + this.dueTime = dueTime; + this.period = period; + this.ignoreTimeScale = ignoreTimeScale; + } -// public AsyncUnit Current => default; + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new Enumerator(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken); + } -// public UniTask MoveNextAsync() -// { -// return false instead of throw -// if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False; + class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly float dueTime; + readonly float? period; + readonly PlayerLoopTiming updateTiming; + readonly bool ignoreTimeScale; + CancellationToken cancellationToken; -// completionSource.Reset(); -// return new UniTask(this, completionSource.Version); -// } + float elapsed; + bool dueTimePhase; + bool disposed; -// public UniTask DisposeAsync() -// { -// if (!disposed) -// { -// disposed = true; -// TaskTracker.RemoveTracking(this); -// } -// return default; -// } + public Enumerator(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken) + { + this.dueTime = (float)dueTime.TotalSeconds; + this.period = (period == null) ? null : (float?)period.Value.TotalSeconds; -// public bool MoveNext() -// { -// if (disposed) return false; -// if (cancellationToken.IsCancellationRequested) return false; + if (this.dueTime <= 0) this.dueTime = 0; + if (this.period != null) + { + if (this.period <= 0) this.period = 1; + } -// completionSource.TrySetResult(true); -// return true; -// } -// } -// } -//} \ No newline at end of file + this.dueTimePhase = true; + this.updateTiming = updateTiming; + this.ignoreTimeScale = ignoreTimeScale; + 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; + } + + elapsed += (ignoreTimeScale) ? UnityEngine.Time.unscaledDeltaTime : UnityEngine.Time.deltaTime; + if (dueTimePhase) + { + if (elapsed >= dueTime) + { + dueTimePhase = false; + elapsed = 0; + completionSource.TrySetResult(true); + } + } + else + { + if (period == null) + { + completionSource.TrySetResult(false); + return false; + } + + if (elapsed >= period) + { + elapsed = 0; + completionSource.TrySetResult(true); + } + } + + return true; + } + } + } + + internal class TimerFrame : IUniTaskAsyncEnumerable + { + readonly PlayerLoopTiming updateTiming; + readonly int dueTimeFrameCount; + readonly int? periodFrameCount; + + public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming) + { + this.updateTiming = updateTiming; + this.dueTimeFrameCount = dueTimeFrameCount; + this.periodFrameCount = periodFrameCount; + } + + public IUniTaskAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = default) + { + return new Enumerator(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken); + } + + class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator, IPlayerLoopItem + { + readonly int dueTimeFrameCount; + readonly int? periodFrameCount; + CancellationToken cancellationToken; + + int currentFrame; + bool dueTimePhase; + bool disposed; + + public Enumerator(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken) + { + if (dueTimeFrameCount <= 0) dueTimeFrameCount = 0; + if (periodFrameCount != null) + { + if (periodFrameCount <= 0) periodFrameCount = 1; + } + + this.dueTimePhase = true; + this.dueTimeFrameCount = dueTimeFrameCount; + this.periodFrameCount = periodFrameCount; + + 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; + } + + if (dueTimePhase) + { + if (currentFrame++ == dueTimeFrameCount) + { + dueTimePhase = false; + completionSource.TrySetResult(true); + currentFrame = 0; + } + } + else + { + if (periodFrameCount == null) + { + completionSource.TrySetResult(false); + return false; + } + + if (++currentFrame == periodFrameCount) + { + completionSource.TrySetResult(true); + currentFrame = 0; + } + } + + return true; + } + } + } +} \ No newline at end of file diff --git a/src/UniTask/Assets/Scenes/SandboxMain.cs b/src/UniTask/Assets/Scenes/SandboxMain.cs index 64f3e25..ff96818 100644 --- a/src/UniTask/Assets/Scenes/SandboxMain.cs +++ b/src/UniTask/Assets/Scenes/SandboxMain.cs @@ -146,11 +146,12 @@ public class SandboxMain : MonoBehaviour //StartCoroutine(cor); - Debug.Log("E:" + DateTime.Now.ToString()); + // await UniTask.Yield(PlayerLoopTiming.EarlyUpdate); + Debug.Log("Start:" + Time.frameCount); - await UniTaskAsyncEnumerable.Timer(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5), PlayerLoopTiming.Update).ForEachAsync(_ => + await UniTaskAsyncEnumerable.TimerFrame(3, 5, PlayerLoopTiming.LastPostLateUpdate).ForEachAsync(_ => { - Debug.Log("Call:" + DateTime.Now.ToString()); + Debug.Log("Call:" + Time.frameCount); }, cancellationToken: this.GetCancellationTokenOnDestroy()); //try