Add EveryUpdate, Time, Interval, TimerFrame, IntervalFrame

pull/61/head
neuecc 2020-05-12 15:36:42 +09:00
parent 354fd65d58
commit 090cacece5
11 changed files with 477 additions and 4 deletions

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\UniTask\Assets\Plugins\UniTask\**\*.cs" Exclude="..\UniTask\Assets\Plugins\UniTask\Triggers\*.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;&#xD;&#xA; &#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\UnityEqualityComparer.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\DiagnosticsExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\PlayerLoopRunner.cs;&#xD;&#xA; &#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\CancellationTokenSourceExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\EnumeratorAsyncExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\PlayerLoopHelper.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Delay.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Run.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Bridge.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.WaitUntil.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.uGUI.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.MonoBehaviour.cs;&#xD;&#xA; " /> <Compile Include="..\UniTask\Assets\Plugins\UniTask\**\*.cs" Exclude="..\UniTask\Assets\Plugins\UniTask\Triggers\*.cs;..\UniTask\Assets\Plugins\UniTask\Linq\UnityExtensions\*.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;&#xD;&#xA; &#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\UnityEqualityComparer.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\DiagnosticsExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\PlayerLoopRunner.cs;&#xD;&#xA; &#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\CancellationTokenSourceExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\EnumeratorAsyncExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\PlayerLoopHelper.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Delay.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Run.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Bridge.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.WaitUntil.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.uGUI.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.MonoBehaviour.cs;&#xD;&#xA; " />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 669f5459819f7284ca1b35f4d55fe226
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,79 @@
using Cysharp.Threading.Tasks.Internal;
using System;
using System.Collections.Generic;
using System.Threading;
namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<AsyncUnit> EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
{
return new EveryUpdate(updateTiming);
}
}
internal class EveryUpdate : IUniTaskAsyncEnumerable<AsyncUnit>
{
readonly PlayerLoopTiming updateTiming;
public EveryUpdate(PlayerLoopTiming updateTiming)
{
this.updateTiming = updateTiming;
}
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(updateTiming, cancellationToken);
}
class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
{
readonly PlayerLoopTiming updateTiming;
CancellationToken cancellationToken;
bool disposed;
public Enumerator(PlayerLoopTiming updateTiming, CancellationToken cancellationToken)
{
this.updateTiming = updateTiming;
TaskTracker.TrackActiveTask(this, 2);
PlayerLoopHelper.AddAction(updateTiming, this);
}
public AsyncUnit Current => default;
public UniTask<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
completionSource.Reset();
return new UniTask<bool>(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;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 00520eb52e49b5b4e8d9870d6ff1aced
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,275 @@
using System;
using System.Threading;
namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
{
return new Timer(dueTime, null, updateTiming, ignoreTimeScale);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
{
return new Timer(dueTime, period, updateTiming, ignoreTimeScale);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
{
return new Timer(period, period, updateTiming, ignoreTimeScale);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
{
return new TimerFrame(dueTimeFrameCount, null, updateTiming);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
{
return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming);
}
public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
{
return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming);
}
}
internal class Timer : IUniTaskAsyncEnumerable<AsyncUnit>
{
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<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken);
}
class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, 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<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
completionSource.Reset();
return new UniTask<bool>(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<AsyncUnit>
{
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<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
return new Enumerator(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken);
}
class Enumerator : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, 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<bool> MoveNextAsync()
{
// return false instead of throw
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
completionSource.Reset();
return new UniTask<bool>(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;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14e8116614488eb43b1428191cef8fe5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 382caacde439855418709c641e4d7b04
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -146,10 +146,12 @@ public class SandboxMain : MonoBehaviour
//StartCoroutine(cor); //StartCoroutine(cor);
await okButton.OnClickAsAsyncEnumerable().Where((x, i) => i % 2 == 0).ForEachAsync(_ => Debug.Log("E:" + DateTime.Now.ToString());
await UniTaskAsyncEnumerable.Timer(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5), PlayerLoopTiming.Update).ForEachAsync(_ =>
{ {
Debug.Log("Call"); Debug.Log("Call:" + DateTime.Now.ToString());
}); }, cancellationToken: this.GetCancellationTokenOnDestroy());
//try //try
//{ //{