mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-26 18:10:17 +00:00
Compare commits
2 Commits
dependabot
...
e4d9a0f620
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4d9a0f620 | ||
|
|
9c4bab6e0a |
@@ -118,6 +118,9 @@ namespace Cysharp.Threading.Tasks.Internal
|
|||||||
case PlayerLoopTiming.LastPostLateUpdate:
|
case PlayerLoopTiming.LastPostLateUpdate:
|
||||||
LastPostLateUpdate();
|
LastPostLateUpdate();
|
||||||
break;
|
break;
|
||||||
|
case PlayerLoopTiming.ManualUpdate:
|
||||||
|
ManualUpdate();
|
||||||
|
break;
|
||||||
#if UNITY_2020_2_OR_NEWER
|
#if UNITY_2020_2_OR_NEWER
|
||||||
case PlayerLoopTiming.TimeUpdate:
|
case PlayerLoopTiming.TimeUpdate:
|
||||||
TimeUpdate();
|
TimeUpdate();
|
||||||
@@ -148,6 +151,7 @@ namespace Cysharp.Threading.Tasks.Internal
|
|||||||
void LastPreLateUpdate() => RunCore();
|
void LastPreLateUpdate() => RunCore();
|
||||||
void PostLateUpdate() => RunCore();
|
void PostLateUpdate() => RunCore();
|
||||||
void LastPostLateUpdate() => RunCore();
|
void LastPostLateUpdate() => RunCore();
|
||||||
|
void ManualUpdate() => RunCore();
|
||||||
#if UNITY_2020_2_OR_NEWER
|
#if UNITY_2020_2_OR_NEWER
|
||||||
void TimeUpdate() => RunCore();
|
void TimeUpdate() => RunCore();
|
||||||
void LastTimeUpdate() => RunCore();
|
void LastTimeUpdate() => RunCore();
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
TimeUpdate = 14,
|
TimeUpdate = 14,
|
||||||
LastTimeUpdate = 15,
|
LastTimeUpdate = 15,
|
||||||
#endif
|
#endif
|
||||||
|
ManualUpdate = 16,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@@ -192,6 +193,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
static SynchronizationContext unitySynchronizationContext;
|
static SynchronizationContext unitySynchronizationContext;
|
||||||
static ContinuationQueue[] yielders;
|
static ContinuationQueue[] yielders;
|
||||||
static PlayerLoopRunner[] runners;
|
static PlayerLoopRunner[] runners;
|
||||||
|
static PlayerLoopRunner ManualRunner;
|
||||||
internal static bool IsEditorApplicationQuitting { get; private set; }
|
internal static bool IsEditorApplicationQuitting { get; private set; }
|
||||||
static PlayerLoopSystem[] InsertRunner(PlayerLoopSystem loopSystem,
|
static PlayerLoopSystem[] InsertRunner(PlayerLoopSystem loopSystem,
|
||||||
bool injectOnFirst,
|
bool injectOnFirst,
|
||||||
@@ -251,6 +253,10 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
public static void ManualUpdate()
|
||||||
|
{
|
||||||
|
ManualRunner.Run();
|
||||||
|
}
|
||||||
|
|
||||||
static PlayerLoopSystem[] RemoveRunner(PlayerLoopSystem loopSystem, Type loopRunnerYieldType, Type loopRunnerType)
|
static PlayerLoopSystem[] RemoveRunner(PlayerLoopSystem loopSystem, Type loopRunnerYieldType, Type loopRunnerType)
|
||||||
{
|
{
|
||||||
@@ -405,6 +411,8 @@ namespace Cysharp.Threading.Tasks
|
|||||||
runners = new PlayerLoopRunner[14];
|
runners = new PlayerLoopRunner[14];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ManualRunner = new PlayerLoopRunner(PlayerLoopTiming.ManualUpdate);
|
||||||
|
|
||||||
var copyList = playerLoop.subSystemList.ToArray();
|
var copyList = playerLoop.subSystemList.ToArray();
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
@@ -491,6 +499,11 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem action)
|
public static void AddAction(PlayerLoopTiming timing, IPlayerLoopItem action)
|
||||||
{
|
{
|
||||||
|
if ((int)timing == (int)PlayerLoopTiming.ManualUpdate)
|
||||||
|
{
|
||||||
|
ManualRunner.AddAction(action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
var runner = runners[(int)timing];
|
var runner = runners[(int)timing];
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,11 +16,14 @@ namespace Cysharp.Threading.Tasks
|
|||||||
/// <summary>Ignore timescale, use Time.unscaledDeltaTime.</summary>
|
/// <summary>Ignore timescale, use Time.unscaledDeltaTime.</summary>
|
||||||
UnscaledDeltaTime,
|
UnscaledDeltaTime,
|
||||||
/// <summary>use Stopwatch.GetTimestamp().</summary>
|
/// <summary>use Stopwatch.GetTimestamp().</summary>
|
||||||
Realtime
|
Realtime,
|
||||||
|
ManualTime
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial struct UniTask
|
public partial struct UniTask
|
||||||
{
|
{
|
||||||
|
public static float deltaTime;
|
||||||
|
public static int frameCount;
|
||||||
public static YieldAwaitable Yield()
|
public static YieldAwaitable Yield()
|
||||||
{
|
{
|
||||||
// optimized for single continuation
|
// optimized for single continuation
|
||||||
@@ -179,6 +182,10 @@ namespace Cysharp.Threading.Tasks
|
|||||||
|
|
||||||
switch (delayType)
|
switch (delayType)
|
||||||
{
|
{
|
||||||
|
case DelayType.ManualTime:
|
||||||
|
{
|
||||||
|
return new UniTask(DelayManualPromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
||||||
|
}
|
||||||
case DelayType.UnscaledDeltaTime:
|
case DelayType.UnscaledDeltaTime:
|
||||||
{
|
{
|
||||||
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
||||||
@@ -320,6 +327,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
CancellationToken cancellationToken;
|
CancellationToken cancellationToken;
|
||||||
CancellationTokenRegistration cancellationTokenRegistration;
|
CancellationTokenRegistration cancellationTokenRegistration;
|
||||||
bool cancelImmediately;
|
bool cancelImmediately;
|
||||||
|
PlayerLoopTiming timing = PlayerLoopTiming.Update;
|
||||||
|
|
||||||
NextFramePromise()
|
NextFramePromise()
|
||||||
{
|
{
|
||||||
@@ -337,8 +345,9 @@ namespace Cysharp.Threading.Tasks
|
|||||||
result = new NextFramePromise();
|
result = new NextFramePromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
result.frameCount = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
result.frameCount = PlayerLoopHelper.IsMainThread ?(timing == PlayerLoopTiming.ManualUpdate ? UniTask.frameCount : Time.frameCount) : -1;
|
||||||
result.cancellationToken = cancellationToken;
|
result.cancellationToken = cancellationToken;
|
||||||
|
result.timing = timing;
|
||||||
result.cancelImmediately = cancelImmediately;
|
result.cancelImmediately = cancelImmediately;
|
||||||
|
|
||||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||||
@@ -400,7 +409,7 @@ namespace Cysharp.Threading.Tasks
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frameCount == Time.frameCount)
|
if (frameCount == (timing == PlayerLoopTiming.ManualUpdate ? UniTask.frameCount : Time.frameCount))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -695,6 +704,138 @@ namespace Cysharp.Threading.Tasks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class DelayManualPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<DelayManualPromise>
|
||||||
|
{
|
||||||
|
static TaskPool<DelayManualPromise> pool;
|
||||||
|
DelayManualPromise nextNode;
|
||||||
|
public ref DelayManualPromise NextNode => ref nextNode;
|
||||||
|
|
||||||
|
static DelayManualPromise()
|
||||||
|
{
|
||||||
|
TaskPool.RegisterSizeGetter(typeof(DelayManualPromise), () => pool.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int initialFrame;
|
||||||
|
float delayTimeSpan;
|
||||||
|
float elapsed;
|
||||||
|
CancellationToken cancellationToken;
|
||||||
|
CancellationTokenRegistration cancellationTokenRegistration;
|
||||||
|
bool cancelImmediately;
|
||||||
|
|
||||||
|
UniTaskCompletionSourceCore<object> core;
|
||||||
|
|
||||||
|
DelayManualPromise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pool.TryPop(out var result))
|
||||||
|
{
|
||||||
|
result = new DelayManualPromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
result.elapsed = 0.0f;
|
||||||
|
result.delayTimeSpan = (float)delayTimeSpan.TotalSeconds;
|
||||||
|
result.cancellationToken = cancellationToken;
|
||||||
|
result.initialFrame = PlayerLoopHelper.IsMainThread ? frameCount : -1;
|
||||||
|
result.cancelImmediately = cancelImmediately;
|
||||||
|
|
||||||
|
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||||
|
{
|
||||||
|
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||||
|
{
|
||||||
|
var promise = (DelayManualPromise)state;
|
||||||
|
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||||
|
}, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskTracker.TrackActiveTask(result, 3);
|
||||||
|
|
||||||
|
PlayerLoopHelper.AddAction(timing, result);
|
||||||
|
|
||||||
|
token = result.core.Version;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetResult(short token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
core.GetResult(token);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||||
|
{
|
||||||
|
TryReturn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus GetStatus(short token)
|
||||||
|
{
|
||||||
|
return core.GetStatus(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus UnsafeGetStatus()
|
||||||
|
{
|
||||||
|
return core.UnsafeGetStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||||
|
{
|
||||||
|
core.OnCompleted(continuation, state, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
core.TrySetCanceled(cancellationToken);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elapsed == 0.0f)
|
||||||
|
{
|
||||||
|
if (initialFrame == Time.frameCount)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elapsed += Time.deltaTime;
|
||||||
|
if (elapsed >= delayTimeSpan)
|
||||||
|
{
|
||||||
|
core.TrySetResult(null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TryReturn()
|
||||||
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
|
core.Reset();
|
||||||
|
delayTimeSpan = default;
|
||||||
|
elapsed = default;
|
||||||
|
cancellationToken = default;
|
||||||
|
cancellationTokenRegistration.Dispose();
|
||||||
|
cancelImmediately = default;
|
||||||
|
return pool.TryPush(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sealed class DelayPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<DelayPromise>
|
sealed class DelayPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<DelayPromise>
|
||||||
{
|
{
|
||||||
static TaskPool<DelayPromise> pool;
|
static TaskPool<DelayPromise> pool;
|
||||||
|
|||||||
Reference in New Issue
Block a user