mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-15 11:30:09 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80704e489d | ||
|
|
3c0aa03643 | ||
|
|
37cd00d347 | ||
|
|
859c4d706f | ||
|
|
7289fe6e25 | ||
|
|
0c33977f5a | ||
|
|
4d4466e801 | ||
|
|
79330d7cdb | ||
|
|
680ce1098b | ||
|
|
2337d705ec | ||
|
|
d2880a818f | ||
|
|
86ea128bf4 | ||
|
|
a66f378622 | ||
|
|
265f88584b |
57
README.md
57
README.md
@@ -53,21 +53,33 @@ async UniTask<string> DemoAsync()
|
||||
{
|
||||
// You can await Unity's AsyncObject
|
||||
var asset = await Resources.LoadAsync<TextAsset>("foo");
|
||||
|
||||
var txt = (await UnityWebRequest.Get("https://...").SendWebRequest()).downloadHandler.text;
|
||||
await SceneManager.LoadSceneAsync("scene2");
|
||||
|
||||
// .WithCancellation enables Cancel, GetCancellationTokenOnDestroy synchornizes with lifetime of GameObject
|
||||
var asset2 = await Resources.LoadAsync<TextAsset>("foo").WithCancellation(this.GetCancellationTokenOnDestroy());
|
||||
var asset2 = await Resources.LoadAsync<TextAsset>("bar").WithCancellation(this.GetCancellationTokenOnDestroy());
|
||||
|
||||
// .ToUniTask accepts progress callback(and all options), Progress.Create is a lightweight alternative of IProgress<T>
|
||||
await SceneManager.LoadSceneAsync("scene2").ToUniTask(Progress.Create<float>(x => Debug.Log(x)));
|
||||
|
||||
var asset3 = await Resources.LoadAsync<TextAsset>("baz").ToUniTask(Progress.Create<float>(x => Debug.Log(x)));
|
||||
|
||||
// await frame-based operation like coroutine
|
||||
await UniTask.DelayFrame(100);
|
||||
|
||||
// replacement of WaitForSeconds/WaitForSecondsRealtime
|
||||
// replacement of yield return new WaitForSeconds/WaitForSecondsRealtime
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(10), ignoreTimeScale: false);
|
||||
|
||||
// replacement of WaitForEndOfFrame(or other timing like yield return null, yield return WaitForFixedUpdate)
|
||||
await UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate);
|
||||
// yield any playerloop timing(PreUpdate, Update, LateUpdate, etc...)
|
||||
await UniTask.Yield(PlayerLoopTiming.PreLateUpdate);
|
||||
|
||||
// replacement of yield return null
|
||||
await UniTask.Yield();
|
||||
await UniTask.NextFrame();
|
||||
|
||||
// replacement of WaitForEndOfFrame(same as UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate))
|
||||
await UniTask.WaitForEndOfFrame();
|
||||
|
||||
// replacement of yield return new WaitForFixedUpdate(same as UniTask.Yield(PlayerLoopTiming.FixedUpdate))
|
||||
await UniTask.WaitForFixedUpdate();
|
||||
|
||||
// replacement of yield return WaitUntil
|
||||
await UniTask.WaitUntil(() => isActive == false);
|
||||
@@ -81,9 +93,14 @@ async UniTask<string> DemoAsync()
|
||||
// You can await standard task
|
||||
await Task.Run(() => 100);
|
||||
|
||||
// Multithreading, run on ThreadPool under this code(use SwitchToMainThread, same as `ObserveOnMainThreadDispatcher`)
|
||||
// Multithreading, run on ThreadPool under this code
|
||||
await UniTask.SwitchToThreadPool();
|
||||
|
||||
/* work on ThreadPool */
|
||||
|
||||
// return to MainThread(same as `ObserveOnMainThread` in UniRx)
|
||||
await UniTask.SwitchToMainThread();
|
||||
|
||||
// get async webrequest
|
||||
async UniTask<string> GetTextAsync(UnityWebRequest req)
|
||||
{
|
||||
@@ -127,6 +144,8 @@ UniTask provides three pattern of extension methods.
|
||||
|
||||
`WithCancellation` is a simple version of `ToUniTask`, both returns `UniTask`. Details of cancellation, see: [Cancellation and Exception handling](#cancellation-and-exception-handling) section.
|
||||
|
||||
> Note: WithCancellation is returned from native timing of PlayerLoop but ToUniTask is returned from specified PlayerLoopTiming. Details of timing, see: [PlayerLoop](#playerloop) section.
|
||||
|
||||
The type of `UniTask` can use utility like `UniTask.WhenAll`, `UniTask.WhenAny`. It is like Task.WhenAll/WhenAny but return type is more useful, returns value tuple so can deconsrtuct each result and pass multiple type.
|
||||
|
||||
```csharp
|
||||
@@ -321,9 +340,15 @@ public enum PlayerLoopTiming
|
||||
|
||||
It indicates when to run, you can check [PlayerLoopList.md](https://gist.github.com/neuecc/bc3a1cfd4d74501ad057e49efcd7bdae) to Unity's default playerloop and injected UniTask's custom loop.
|
||||
|
||||
`PlayerLoopTiming.Update` is similar as `yield return null` in coroutine, but it is called before Update(Update is called on `ScriptRunBehaviourUpdate`, yield return null is called on `ScriptRunDelayedDynamicFrameRate`). If change timing to `PlayerLoopTiming.LastUpdate`, called after these Unity's update methods.
|
||||
`PlayerLoopTiming.Update` is similar as `yield return null` in coroutine, but it is called before Update(Update and uGUI events(button.onClick, etc...) are called on `ScriptRunBehaviourUpdate`, yield return null is called on `ScriptRunDelayedDynamicFrameRate`). `PlayerLoopTiming.FixedUpdate` is similar as `WaitForFixedUpdate`, `PlayerLoopTiming.LastPostLateUpdate` is similar as `WaitForEndOfFrame` in coroutine.
|
||||
|
||||
`PlayerLoopTiming.FixedUpdate` is similar as `WaitForFixedUpdate`, `PlayerLoopTiming.LastPostLateUpdate` is similar as `WaitForEndOfFrame` in coroutine.
|
||||
`yield return null` and `UniTask.Yield` is similar but different. `yield return null` always return next frame but `UniTask.Yield` return next called, that is, call `UniTask.Yield(PlayerLoopTiming.Update)` on `PreUpdate`, it returns same frame. `UniTask.NextFrame()` gurantees return next frame, this would be expected to behave exactly the same as `yield return null`.
|
||||
|
||||
> UniTask.Yield(without CancellationToken) is a special type, returns `YieldAwaitable` and run on YieldRunner. It is most lightweight and faster.
|
||||
|
||||
AsyncOperation is returned from native timing. For example, await `SceneManager.LoadSceneAsync` is returned from `EarlyUpdate.UpdatePreloading` and after called, loaded scene called from `EarlyUpdate.ScriptRunDelayedStartupFrame`. Also `await UnityWebRequest` is returned from `EarlyUpdate.ExecuteMainThreadJobs`.
|
||||
|
||||
In UniTask, await directly and `WithCancellation` use native timing, `ToUniTask` use specified timing. This is usually not a particular problem, but with `LoadSceneAsync`, causes different order of Start and continuation after await. so recommend not to use `LoadSceneAsync.ToUniTask`.
|
||||
|
||||
In stacktrace, you can check where is running in playerloop.
|
||||
|
||||
@@ -665,6 +690,8 @@ foreach (var (type, size) in TaskPool.GetCacheSizeInfo())
|
||||
}
|
||||
```
|
||||
|
||||
> In UnityEditor profiler shows allocation of compiler generated AsyncStateMachine but it only occurs in debug(development) build. C# Compiler generate AsyncStateMachine as class on Debug build and as struct on Release build. And also currently due to IL2CPP limitation, in IL2CPP build, UniTask do boxing AsyncStateMachine when needed so sometimes exists `one` allocation.
|
||||
|
||||
API References
|
||||
---
|
||||
UniTask's API References is hosted at [cysharp.github.io/UniTask](https://cysharp.github.io/UniTask/api/Cysharp.Threading.Tasks.html) by [DocFX](https://dotnet.github.io/docfx/) and [Cysharp/DocfXTemplate](https://github.com/Cysharp/DocfxTemplate).
|
||||
@@ -722,6 +749,16 @@ public class ZeroAllocAsyncAwaitInDotNetCore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UniTask does not return to original SynchronizationContext but you can use helper `ReturnToCurrentSynchronizationContext`.
|
||||
public ValueTask TestAsync()
|
||||
{
|
||||
await using (UniTask.ReturnToCurrentSynchronizationContext())
|
||||
{
|
||||
await UniTask.SwitchToThreadPool();
|
||||
// do anything..
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
.NET Core version is intended to allow users to use UniTask as an interface when sharing code with Unity (such as [Cysharp/MagicOnion](https://github.com/Cysharp/MagicOnion/)). .NET Core version of UniTask enables smooth code sharing.
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTaskMethodBuilder
|
||||
{
|
||||
internal IStateMachineRunnerPromise runnerPromise;
|
||||
IStateMachineRunnerPromise runnerPromise;
|
||||
Exception ex;
|
||||
|
||||
// 1. Static Create method.
|
||||
@@ -80,7 +80,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
AsyncUniTask<TStateMachine>.SetStateMachine(ref this, ref stateMachine);
|
||||
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runnerPromise.MoveNext);
|
||||
@@ -96,7 +96,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
AsyncUniTask<TStateMachine>.SetStateMachine(ref this, ref stateMachine);
|
||||
AsyncUniTask<TStateMachine>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
|
||||
@@ -138,7 +138,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTaskMethodBuilder<T>
|
||||
{
|
||||
internal IStateMachineRunnerPromise<T> runnerPromise;
|
||||
IStateMachineRunnerPromise<T> runnerPromise;
|
||||
Exception ex;
|
||||
T result;
|
||||
|
||||
@@ -211,7 +211,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref this, ref stateMachine);
|
||||
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runnerPromise.MoveNext);
|
||||
@@ -227,7 +227,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
if (runnerPromise == null)
|
||||
{
|
||||
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref this, ref stateMachine);
|
||||
AsyncUniTask<TStateMachine, T>.SetStateMachine(ref stateMachine, ref runnerPromise);
|
||||
}
|
||||
|
||||
awaiter.UnsafeOnCompleted(runnerPromise.MoveNext);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTaskVoidMethodBuilder
|
||||
{
|
||||
internal IStateMachineRunner runner;
|
||||
IStateMachineRunner runner;
|
||||
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
@@ -70,7 +70,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
if (runner == null)
|
||||
{
|
||||
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref this, ref stateMachine);
|
||||
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.MoveNext);
|
||||
@@ -86,7 +86,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
if (runner == null)
|
||||
{
|
||||
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref this, ref stateMachine);
|
||||
AsyncUniTaskVoid<TStateMachine>.SetStateMachine(ref stateMachine, ref runner);
|
||||
}
|
||||
|
||||
awaiter.UnsafeOnCompleted(runner.MoveNext);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
@@ -29,12 +30,26 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
void SetException(Exception exception);
|
||||
}
|
||||
|
||||
internal static class StateMachineUtility
|
||||
{
|
||||
public static int GetState(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
var info = stateMachine.GetType().GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)
|
||||
.First(x => x.Name.EndsWith("__state"));
|
||||
return (int)info.GetValue(stateMachine);
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class AsyncUniTaskVoid<TStateMachine> : IStateMachineRunner, ITaskPoolNode<AsyncUniTaskVoid<TStateMachine>>, IUniTaskSource
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
static TaskPool<AsyncUniTaskVoid<TStateMachine>> pool;
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
IAsyncStateMachine stateMachine; // unfortunatelly boxed to fix IL2CPP issue.
|
||||
#else
|
||||
TStateMachine stateMachine;
|
||||
#endif
|
||||
|
||||
public Action MoveNext { get; }
|
||||
|
||||
@@ -43,7 +58,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
MoveNext = Run;
|
||||
}
|
||||
|
||||
public static void SetStateMachine(ref AsyncUniTaskVoidMethodBuilder builder, ref TStateMachine stateMachine)
|
||||
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunner runnerFieldRef)
|
||||
{
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
@@ -51,7 +66,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
builder.runner = result; // set runner before copied.
|
||||
runnerFieldRef = result; // set runner before copied.
|
||||
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
|
||||
}
|
||||
|
||||
@@ -102,7 +117,11 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
static TaskPool<AsyncUniTask<TStateMachine>> pool;
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
IAsyncStateMachine stateMachine; // unfortunatelly boxed to fix IL2CPP issue.
|
||||
#else
|
||||
TStateMachine stateMachine;
|
||||
#endif
|
||||
|
||||
public Action MoveNext { get; }
|
||||
|
||||
@@ -113,7 +132,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
MoveNext = Run;
|
||||
}
|
||||
|
||||
public static void SetStateMachine(ref AsyncUniTaskMethodBuilder builder, ref TStateMachine stateMachine)
|
||||
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise runnerPromiseFieldRef)
|
||||
{
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
@@ -121,7 +140,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
builder.runnerPromise = result; // set runner before copied.
|
||||
runnerPromiseFieldRef = result; // set runner before copied.
|
||||
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
|
||||
}
|
||||
|
||||
@@ -213,7 +232,11 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
{
|
||||
static TaskPool<AsyncUniTask<TStateMachine, T>> pool;
|
||||
|
||||
#if ENABLE_IL2CPP
|
||||
IAsyncStateMachine stateMachine; // unfortunatelly boxed to fix IL2CPP issue.
|
||||
#else
|
||||
TStateMachine stateMachine;
|
||||
#endif
|
||||
|
||||
public Action MoveNext { get; }
|
||||
|
||||
@@ -224,7 +247,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
MoveNext = Run;
|
||||
}
|
||||
|
||||
public static void SetStateMachine(ref AsyncUniTaskMethodBuilder<T> builder, ref TStateMachine stateMachine)
|
||||
public static void SetStateMachine(ref TStateMachine stateMachine, ref IStateMachineRunnerPromise<T> runnerPromiseFieldRef)
|
||||
{
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
@@ -232,10 +255,13 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
}
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
builder.runnerPromise = result; // set runner before copied.
|
||||
runnerPromiseFieldRef = result; // set runner before copied.
|
||||
result.stateMachine = stateMachine; // copy struct StateMachine(in release build).
|
||||
|
||||
// UnityEngine.Debug.Log($"SetStateMachine State:" + StateMachineUtility.GetState(stateMachine));
|
||||
}
|
||||
|
||||
|
||||
public AsyncUniTask<TStateMachine, T> NextNode { get; set; }
|
||||
|
||||
static AsyncUniTask()
|
||||
@@ -255,6 +281,7 @@ namespace Cysharp.Threading.Tasks.CompilerServices
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void Run()
|
||||
{
|
||||
// UnityEngine.Debug.Log($"MoveNext State:" + StateMachineUtility.GetState(stateMachine));
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Cysharp.Threading.Tasks
|
||||
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken)
|
||||
{
|
||||
if (handle.IsDone) return UniTask.CompletedTask;
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask(AsyncOperationHandleWithCancellationSource.Create(handle, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -77,6 +77,132 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AsyncOperationHandleWithCancellationSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleWithCancellationSource>
|
||||
{
|
||||
static TaskPool<AsyncOperationHandleWithCancellationSource> pool;
|
||||
public AsyncOperationHandleWithCancellationSource NextNode { get; set; }
|
||||
|
||||
static AsyncOperationHandleWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleWithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperationHandle> continuationAction;
|
||||
AsyncOperationHandle handle;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
AsyncOperationHandleWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(AsyncOperationHandle handle, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncOperationHandleWithCancellationSource();
|
||||
}
|
||||
|
||||
result.handle = handle;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
handle.Completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperationHandle _)
|
||||
{
|
||||
handle.Completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
handle = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~AsyncOperationHandleWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AsyncOperationHandleConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource>
|
||||
{
|
||||
static TaskPool<AsyncOperationHandleConfiguredSource> pool;
|
||||
@@ -210,7 +336,7 @@ namespace Cysharp.Threading.Tasks
|
||||
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken)
|
||||
{
|
||||
if (handle.IsDone) return UniTask.FromResult(handle.Result);
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask<T>(AsyncOperationHandleWithCancellationSource<T>.Create(handle, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -265,6 +391,137 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AsyncOperationHandleWithCancellationSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleWithCancellationSource<T>>
|
||||
{
|
||||
static TaskPool<AsyncOperationHandleWithCancellationSource<T>> pool;
|
||||
public AsyncOperationHandleWithCancellationSource<T> NextNode { get; set; }
|
||||
|
||||
static AsyncOperationHandleWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleWithCancellationSource<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperationHandle<T>> continuationAction;
|
||||
AsyncOperationHandle<T> handle;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<T> core;
|
||||
|
||||
AsyncOperationHandleWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<T>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncOperationHandleWithCancellationSource<T>();
|
||||
}
|
||||
|
||||
result.handle = handle;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
handle.Completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperationHandle<T> _)
|
||||
{
|
||||
handle.Completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(handle.Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
handle = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~AsyncOperationHandleWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
|
||||
{
|
||||
static TaskPool<AsyncOperationHandleConfiguredSource<T>> pool;
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace Cysharp.Threading.Tasks.Internal
|
||||
}
|
||||
else
|
||||
{
|
||||
var fname = fi.FullName.Replace(Path.DirectorySeparatorChar, '/').Replace(Application.dataPath, "");
|
||||
var fname = fi.FullName.Replace(Path.DirectorySeparatorChar, '/').Replace(PlayerLoopHelper.ApplicationDataPath, "");
|
||||
var withAssetsPath = "Assets/" + fname;
|
||||
return "<a href=\"" + withAssetsPath + "\" line=\"" + line + "\">" + withAssetsPath + ":" + line + "</a>";
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
internal static async UniTask<TSource[]> ToArrayAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
|
||||
{
|
||||
// UnityEngine.Debug.Log("Called ToArray");
|
||||
|
||||
var pool = ArrayPool<TSource>.Shared;
|
||||
var array = pool.Rent(16);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
@@ -22,16 +23,34 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
{
|
||||
if (dueTimeFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount);
|
||||
}
|
||||
|
||||
return new TimerFrame(dueTimeFrameCount, null, updateTiming);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
{
|
||||
if (dueTimeFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount);
|
||||
}
|
||||
if (periodFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus periodFrameCount. periodFrameCount:" + dueTimeFrameCount);
|
||||
}
|
||||
|
||||
return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
{
|
||||
if (intervalFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus intervalFrameCount. intervalFrameCount:" + intervalFrameCount);
|
||||
}
|
||||
return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming);
|
||||
}
|
||||
}
|
||||
@@ -64,6 +83,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly bool ignoreTimeScale;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
int initialFrame;
|
||||
float elapsed;
|
||||
bool dueTimePhase;
|
||||
bool completed;
|
||||
@@ -80,6 +100,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
if (this.period <= 0) this.period = 1;
|
||||
}
|
||||
|
||||
this.initialFrame = Time.frameCount;
|
||||
this.dueTimePhase = true;
|
||||
this.updateTiming = updateTiming;
|
||||
this.ignoreTimeScale = ignoreTimeScale;
|
||||
@@ -119,9 +140,19 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return false;
|
||||
}
|
||||
|
||||
elapsed += (ignoreTimeScale) ? UnityEngine.Time.unscaledDeltaTime : UnityEngine.Time.deltaTime;
|
||||
if (dueTimePhase)
|
||||
{
|
||||
if (elapsed == 0)
|
||||
{
|
||||
// skip in initial frame.
|
||||
if (initialFrame == Time.frameCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
elapsed += (ignoreTimeScale) ? UnityEngine.Time.unscaledDeltaTime : UnityEngine.Time.deltaTime;
|
||||
|
||||
if (elapsed >= dueTime)
|
||||
{
|
||||
dueTimePhase = false;
|
||||
@@ -137,6 +168,8 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return false;
|
||||
}
|
||||
|
||||
elapsed += (ignoreTimeScale) ? UnityEngine.Time.unscaledDeltaTime : UnityEngine.Time.deltaTime;
|
||||
|
||||
if (elapsed >= period)
|
||||
{
|
||||
completionSource.TrySetResult(true);
|
||||
@@ -172,6 +205,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly int? periodFrameCount;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
int initialFrame;
|
||||
int currentFrame;
|
||||
bool dueTimePhase;
|
||||
bool completed;
|
||||
@@ -185,6 +219,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
if (periodFrameCount <= 0) periodFrameCount = 1;
|
||||
}
|
||||
|
||||
this.initialFrame = Time.frameCount;
|
||||
this.dueTimePhase = true;
|
||||
this.dueTimeFrameCount = dueTimeFrameCount;
|
||||
this.periodFrameCount = periodFrameCount;
|
||||
@@ -228,11 +263,30 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
if (dueTimePhase)
|
||||
{
|
||||
if (currentFrame++ >= dueTimeFrameCount)
|
||||
if (currentFrame == 0)
|
||||
{
|
||||
if (dueTimeFrameCount == 0)
|
||||
{
|
||||
dueTimePhase = false;
|
||||
completionSource.TrySetResult(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip in initial frame.
|
||||
if (initialFrame == Time.frameCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (++currentFrame >= dueTimeFrameCount)
|
||||
{
|
||||
dueTimePhase = false;
|
||||
completionSource.TrySetResult(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -92,8 +92,10 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static SynchronizationContext UnitySynchronizationContext => unitySynchronizationContetext;
|
||||
public static int MainThreadId => mainThreadId;
|
||||
internal static string ApplicationDataPath => applicationDataPath;
|
||||
|
||||
static int mainThreadId;
|
||||
static string applicationDataPath;
|
||||
static SynchronizationContext unitySynchronizationContetext;
|
||||
static ContinuationQueue[] yielders;
|
||||
static PlayerLoopRunner[] runners;
|
||||
@@ -177,6 +179,11 @@ namespace Cysharp.Threading.Tasks
|
||||
// capture default(unity) sync-context.
|
||||
unitySynchronizationContetext = SynchronizationContext.Current;
|
||||
mainThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
try
|
||||
{
|
||||
applicationDataPath = Application.dataPath;
|
||||
}
|
||||
catch { }
|
||||
|
||||
#if UNITY_EDITOR && UNITY_2019_3_OR_NEWER
|
||||
// When domain reload is disabled, re-initialization is required when entering play mode;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
@@ -21,6 +20,46 @@ namespace Cysharp.Threading.Tasks
|
||||
return new UniTask(YieldPromise.Create(timing, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similar as UniTask.Yield but guaranteed run on next frame.
|
||||
/// </summary>
|
||||
public static UniTask NextFrame(PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same as UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate).
|
||||
/// </summary>
|
||||
public static YieldAwaitable WaitForEndOfFrame()
|
||||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same as UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken).
|
||||
/// </summary>
|
||||
public static UniTask WaitForEndOfFrame(CancellationToken cancellationToken)
|
||||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same as UniTask.Yield(PlayerLoopTiming.FixedUpdate).
|
||||
/// </summary>
|
||||
public static YieldAwaitable WaitForFixedUpdate()
|
||||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.FixedUpdate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same as UniTask.Yield(PlayerLoopTiming.FixedUpdate, cancellationToken).
|
||||
/// </summary>
|
||||
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken)
|
||||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.FixedUpdate, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
if (delayFrameCount < 0)
|
||||
@@ -152,27 +191,25 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DelayFramePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<DelayFramePromise>
|
||||
sealed class NextFramePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<NextFramePromise>
|
||||
{
|
||||
static TaskPool<DelayFramePromise> pool;
|
||||
public DelayFramePromise NextNode { get; set; }
|
||||
static TaskPool<NextFramePromise> pool;
|
||||
public NextFramePromise NextNode { get; set; }
|
||||
|
||||
static DelayFramePromise()
|
||||
static NextFramePromise()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(DelayFramePromise), () => pool.Size);
|
||||
TaskPool.RegisterSizeGetter(typeof(NextFramePromise), () => pool.Size);
|
||||
}
|
||||
|
||||
int delayFrameCount;
|
||||
int frameCount;
|
||||
CancellationToken cancellationToken;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
int currentFrameCount;
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
DelayFramePromise()
|
||||
NextFramePromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -181,10 +218,10 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new DelayFramePromise();
|
||||
result = new NextFramePromise();
|
||||
}
|
||||
|
||||
result.delayFrameCount = delayFrameCount;
|
||||
result.frameCount = Time.frameCount;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
@@ -230,13 +267,133 @@ namespace Cysharp.Threading.Tasks
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentFrameCount == delayFrameCount)
|
||||
if (frameCount == Time.frameCount)
|
||||
{
|
||||
core.TrySetResult(null);
|
||||
return true;
|
||||
}
|
||||
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~NextFramePromise()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DelayFramePromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<DelayFramePromise>
|
||||
{
|
||||
static TaskPool<DelayFramePromise> pool;
|
||||
public DelayFramePromise NextNode { get; set; }
|
||||
|
||||
static DelayFramePromise()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(DelayFramePromise), () => pool.Size);
|
||||
}
|
||||
|
||||
int initialFrame;
|
||||
int delayFrameCount;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
int currentFrameCount;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
DelayFramePromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new DelayFramePromise();
|
||||
}
|
||||
|
||||
result.delayFrameCount = delayFrameCount;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.initialFrame = Time.frameCount;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
|
||||
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 (currentFrameCount == 0)
|
||||
{
|
||||
if (delayFrameCount == 0) // same as Yield
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
return false;
|
||||
}
|
||||
|
||||
// skip in initial frame.
|
||||
if (initialFrame == Time.frameCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (++currentFrameCount >= delayFrameCount)
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentFrameCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -269,6 +426,7 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskPool.RegisterSizeGetter(typeof(DelayPromise), () => pool.Size);
|
||||
}
|
||||
|
||||
int initialFrame;
|
||||
float delayFrameTimeSpan;
|
||||
float elapsed;
|
||||
CancellationToken cancellationToken;
|
||||
@@ -294,6 +452,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.elapsed = 0.0f;
|
||||
result.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.initialFrame = Time.frameCount;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -338,6 +497,14 @@ namespace Cysharp.Threading.Tasks
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elapsed == 0.0f)
|
||||
{
|
||||
if (initialFrame == Time.frameCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
elapsed += Time.deltaTime;
|
||||
if (elapsed >= delayFrameTimeSpan)
|
||||
{
|
||||
@@ -379,6 +546,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
float delayFrameTimeSpan;
|
||||
float elapsed;
|
||||
int initialFrame;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
@@ -401,6 +569,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.elapsed = 0.0f;
|
||||
result.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds;
|
||||
result.initialFrame = Time.frameCount;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
@@ -446,6 +615,14 @@ namespace Cysharp.Threading.Tasks
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elapsed == 0.0f)
|
||||
{
|
||||
if (initialFrame == Time.frameCount)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
if (elapsed >= delayFrameTimeSpan)
|
||||
{
|
||||
|
||||
@@ -621,9 +621,8 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
// throw exception on iterator (main)thread.
|
||||
// unfortunately unity test-runner can not handle throw exception on hand-write IEnumerator.MoveNext.
|
||||
UnityEngine.Debug.LogException(exception.SourceException);
|
||||
exception.Throw();
|
||||
return false;
|
||||
}
|
||||
|
||||
return !completed;
|
||||
@@ -692,9 +691,8 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (exception != null)
|
||||
{
|
||||
// throw exception on iterator (main)thread.
|
||||
// unfortunately unity test-runner can not handle throw exception on hand-write IEnumerator.MoveNext.
|
||||
UnityEngine.Debug.LogException(exception.SourceException);
|
||||
exception.Throw();
|
||||
return false;
|
||||
}
|
||||
|
||||
return !completed;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (asyncOperation.isDone) return UniTask.CompletedTask;
|
||||
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask(AsyncOperationWithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -75,7 +75,127 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncOperationConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationConfiguredSource>
|
||||
sealed class AsyncOperationWithCancellationSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationWithCancellationSource>
|
||||
{
|
||||
static TaskPool<AsyncOperationWithCancellationSource> pool;
|
||||
public AsyncOperationWithCancellationSource NextNode { get; set; }
|
||||
|
||||
static AsyncOperationWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationWithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperation> continuationAction;
|
||||
AsyncOperation asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
AsyncOperationWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(AsyncOperation asyncOperation, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncOperationWithCancellationSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~AsyncOperationWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AsyncOperationConfiguredSource : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<AsyncOperationConfiguredSource>
|
||||
{
|
||||
static TaskPool<AsyncOperationConfiguredSource> pool;
|
||||
public AsyncOperationConfiguredSource NextNode { get; set; }
|
||||
@@ -124,7 +244,6 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
@@ -133,6 +252,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
@@ -203,7 +323,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
|
||||
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityEngine.Object>(ResourceRequestWithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -257,7 +377,131 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
class ResourceRequestConfiguredSource : IUniTaskSource<UnityEngine.Object>, IPlayerLoopItem, ITaskPoolNode<ResourceRequestConfiguredSource>
|
||||
sealed class ResourceRequestWithCancellationSource : IUniTaskSource<UnityEngine.Object>, IPlayerLoopItem, ITaskPoolNode<ResourceRequestWithCancellationSource>
|
||||
{
|
||||
static TaskPool<ResourceRequestWithCancellationSource> pool;
|
||||
public ResourceRequestWithCancellationSource NextNode { get; set; }
|
||||
|
||||
static ResourceRequestWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(ResourceRequestWithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperation> continuationAction;
|
||||
ResourceRequest asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object> core;
|
||||
|
||||
ResourceRequestWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<UnityEngine.Object>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new ResourceRequestWithCancellationSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
}
|
||||
|
||||
public UnityEngine.Object GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~ResourceRequestWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class ResourceRequestConfiguredSource : IUniTaskSource<UnityEngine.Object>, IPlayerLoopItem, ITaskPoolNode<ResourceRequestConfiguredSource>
|
||||
{
|
||||
static TaskPool<ResourceRequestConfiguredSource> pool;
|
||||
public ResourceRequestConfiguredSource NextNode { get; set; }
|
||||
@@ -306,7 +550,6 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
@@ -390,7 +633,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.asset);
|
||||
return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityEngine.Object>(AssetBundleRequestWithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -444,7 +687,131 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
class AssetBundleRequestConfiguredSource : IUniTaskSource<UnityEngine.Object>, IPlayerLoopItem, ITaskPoolNode<AssetBundleRequestConfiguredSource>
|
||||
sealed class AssetBundleRequestWithCancellationSource : IUniTaskSource<UnityEngine.Object>, IPlayerLoopItem, ITaskPoolNode<AssetBundleRequestWithCancellationSource>
|
||||
{
|
||||
static TaskPool<AssetBundleRequestWithCancellationSource> pool;
|
||||
public AssetBundleRequestWithCancellationSource NextNode { get; set; }
|
||||
|
||||
static AssetBundleRequestWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AssetBundleRequestWithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperation> continuationAction;
|
||||
AssetBundleRequest asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object> core;
|
||||
|
||||
AssetBundleRequestWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<UnityEngine.Object>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AssetBundleRequestWithCancellationSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
}
|
||||
|
||||
public UnityEngine.Object GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~AssetBundleRequestWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AssetBundleRequestConfiguredSource : IUniTaskSource<UnityEngine.Object>, IPlayerLoopItem, ITaskPoolNode<AssetBundleRequestConfiguredSource>
|
||||
{
|
||||
static TaskPool<AssetBundleRequestConfiguredSource> pool;
|
||||
public AssetBundleRequestConfiguredSource NextNode { get; set; }
|
||||
@@ -545,11 +912,11 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -576,7 +943,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle);
|
||||
return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask<AssetBundle>(AssetBundleCreateRequestWithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -630,7 +997,131 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
class AssetBundleCreateRequestConfiguredSource : IUniTaskSource<AssetBundle>, IPlayerLoopItem, ITaskPoolNode<AssetBundleCreateRequestConfiguredSource>
|
||||
sealed class AssetBundleCreateRequestWithCancellationSource : IUniTaskSource<AssetBundle>, IPlayerLoopItem, ITaskPoolNode<AssetBundleCreateRequestWithCancellationSource>
|
||||
{
|
||||
static TaskPool<AssetBundleCreateRequestWithCancellationSource> pool;
|
||||
public AssetBundleCreateRequestWithCancellationSource NextNode { get; set; }
|
||||
|
||||
static AssetBundleCreateRequestWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AssetBundleCreateRequestWithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperation> continuationAction;
|
||||
AssetBundleCreateRequest asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AssetBundle> core;
|
||||
|
||||
AssetBundleCreateRequestWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<AssetBundle>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AssetBundleCreateRequestWithCancellationSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetResult(asyncOperation.assetBundle);
|
||||
}
|
||||
}
|
||||
|
||||
public AssetBundle GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~AssetBundleCreateRequestWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AssetBundleCreateRequestConfiguredSource : IUniTaskSource<AssetBundle>, IPlayerLoopItem, ITaskPoolNode<AssetBundleCreateRequestConfiguredSource>
|
||||
{
|
||||
static TaskPool<AssetBundleCreateRequestConfiguredSource> pool;
|
||||
public AssetBundleCreateRequestConfiguredSource NextNode { get; set; }
|
||||
@@ -731,11 +1222,11 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -763,7 +1254,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.webRequest);
|
||||
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationWithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
@@ -817,7 +1308,132 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
class UnityWebRequestAsyncOperationConfiguredSource : IUniTaskSource<UnityWebRequest>, IPlayerLoopItem, ITaskPoolNode<UnityWebRequestAsyncOperationConfiguredSource>
|
||||
sealed class UnityWebRequestAsyncOperationWithCancellationSource : IUniTaskSource<UnityWebRequest>, IPlayerLoopItem, ITaskPoolNode<UnityWebRequestAsyncOperationWithCancellationSource>
|
||||
{
|
||||
static TaskPool<UnityWebRequestAsyncOperationWithCancellationSource> pool;
|
||||
public UnityWebRequestAsyncOperationWithCancellationSource NextNode { get; set; }
|
||||
|
||||
static UnityWebRequestAsyncOperationWithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(UnityWebRequestAsyncOperationWithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperation> continuationAction;
|
||||
UnityWebRequestAsyncOperation asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityWebRequest> core;
|
||||
|
||||
UnityWebRequestAsyncOperationWithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<UnityWebRequest>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new UnityWebRequestAsyncOperationWithCancellationSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetResult(asyncOperation.webRequest);
|
||||
}
|
||||
}
|
||||
|
||||
public UnityWebRequest GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
asyncOperation.webRequest.Abort();
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~UnityWebRequestAsyncOperationWithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class UnityWebRequestAsyncOperationConfiguredSource : IUniTaskSource<UnityWebRequest>, IPlayerLoopItem, ITaskPoolNode<UnityWebRequestAsyncOperationConfiguredSource>
|
||||
{
|
||||
static TaskPool<UnityWebRequestAsyncOperationConfiguredSource> pool;
|
||||
public UnityWebRequestAsyncOperationConfiguredSource NextNode { get; set; }
|
||||
@@ -866,7 +1482,6 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
@@ -920,11 +1535,11 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Cysharp.Threading.Tasks
|
||||
<# if(t.returnType == "UnityWebRequest") { #>
|
||||
#if ENABLE_UNITYWEBREQUEST
|
||||
<# } #>
|
||||
#region <#= t.typeName #>
|
||||
#region <#= t.typeName #>
|
||||
|
||||
public static <#= t.typeName #>Awaiter GetAwaiter(this <#= t.typeName #> asyncOperation)
|
||||
{
|
||||
@@ -45,18 +45,18 @@ namespace Cysharp.Threading.Tasks
|
||||
return new <#= t.typeName #>Awaiter(asyncOperation);
|
||||
}
|
||||
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation)
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken)
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
|
||||
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, PlayerLoopTiming.Update, null, CancellationToken.None, out var token), token);
|
||||
if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>;
|
||||
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>WithCancellationSource.Create(asyncOperation, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> ConfigureAwait(this <#= t.typeName #> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellation = default(CancellationToken))
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
|
||||
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellation, out var token), token);
|
||||
if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>;
|
||||
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
}
|
||||
|
||||
public struct <#= t.typeName #>Awaiter : ICriticalNotifyCompletion
|
||||
@@ -106,14 +106,153 @@ namespace Cysharp.Threading.Tasks
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
||||
class <#= t.typeName #>ConfiguredSource : <#= ToIUniTaskSourceReturnType(t.returnType) #>, IPlayerLoopItem, IPromisePoolItem
|
||||
sealed class <#= t.typeName #>WithCancellationSource : <#= ToIUniTaskSourceReturnType(t.returnType) #>, IPlayerLoopItem, ITaskPoolNode<<#= t.typeName #>WithCancellationSource>
|
||||
{
|
||||
static readonly PromisePool<<#= t.typeName #>ConfiguredSource> pool = new PromisePool<<#= t.typeName #>ConfiguredSource>();
|
||||
static TaskPool<<#= t.typeName #>WithCancellationSource> pool;
|
||||
public <#= t.typeName #>WithCancellationSource NextNode { get; set; }
|
||||
|
||||
static <#= t.typeName #>WithCancellationSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(<#= t.typeName #>WithCancellationSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperation> continuationAction;
|
||||
<#= t.typeName #> asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<<#= IsVoid(t) ? "AsyncUnit" : t.returnType #>> core;
|
||||
|
||||
<#= t.typeName #>WithCancellationSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, CancellationToken cancellationToken, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<#= IsVoid(t) ? "" : $"<{t.returnType}>" #>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new <#= t.typeName #>WithCancellationSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, result);
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>);
|
||||
}
|
||||
}
|
||||
|
||||
public <#= t.returnType #> GetResult(short token)
|
||||
{
|
||||
<# if (!IsVoid(t)) { #>
|
||||
return core.GetResult(token);
|
||||
<# } else { #>
|
||||
core.GetResult(token);
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<# if (!IsVoid(t)) { #>
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
<# } #>
|
||||
|
||||
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 (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
<# if(t.returnType == "UnityWebRequest") { #>
|
||||
asyncOperation.webRequest.Abort();
|
||||
<# } #>
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~<#= t.typeName #>WithCancellationSource()
|
||||
{
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class <#= t.typeName #>ConfiguredSource : <#= ToIUniTaskSourceReturnType(t.returnType) #>, IPlayerLoopItem, ITaskPoolNode<<#= t.typeName #>ConfiguredSource>
|
||||
{
|
||||
static TaskPool<<#= t.typeName #>ConfiguredSource> pool;
|
||||
public <#= t.typeName #>ConfiguredSource NextNode { get; set; }
|
||||
|
||||
static <#= t.typeName #>ConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(<#= t.typeName #>ConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
<#= t.typeName #> asyncOperation;
|
||||
IProgress<float> progress;
|
||||
@@ -133,7 +272,10 @@ namespace Cysharp.Threading.Tasks
|
||||
return AutoResetUniTaskCompletionSource<#= IsVoid(t) ? "" : $"<{t.returnType}>" #>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
var result = pool.TryRent() ?? new <#= t.typeName #>ConfiguredSource();
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new <#= t.typeName #>ConfiguredSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
@@ -151,8 +293,6 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
try
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
|
||||
<# if (!IsVoid(t)) { #>
|
||||
return core.GetResult(token);
|
||||
<# } else { #>
|
||||
@@ -161,7 +301,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
pool.TryReturn(this);
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +331,9 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
<# if(t.returnType == "UnityWebRequest") { #>
|
||||
asyncOperation.webRequest.Abort();
|
||||
<# } #>
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
@@ -209,24 +352,26 @@ namespace Cysharp.Threading.Tasks
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
~<#= t.typeName #>ConfiguredSource()
|
||||
{
|
||||
if (pool.TryReturn(this))
|
||||
if (TryReturn())
|
||||
{
|
||||
GC.ReRegisterForFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# endregion
|
||||
#endregion
|
||||
<# if(t.returnType == "UnityWebRequest") { #>
|
||||
#endif
|
||||
<# } #>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "com.cysharp.unitask",
|
||||
"displayName": "UniTask",
|
||||
"version": "2.0.14",
|
||||
"version": "2.0.15",
|
||||
"unity": "2018.4",
|
||||
"description": "Provides an efficient async/await integration to Unity.",
|
||||
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
||||
|
||||
@@ -21,13 +21,15 @@ public class ExceptionExamples : MonoBehaviour
|
||||
|
||||
private void Start()
|
||||
{
|
||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
UnityEngine.Debug.Log("ExceptionScene, LoopType:" + PlayerLoopInfo.CurrentLoopType + ":" + Time.frameCount);
|
||||
|
||||
ThrowFromAsyncVoid();
|
||||
_ = ThrowFromTask();
|
||||
_ = ThrowFromUniTask();
|
||||
//TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||
|
||||
ThrowFromNonAsync();
|
||||
//ThrowFromAsyncVoid();
|
||||
//_ = ThrowFromTask();
|
||||
//_ = ThrowFromUniTask();
|
||||
|
||||
//ThrowFromNonAsync();
|
||||
}
|
||||
|
||||
private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
||||
|
||||
@@ -14,6 +14,7 @@ using UnityEngine;
|
||||
using UnityEngine.LowLevel;
|
||||
using UnityEngine.Networking;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
|
||||
// using DG.Tweening;
|
||||
@@ -265,11 +266,14 @@ public class SandboxMain : MonoBehaviour
|
||||
//var r = UniAsync("https://bing.com/", cts.Token);
|
||||
//cts.Cancel();
|
||||
//await r;
|
||||
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||
Debug.Log("UNIASYNC1 ");
|
||||
Debug.Log("SendWebRequestDone:" + PlayerLoopInfo.CurrentLoopType);
|
||||
|
||||
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||
Debug.Log("UNIASYNC2");
|
||||
|
||||
// var foo = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||
// foo.downloadHandler.text;
|
||||
//
|
||||
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest().WithCancellation(CancellationToken.None);
|
||||
Debug.Log("SendWebRequestWithCancellationDone:" + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -302,15 +306,207 @@ public class SandboxMain : MonoBehaviour
|
||||
return 10;
|
||||
}
|
||||
|
||||
async UniTask<int> Ex()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
//throw new Exception();
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(15));
|
||||
return 0;
|
||||
}
|
||||
|
||||
IEnumerator CoroutineRun()
|
||||
{
|
||||
UnityEngine.Debug.Log("Before Coroutine yield return null," + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
yield return null;
|
||||
UnityEngine.Debug.Log("After Coroutine yield return null," + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
|
||||
IEnumerator CoroutineRun2()
|
||||
{
|
||||
UnityEngine.Debug.Log("Before Coroutine yield return WaitForEndOfFrame," + Time.frameCount);
|
||||
yield return new WaitForEndOfFrame();
|
||||
UnityEngine.Debug.Log("After Coroutine yield return WaitForEndOfFrame," + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
yield return new WaitForEndOfFrame();
|
||||
UnityEngine.Debug.Log("Onemore After Coroutine yield return WaitForEndOfFrame," + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
|
||||
|
||||
async UniTaskVoid AsyncRun()
|
||||
{
|
||||
UnityEngine.Debug.Log("Before async Yield(default)," + Time.frameCount);
|
||||
await UniTask.Yield();
|
||||
UnityEngine.Debug.Log("After async Yield(default)," + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
|
||||
async UniTaskVoid AsyncLastUpdate()
|
||||
{
|
||||
UnityEngine.Debug.Log("Before async Yield(LastUpdate)," + Time.frameCount);
|
||||
await UniTask.Yield(PlayerLoopTiming.LastUpdate);
|
||||
UnityEngine.Debug.Log("After async Yield(LastUpdate)," + Time.frameCount);
|
||||
}
|
||||
|
||||
async UniTaskVoid AsyncLastLast()
|
||||
{
|
||||
UnityEngine.Debug.Log("Before async Yield(LastPostLateUpdate)," + Time.frameCount);
|
||||
await UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate);
|
||||
UnityEngine.Debug.Log("After async Yield(LastPostLateUpdate)," + Time.frameCount);
|
||||
}
|
||||
|
||||
async UniTaskVoid Yieldding()
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
StartCoroutine(CoroutineRun());
|
||||
}
|
||||
|
||||
async UniTaskVoid AsyncFixedUpdate()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
await UniTask.WaitForFixedUpdate();
|
||||
Debug.Log("Async:" + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator CoroutineFixedUpdate()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForFixedUpdate();
|
||||
Debug.Log("Coroutine:" + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
// Debug.Log("FixedUpdate:" + Time.frameCount + ", " + PlayerLoopInfo.CurrentLoopType);
|
||||
}
|
||||
|
||||
async UniTaskVoid DelayFrame3_Pre()
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
Debug.Log("Before framecount:" + Time.frameCount);
|
||||
await UniTask.DelayFrame(3);
|
||||
Debug.Log("After framecount:" + Time.frameCount);
|
||||
}
|
||||
|
||||
async UniTaskVoid DelayFrame3_Post()
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
Debug.Log("Before framecount:" + Time.frameCount);
|
||||
await UniTask.DelayFrame(3);
|
||||
Debug.Log("After framecount:" + Time.frameCount);
|
||||
}
|
||||
|
||||
async UniTask TestCoroutine()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
throw new Exception("foobarbaz");
|
||||
}
|
||||
|
||||
async UniTask DelayCheck()
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
Debug.Log("before");
|
||||
var t = UniTask.Delay(TimeSpan.FromSeconds(1), ignoreTimeScale: false);
|
||||
|
||||
await t;
|
||||
Debug.Log("after");
|
||||
}
|
||||
|
||||
private async UniTaskVoid ExecuteAsync()
|
||||
{
|
||||
Debug.Log("1");
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.TimerFrame(1).ToArrayAsync();
|
||||
}
|
||||
Debug.Log("------------------");
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.TimerFrame(1).ToArrayAsync();
|
||||
Debug.Log("2");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Start()
|
||||
{
|
||||
//_ = UniTask.Run(async () =>
|
||||
//{
|
||||
// var watch = System.Diagnostics.Stopwatch.StartNew();
|
||||
// await UniTask.Delay(new TimeSpan(0, 0, seconds: 10));
|
||||
// Debug.Log(watch.Elapsed);
|
||||
//});
|
||||
PlayerLoopInfo.Inject();
|
||||
|
||||
//_ = AsyncFixedUpdate();
|
||||
//StartCoroutine(CoroutineFixedUpdate());
|
||||
|
||||
//StartCoroutine(TestCoroutine().ToCoroutine());
|
||||
|
||||
// Application.logMessageReceived += Application_logMessageReceived;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
okButton.onClick.AddListener(UniTask.UnityAction(async () =>
|
||||
{
|
||||
_ = ExecuteAsync();
|
||||
|
||||
await UniTask.Yield();
|
||||
|
||||
//await DelayCheck();
|
||||
/*
|
||||
UnityEngine.Debug.Log("click:" + PlayerLoopInfo.CurrentLoopType);
|
||||
StartCoroutine(CoroutineRun());
|
||||
StartCoroutine(CoroutineRun2());
|
||||
_ = AsyncRun();
|
||||
_ = AsyncLastUpdate();
|
||||
_ = AsyncLastLast();
|
||||
*/
|
||||
//await UniTask.Yield();
|
||||
//_ = Test2();
|
||||
// EarlyUpdate.ExecuteMainThreadJobs
|
||||
// _ = Test2();
|
||||
|
||||
//var t = await Resources.LoadAsync<TextAsset>(Application.streamingAssetsPath + "test.txt");
|
||||
//Debug.Log("LoadEnd" + PlayerLoopInfo.CurrentLoopType + ", " + (t != null));
|
||||
//Debug.Log("LoadEnd" + PlayerLoopInfo.CurrentLoopType + ", " + ((TextAsset)t).text);
|
||||
|
||||
|
||||
//await UniTask.Yield(PlayerLoopTiming.LastUpdate);
|
||||
//UnityEngine.Debug.Log("after update:" + Time.frameCount);
|
||||
////await UniTask.NextFrame();
|
||||
////await UniTask.Yield();
|
||||
////UnityEngine.Debug.Log("after update nextframe:" + Time.frameCount);
|
||||
|
||||
//StartCoroutine(CoroutineRun2());
|
||||
////StartCoroutine(CoroutineRun());
|
||||
//UnityEngine.Debug.Log("FOO?");
|
||||
|
||||
//_ = DelayFrame3_Pre();
|
||||
//await UniTask.Yield();
|
||||
|
||||
}));
|
||||
|
||||
cancelButton.onClick.AddListener(UniTask.UnityAction(async () =>
|
||||
{
|
||||
_ = DelayFrame3_Post();
|
||||
await UniTask.Yield();
|
||||
|
||||
//await UniTask.Yield(PlayerLoopTiming.LastPreUpdate);
|
||||
//UnityEngine.Debug.Log("before update:" + Time.frameCount);
|
||||
//await UniTask.NextFrame();
|
||||
//await UniTask.Yield();
|
||||
//UnityEngine.Debug.Log("before update nextframe:" + Time.frameCount);
|
||||
|
||||
//StartCoroutine(CoroutineRun());
|
||||
|
||||
//UnityEngine.Debug.Log("click:" + PlayerLoopInfo.CurrentLoopType);
|
||||
//_ = Yieldding();
|
||||
|
||||
//var cts = new CancellationTokenSource();
|
||||
|
||||
//UnityEngine.Debug.Log("click:" + PlayerLoopInfo.CurrentLoopType + ":" + Time.frameCount);
|
||||
//var la = SceneManager.LoadSceneAsync("Scenes/ExceptionExamples").WithCancellation(cts.Token);
|
||||
////cts.Cancel();
|
||||
//await la;
|
||||
//UnityEngine.Debug.Log("End LoadSceneAsync" + PlayerLoopInfo.CurrentLoopType + ":" + Time.frameCount);
|
||||
}));
|
||||
|
||||
//return;
|
||||
//await UniTask.SwitchToMainThread();
|
||||
@@ -423,7 +619,7 @@ public class SandboxMain : MonoBehaviour
|
||||
|
||||
//okButton.onClick.AddListener(UniTask.UnityAction(async () => await UniTask.Yield()));
|
||||
|
||||
PlayerLoopInfo.Inject();
|
||||
|
||||
|
||||
//UpdateUniTask().Forget();
|
||||
|
||||
@@ -437,10 +633,16 @@ public class SandboxMain : MonoBehaviour
|
||||
//GameObject.Destroy(this.gameObject);
|
||||
|
||||
|
||||
SynchronizationContext.Current.Post(_ =>
|
||||
{
|
||||
//UnityEngine.Debug.Log("Post:" + PlayerLoopInfo.CurrentLoopType);
|
||||
}, null);
|
||||
}
|
||||
|
||||
private void Application_logMessageReceived2(string condition, string stackTrace, LogType type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private void Application_logMessageReceived1(string condition, string stackTrace, LogType type)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
async UniTaskVoid UpdateUniTask()
|
||||
|
||||
@@ -126,15 +126,15 @@ namespace Cysharp.Threading.TasksTests
|
||||
await ToaruCoroutineEnumerator(); // wait 5 frame:)
|
||||
});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator JobSystem() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var job = new MyJob() { loopCount = 999, inOut = new NativeArray<int>(1, Allocator.TempJob) };
|
||||
JobHandle.ScheduleBatchedJobs();
|
||||
await job.Schedule();
|
||||
job.inOut[0].Should().Be(999);
|
||||
job.inOut.Dispose();
|
||||
});
|
||||
//[UnityTest]
|
||||
//public IEnumerator JobSystem() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// var job = new MyJob() { loopCount = 999, inOut = new NativeArray<int>(1, Allocator.TempJob) };
|
||||
// JobHandle.ScheduleBatchedJobs();
|
||||
// await job.Schedule();
|
||||
// job.inOut[0].Should().Be(999);
|
||||
// job.inOut.Dispose();
|
||||
//});
|
||||
|
||||
class MyMyClass
|
||||
{
|
||||
@@ -197,7 +197,7 @@ namespace Cysharp.Threading.TasksTests
|
||||
//await UniTask.SwitchToThreadPool();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -269,7 +269,8 @@ namespace Cysharp.Threading.TasksTests
|
||||
var first = Time.frameCount;
|
||||
var canceled = await UniTask.DelayFrame(100, cancellationToken: cts.Token).SuppressCancellationThrow();
|
||||
|
||||
(Time.frameCount - first).Should().Be(11); // 10 frame canceled
|
||||
var r = (Time.frameCount - first);
|
||||
(9 < r && r < 11).Should().BeTrue();
|
||||
canceled.Should().Be(true);
|
||||
});
|
||||
|
||||
@@ -369,6 +370,24 @@ namespace Cysharp.Threading.TasksTests
|
||||
throw new Exception("MyException");
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NextFrame1() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.LastUpdate);
|
||||
var frame = Time.frameCount;
|
||||
await UniTask.NextFrame();
|
||||
Time.frameCount.Should().Be(frame + 1);
|
||||
});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NextFrame2() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
var frame = Time.frameCount;
|
||||
await UniTask.NextFrame();
|
||||
Time.frameCount.Should().Be(frame + 1);
|
||||
});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NestedEnumerator() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
|
||||
97
src/UniTask/Assets/Tests/CachelikeTest.cs
Normal file
97
src/UniTask/Assets/Tests/CachelikeTest.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Cysharp.Threading.TasksTests
|
||||
{
|
||||
public class Cachelike
|
||||
{
|
||||
[UnityTest]
|
||||
public IEnumerator Check() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
{
|
||||
var v = await CachedCheck("foo", 10);
|
||||
v.Should().Be(10);
|
||||
|
||||
var v2 = await CachedCheck("bar", 20);
|
||||
v2.Should().Be(20);
|
||||
|
||||
var v3 = await CachedCheck("baz", 30);
|
||||
v3.Should().Be(30);
|
||||
}
|
||||
{
|
||||
var v = await CachedCheck("foo", 10);
|
||||
v.Should().Be(10);
|
||||
|
||||
var v2 = await CachedCheck("bar", 20);
|
||||
v2.Should().Be(20);
|
||||
|
||||
var v3 = await CachedCheck("baz", 30);
|
||||
v3.Should().Be(30);
|
||||
}
|
||||
{
|
||||
var v = CachedCheck("foo", 10);
|
||||
var v2 = CachedCheck("bar", 20);
|
||||
var v3 = CachedCheck("baz", 30);
|
||||
|
||||
(await v).Should().Be(10);
|
||||
(await v2).Should().Be(20);
|
||||
(await v3).Should().Be(30);
|
||||
}
|
||||
{
|
||||
var v = CachedCheck("foo", 10, true);
|
||||
var v2 = CachedCheck("bar", 20, true);
|
||||
var v3 = CachedCheck("baz", 30, true);
|
||||
|
||||
(await v).Should().Be(10);
|
||||
(await v2).Should().Be(20);
|
||||
(await v3).Should().Be(30);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
static Dictionary<string, int> cacheDict = new Dictionary<string, int>();
|
||||
|
||||
async UniTask<int> CachedCheck(string cache, int value, bool yield = false)
|
||||
{
|
||||
if (!cacheDict.ContainsKey(cache))
|
||||
{
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
if (yield)
|
||||
{
|
||||
await UniTask.Yield();
|
||||
}
|
||||
|
||||
if (cacheDict.TryGetValue(cache, out var v))
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
cacheDict.Add(cache, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
11
src/UniTask/Assets/Tests/CachelikeTest.cs.meta
Normal file
11
src/UniTask/Assets/Tests/CachelikeTest.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 416e0e77b4408b0498792eb218ed2870
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
394
src/UniTask/Assets/Tests/DelayTest.cs
Normal file
394
src/UniTask/Assets/Tests/DelayTest.cs
Normal file
@@ -0,0 +1,394 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Cysharp.Threading.Tasks.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Cysharp.Threading.TasksTests
|
||||
{
|
||||
public class DelayTest
|
||||
{
|
||||
//[UnityTest]
|
||||
//public IEnumerator DelayFrame() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// for (int i = 1; i < 5; i++)
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
// var frameCount = Time.frameCount;
|
||||
// await UniTask.DelayFrame(i);
|
||||
// Time.frameCount.Should().Be(frameCount + i);
|
||||
// }
|
||||
|
||||
// for (int i = 1; i < 5; i++)
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// var frameCount = Time.frameCount;
|
||||
// await UniTask.DelayFrame(i);
|
||||
// Time.frameCount.Should().Be(frameCount + i);
|
||||
// }
|
||||
//});
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator DelayFrameZero() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
// var frameCount = Time.frameCount;
|
||||
// await UniTask.DelayFrame(0);
|
||||
// Time.frameCount.Should().Be(frameCount); // same frame
|
||||
// }
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// var frameCount = Time.frameCount;
|
||||
// await UniTask.DelayFrame(0);
|
||||
// Time.frameCount.Should().Be(frameCount + 1); // next frame
|
||||
// }
|
||||
//});
|
||||
|
||||
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator TimerFramePre() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(2, 3).Take(5).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
|
||||
// xs[0].Should().Be(initialFrame + 2);
|
||||
// xs[1].Should().Be(initialFrame + 2 + (3 * 1));
|
||||
// xs[2].Should().Be(initialFrame + 2 + (3 * 2));
|
||||
// xs[3].Should().Be(initialFrame + 2 + (3 * 3));
|
||||
// xs[4].Should().Be(initialFrame + 2 + (3 * 4));
|
||||
//});
|
||||
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator TimerFramePost() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(2, 3).Take(5).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
|
||||
// xs[0].Should().Be(initialFrame + 2);
|
||||
// xs[1].Should().Be(initialFrame + 2 + (3 * 1));
|
||||
// xs[2].Should().Be(initialFrame + 2 + (3 * 2));
|
||||
// xs[3].Should().Be(initialFrame + 2 + (3 * 3));
|
||||
// xs[4].Should().Be(initialFrame + 2 + (3 * 4));
|
||||
//});
|
||||
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator TimerFrameTest() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(0, 0).Take(5).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
|
||||
// xs[0].Should().Be(initialFrame);
|
||||
// xs[1].Should().Be(initialFrame + 1);
|
||||
// xs[2].Should().Be(initialFrame + 2);
|
||||
// xs[3].Should().Be(initialFrame + 3);
|
||||
// xs[4].Should().Be(initialFrame + 4);
|
||||
//});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator TimerFrameSinglePre2() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.TimerFrame(1).ToArrayAsync();
|
||||
}
|
||||
//Debug.Log("------------------");
|
||||
//{
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(1).ToArrayAsync();
|
||||
//}
|
||||
});
|
||||
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator TimerFrameSinglePre2() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// {
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await new MyTimerFrame(0, null)/*.Select(_ => Time.frameCount)*/.ToArrayAsync();
|
||||
// Debug.Log("OK 0 ------------------");
|
||||
// }
|
||||
// {
|
||||
// var xs = await new MyTimerFrame(1, null)/*.Select(_ =>
|
||||
// {
|
||||
// var t = Time.frameCount;
|
||||
// UnityEngine.Debug.Log("store frameCount:" + t);
|
||||
// return t;
|
||||
// })*/.ToArrayAsync();
|
||||
// }
|
||||
//});
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator TimerFrameSinglePre() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.Return(UniTask.Yield(PlayerLoopTiming.Update, CancellationToken.None))/*.Select(_ => Time.frameCount)*/.ToArrayAsync();
|
||||
// xs[0].Should().Be(initialFrame);
|
||||
// Debug.Log("OK 0 ------------------");
|
||||
// }
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
// var initialFrame = Time.frameCount;
|
||||
// Debug.Log("initialFrame:" + initialFrame);
|
||||
// var xs = await UniTaskAsyncEnumerable.Return(UniTask.Yield(PlayerLoopTiming.Update, CancellationToken.None))/*.Select(_ =>
|
||||
// {
|
||||
// var t = Time.frameCount;
|
||||
// UnityEngine.Debug.Log("store frameCount:" + t);
|
||||
// return t;
|
||||
// })*/.ToArrayAsync();
|
||||
// Debug.Log("xs len:" + xs.Length);
|
||||
// Debug.Log("xs[0]:" + xs[0]);
|
||||
|
||||
// xs[0].Should().Be(initialFrame + 1);
|
||||
// Debug.Log("OK 1");
|
||||
// }
|
||||
// {
|
||||
// //await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(2).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
// xs[0].Should().Be(initialFrame + 2);
|
||||
// Debug.Log("OK 2");
|
||||
// }
|
||||
//});
|
||||
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator TimerFrameSinglePost() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// {
|
||||
// //await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// //var initialFrame = Time.frameCount;
|
||||
// //var xs = await UniTaskAsyncEnumerable.TimerFrame(0).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
// //xs[0].Should().Be(initialFrame);
|
||||
// }
|
||||
// {
|
||||
// //await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(1).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
// xs[0].Should().Be(initialFrame + 1);
|
||||
// }
|
||||
// {
|
||||
// //await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// var initialFrame = Time.frameCount;
|
||||
// var xs = await UniTaskAsyncEnumerable.TimerFrame(2).Select(_ => Time.frameCount).ToArrayAsync();
|
||||
// xs[0].Should().Be(initialFrame + 2);
|
||||
// }
|
||||
//});
|
||||
|
||||
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator Timer() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// await UniTask.Yield(PlayerLoopTiming.PreUpdate);
|
||||
|
||||
// {
|
||||
// var initialSeconds = Time.realtimeSinceStartup;
|
||||
// var xs = await UniTaskAsyncEnumerable.Timer(TimeSpan.FromSeconds(2)).Select(_ => Time.realtimeSinceStartup).ToArrayAsync();
|
||||
|
||||
// Mathf.Approximately(initialSeconds, xs[0]).Should().BeFalse();
|
||||
// Debug.Log("Init:" + initialSeconds);
|
||||
// Debug.Log("After:" + xs[0]);
|
||||
// }
|
||||
//});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class DelayTest2
|
||||
{
|
||||
[UnityTest]
|
||||
public IEnumerator TimerFrameSinglePre2() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.TimerFrame(1).ToArrayAsync();
|
||||
}
|
||||
Debug.Log("------------------");
|
||||
{
|
||||
var xs = await UniTaskAsyncEnumerable.TimerFrame(1).ToArrayAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public class ThreadRunner
|
||||
{
|
||||
Thread thread;
|
||||
|
||||
public void Start(IPlayerLoopItem runner)
|
||||
{
|
||||
thread = new Thread(() =>
|
||||
{
|
||||
Thread.Sleep(30);
|
||||
while (runner.MoveNext())
|
||||
{
|
||||
Thread.Sleep(30);
|
||||
}
|
||||
});
|
||||
|
||||
thread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
internal class MyTimerFrame : IUniTaskAsyncEnumerable<AsyncUnit>
|
||||
{
|
||||
//readonly PlayerLoopTiming updateTiming;
|
||||
readonly int dueTimeFrameCount;
|
||||
readonly int? periodFrameCount;
|
||||
|
||||
public MyTimerFrame(int dueTimeFrameCount, int? periodFrameCount)
|
||||
{
|
||||
//this.updateTiming = updateTiming;
|
||||
this.dueTimeFrameCount = dueTimeFrameCount;
|
||||
this.periodFrameCount = periodFrameCount;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _TimerFrame(dueTimeFrameCount, periodFrameCount, cancellationToken);
|
||||
}
|
||||
|
||||
class _TimerFrame : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
|
||||
{
|
||||
readonly int dueTimeFrameCount;
|
||||
readonly int? periodFrameCount;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
int initialFrame;
|
||||
int currentFrame;
|
||||
bool dueTimePhase;
|
||||
bool completed;
|
||||
bool disposed;
|
||||
ThreadRunner runner;
|
||||
|
||||
public _TimerFrame(int dueTimeFrameCount, int? periodFrameCount, CancellationToken cancellationToken)
|
||||
{
|
||||
if (dueTimeFrameCount <= 0) dueTimeFrameCount = 0;
|
||||
if (periodFrameCount != null)
|
||||
{
|
||||
if (periodFrameCount <= 0) periodFrameCount = 1;
|
||||
}
|
||||
|
||||
//this.initialFrame = Time.frameCount;
|
||||
this.dueTimePhase = true;
|
||||
this.dueTimeFrameCount = dueTimeFrameCount;
|
||||
this.periodFrameCount = periodFrameCount;
|
||||
|
||||
//TaskTracker.TrackActiveTask(this, 2);
|
||||
//PlayerLoopHelper.AddAction(updateTiming, this);
|
||||
|
||||
runner = new ThreadRunner();
|
||||
runner.Start(this);
|
||||
}
|
||||
|
||||
public AsyncUnit Current => default;
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// return false instead of throw
|
||||
if (disposed || cancellationToken.IsCancellationRequested || completed) return default;
|
||||
|
||||
|
||||
// reset value here.
|
||||
this.currentFrame = 0;
|
||||
|
||||
completionSource.Reset();
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
public UniTask DisposeAsync()
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
disposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
UnityEngine.Debug.Log("Called MoveNext");
|
||||
if (disposed || cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
UnityEngine.Debug.Log("Disposing");
|
||||
completionSource.TrySetResult(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dueTimePhase)
|
||||
{
|
||||
UnityEngine.Debug.Log("In DueTime Phase");
|
||||
if (currentFrame == 0)
|
||||
{
|
||||
if (dueTimeFrameCount == 0)
|
||||
{
|
||||
dueTimePhase = false;
|
||||
completionSource.TrySetResult(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip in initial frame.
|
||||
/*
|
||||
UnityEngine.Debug.Log("(Init, frameConut)" + (initialFrame, Time.frameCount));
|
||||
if (initialFrame == Time.frameCount)
|
||||
{
|
||||
UnityEngine.Debug.Log("Skip Here");
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
UnityEngine.Debug.Log("Which Go?");
|
||||
if (++currentFrame >= dueTimeFrameCount)
|
||||
{
|
||||
UnityEngine.Debug.Log("END Go?");
|
||||
dueTimePhase = false;
|
||||
completionSource.TrySetResult(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.Log("NG Go?");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (periodFrameCount == null)
|
||||
{
|
||||
UnityEngine.Debug.Log("PERIOD");
|
||||
completed = true;
|
||||
completionSource.TrySetResult(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (++currentFrame >= periodFrameCount)
|
||||
{
|
||||
completionSource.TrySetResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
11
src/UniTask/Assets/Tests/DelayTest.cs.meta
Normal file
11
src/UniTask/Assets/Tests/DelayTest.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1376b93d9e1083a4a9b4081e08f3a7b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,400 +1,400 @@
|
||||
#if !(UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
//#if !(UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||||
//#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Scripting;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine.SceneManagement;
|
||||
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using UnityEngine.Networking;
|
||||
//using UnityEngine;
|
||||
//using System;
|
||||
//using System.Collections;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using UnityEngine.UI;
|
||||
//using UnityEngine.Scripting;
|
||||
//using Cysharp.Threading.Tasks;
|
||||
//using UnityEngine.SceneManagement;
|
||||
//#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
//using System.Threading.Tasks;
|
||||
//#endif
|
||||
//using UnityEngine.Networking;
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
using UnityEngine.Experimental.LowLevel;
|
||||
#else
|
||||
using UnityEngine.LowLevel;
|
||||
#endif
|
||||
//#if !UNITY_2019_3_OR_NEWER
|
||||
//using UnityEngine.Experimental.LowLevel;
|
||||
//#else
|
||||
//using UnityEngine.LowLevel;
|
||||
//#endif
|
||||
|
||||
#if !UNITY_WSA
|
||||
using Unity.Jobs;
|
||||
#endif
|
||||
using Unity.Collections;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
using FluentAssertions;
|
||||
//#if !UNITY_WSA
|
||||
//using Unity.Jobs;
|
||||
//#endif
|
||||
//using Unity.Collections;
|
||||
//using System.Threading;
|
||||
//using NUnit.Framework;
|
||||
//using UnityEngine.TestTools;
|
||||
//using FluentAssertions;
|
||||
|
||||
namespace Cysharp.Threading.TasksTests
|
||||
{
|
||||
public class AsyncTest
|
||||
{
|
||||
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
#if !UNITY_WSA
|
||||
//namespace Cysharp.Threading.TasksTests
|
||||
//{
|
||||
// public class AsyncTest
|
||||
// {
|
||||
//#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
//#if !UNITY_WSA
|
||||
|
||||
public struct MyJob : IJob
|
||||
{
|
||||
public int loopCount;
|
||||
public NativeArray<int> inOut;
|
||||
public int result;
|
||||
// public struct MyJob : IJob
|
||||
// {
|
||||
// public int loopCount;
|
||||
// public NativeArray<int> inOut;
|
||||
// public int result;
|
||||
|
||||
public void Execute()
|
||||
{
|
||||
result = 0;
|
||||
for (int i = 0; i < loopCount; i++)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
inOut[0] = result;
|
||||
}
|
||||
}
|
||||
// public void Execute()
|
||||
// {
|
||||
// result = 0;
|
||||
// for (int i = 0; i < loopCount; i++)
|
||||
// {
|
||||
// result++;
|
||||
// }
|
||||
// inOut[0] = result;
|
||||
// }
|
||||
// }
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator DelayAnd() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// [UnityTest]
|
||||
// public IEnumerator DelayAnd() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
|
||||
var time = Time.realtimeSinceStartup;
|
||||
// var time = Time.realtimeSinceStartup;
|
||||
|
||||
Time.timeScale = 0.5f;
|
||||
try
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(3));
|
||||
// Time.timeScale = 0.5f;
|
||||
// try
|
||||
// {
|
||||
// await UniTask.Delay(TimeSpan.FromSeconds(3));
|
||||
|
||||
var elapsed = Time.realtimeSinceStartup - time;
|
||||
((int)Math.Round(TimeSpan.FromSeconds(elapsed).TotalSeconds, MidpointRounding.ToEven)).Should().Be(6);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Time.timeScale = 1.0f;
|
||||
}
|
||||
});
|
||||
// var elapsed = Time.realtimeSinceStartup - time;
|
||||
// ((int)Math.Round(TimeSpan.FromSeconds(elapsed).TotalSeconds, MidpointRounding.ToEven)).Should().Be(6);
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// Time.timeScale = 1.0f;
|
||||
// }
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator DelayIgnore() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var time = Time.realtimeSinceStartup;
|
||||
// [UnityTest]
|
||||
// public IEnumerator DelayIgnore() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var time = Time.realtimeSinceStartup;
|
||||
|
||||
Time.timeScale = 0.5f;
|
||||
try
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(3), ignoreTimeScale: true);
|
||||
// Time.timeScale = 0.5f;
|
||||
// try
|
||||
// {
|
||||
// await UniTask.Delay(TimeSpan.FromSeconds(3), ignoreTimeScale: true);
|
||||
|
||||
var elapsed = Time.realtimeSinceStartup - time;
|
||||
((int)Math.Round(TimeSpan.FromSeconds(elapsed).TotalSeconds, MidpointRounding.ToEven)).Should().Be(3);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Time.timeScale = 1.0f;
|
||||
}
|
||||
});
|
||||
// var elapsed = Time.realtimeSinceStartup - time;
|
||||
// ((int)Math.Round(TimeSpan.FromSeconds(elapsed).TotalSeconds, MidpointRounding.ToEven)).Should().Be(3);
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// Time.timeScale = 1.0f;
|
||||
// }
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenAll() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var a = UniTask.FromResult(999);
|
||||
var b = UniTask.Yield(PlayerLoopTiming.Update, CancellationToken.None).AsAsyncUnitUniTask();
|
||||
var c = UniTask.DelayFrame(99).AsAsyncUnitUniTask();
|
||||
// [UnityTest]
|
||||
// public IEnumerator WhenAll() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var a = UniTask.FromResult(999);
|
||||
// var b = UniTask.Yield(PlayerLoopTiming.Update, CancellationToken.None).AsAsyncUnitUniTask();
|
||||
// var c = UniTask.DelayFrame(99).AsAsyncUnitUniTask();
|
||||
|
||||
var (a2, b2, c2) = await UniTask.WhenAll(a, b, c);
|
||||
a2.Should().Be(999);
|
||||
b2.Should().Be(AsyncUnit.Default);
|
||||
c2.Should().Be(AsyncUnit.Default);
|
||||
});
|
||||
// var (a2, b2, c2) = await UniTask.WhenAll(a, b, c);
|
||||
// a2.Should().Be(999);
|
||||
// b2.Should().Be(AsyncUnit.Default);
|
||||
// c2.Should().Be(AsyncUnit.Default);
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WhenAny() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var a = UniTask.FromResult(999);
|
||||
var b = UniTask.Yield(PlayerLoopTiming.Update, CancellationToken.None).AsAsyncUnitUniTask();
|
||||
var c = UniTask.DelayFrame(99).AsAsyncUnitUniTask();
|
||||
// [UnityTest]
|
||||
// public IEnumerator WhenAny() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var a = UniTask.FromResult(999);
|
||||
// var b = UniTask.Yield(PlayerLoopTiming.Update, CancellationToken.None).AsAsyncUnitUniTask();
|
||||
// var c = UniTask.DelayFrame(99).AsAsyncUnitUniTask();
|
||||
|
||||
var (win, a2, b2, c2) = await UniTask.WhenAny(a, b, c);
|
||||
win.Should().Be(0);
|
||||
a2.Should().Be(999);
|
||||
});
|
||||
// var (win, a2, b2, c2) = await UniTask.WhenAny(a, b, c);
|
||||
// win.Should().Be(0);
|
||||
// a2.Should().Be(999);
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator BothEnumeratorCheck() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
await ToaruCoroutineEnumerator(); // wait 5 frame:)
|
||||
});
|
||||
// [UnityTest]
|
||||
// public IEnumerator BothEnumeratorCheck() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// await ToaruCoroutineEnumerator(); // wait 5 frame:)
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator JobSystem() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var job = new MyJob() { loopCount = 999, inOut = new NativeArray<int>(1, Allocator.TempJob) };
|
||||
JobHandle.ScheduleBatchedJobs();
|
||||
await job.Schedule();
|
||||
job.inOut[0].Should().Be(999);
|
||||
job.inOut.Dispose();
|
||||
});
|
||||
// [UnityTest]
|
||||
// public IEnumerator JobSystem() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var job = new MyJob() { loopCount = 999, inOut = new NativeArray<int>(1, Allocator.TempJob) };
|
||||
// JobHandle.ScheduleBatchedJobs();
|
||||
// await job.Schedule();
|
||||
// job.inOut[0].Should().Be(999);
|
||||
// job.inOut.Dispose();
|
||||
// });
|
||||
|
||||
class MyMyClass
|
||||
{
|
||||
public int MyProperty { get; set; }
|
||||
}
|
||||
// class MyMyClass
|
||||
// {
|
||||
// public int MyProperty { get; set; }
|
||||
// }
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WaitUntil() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
bool t = false;
|
||||
// [UnityTest]
|
||||
// public IEnumerator WaitUntil() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// bool t = false;
|
||||
|
||||
await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
// await UniTask.Yield(PlayerLoopTiming.PostLateUpdate);
|
||||
|
||||
UniTask.DelayFrame(10,PlayerLoopTiming.PostLateUpdate).ContinueWith(() => t = true).Forget();
|
||||
// UniTask.DelayFrame(10,PlayerLoopTiming.PostLateUpdate).ContinueWith(() => t = true).Forget();
|
||||
|
||||
var startFrame = Time.frameCount;
|
||||
await UniTask.WaitUntil(() => t, PlayerLoopTiming.EarlyUpdate);
|
||||
// var startFrame = Time.frameCount;
|
||||
// await UniTask.WaitUntil(() => t, PlayerLoopTiming.EarlyUpdate);
|
||||
|
||||
var diff = Time.frameCount - startFrame;
|
||||
diff.Should().Be(11);
|
||||
});
|
||||
// var diff = Time.frameCount - startFrame;
|
||||
// diff.Should().Be(11);
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WaitWhile() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
bool t = true;
|
||||
// [UnityTest]
|
||||
// public IEnumerator WaitWhile() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// bool t = true;
|
||||
|
||||
UniTask.DelayFrame(10, PlayerLoopTiming.PostLateUpdate).ContinueWith(() => t = false).Forget();
|
||||
// UniTask.DelayFrame(10, PlayerLoopTiming.PostLateUpdate).ContinueWith(() => t = false).Forget();
|
||||
|
||||
var startFrame = Time.frameCount;
|
||||
await UniTask.WaitWhile(() => t, PlayerLoopTiming.EarlyUpdate);
|
||||
// var startFrame = Time.frameCount;
|
||||
// await UniTask.WaitWhile(() => t, PlayerLoopTiming.EarlyUpdate);
|
||||
|
||||
var diff = Time.frameCount - startFrame;
|
||||
diff.Should().Be(11);
|
||||
});
|
||||
// var diff = Time.frameCount - startFrame;
|
||||
// diff.Should().Be(11);
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator WaitUntilValueChanged() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var v = new MyMyClass { MyProperty = 99 };
|
||||
// [UnityTest]
|
||||
// public IEnumerator WaitUntilValueChanged() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var v = new MyMyClass { MyProperty = 99 };
|
||||
|
||||
UniTask.DelayFrame(10, PlayerLoopTiming.PostLateUpdate).ContinueWith(() => v.MyProperty = 1000).Forget();
|
||||
// UniTask.DelayFrame(10, PlayerLoopTiming.PostLateUpdate).ContinueWith(() => v.MyProperty = 1000).Forget();
|
||||
|
||||
var startFrame = Time.frameCount;
|
||||
await UniTask.WaitUntilValueChanged(v, x => x.MyProperty, PlayerLoopTiming.EarlyUpdate);
|
||||
// var startFrame = Time.frameCount;
|
||||
// await UniTask.WaitUntilValueChanged(v, x => x.MyProperty, PlayerLoopTiming.EarlyUpdate);
|
||||
|
||||
var diff = Time.frameCount - startFrame;
|
||||
diff.Should().Be(11);
|
||||
});
|
||||
// var diff = Time.frameCount - startFrame;
|
||||
// diff.Should().Be(11);
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator SwitchTo() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
await UniTask.Yield();
|
||||
// [UnityTest]
|
||||
// public IEnumerator SwitchTo() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// await UniTask.Yield();
|
||||
|
||||
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
// var currentThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
|
||||
|
||||
|
||||
await UniTask.SwitchToThreadPool();
|
||||
//await UniTask.SwitchToThreadPool();
|
||||
//await UniTask.SwitchToThreadPool();
|
||||
// await UniTask.SwitchToThreadPool();
|
||||
// //await UniTask.SwitchToThreadPool();
|
||||
// //await UniTask.SwitchToThreadPool();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var switchedThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
// var switchedThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
|
||||
|
||||
|
||||
currentThreadId.Should().NotBe(switchedThreadId);
|
||||
// currentThreadId.Should().NotBe(switchedThreadId);
|
||||
|
||||
|
||||
await UniTask.Yield();
|
||||
// await UniTask.Yield();
|
||||
|
||||
var switchedThreadId2 = Thread.CurrentThread.ManagedThreadId;
|
||||
// var switchedThreadId2 = Thread.CurrentThread.ManagedThreadId;
|
||||
|
||||
currentThreadId.Should().Be(switchedThreadId2);
|
||||
});
|
||||
// currentThreadId.Should().Be(switchedThreadId2);
|
||||
// });
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator ObservableConversion() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// var v = await Observable.Range(1, 10).ToUniTask();
|
||||
// v.Is(10);
|
||||
// //[UnityTest]
|
||||
// //public IEnumerator ObservableConversion() => UniTask.ToCoroutine(async () =>
|
||||
// //{
|
||||
// // var v = await Observable.Range(1, 10).ToUniTask();
|
||||
// // v.Is(10);
|
||||
|
||||
// v = await Observable.Range(1, 10).ToUniTask(useFirstValue: true);
|
||||
// v.Is(1);
|
||||
// // v = await Observable.Range(1, 10).ToUniTask(useFirstValue: true);
|
||||
// // v.Is(1);
|
||||
|
||||
// v = await UniTask.DelayFrame(10).ToObservable().ToTask();
|
||||
// v.Is(10);
|
||||
// // v = await UniTask.DelayFrame(10).ToObservable().ToTask();
|
||||
// // v.Is(10);
|
||||
|
||||
// v = await UniTask.FromResult(99).ToObservable();
|
||||
// v.Is(99);
|
||||
//});
|
||||
// // v = await UniTask.FromResult(99).ToObservable();
|
||||
// // v.Is(99);
|
||||
// //});
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator AwaitableReactiveProperty() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// var rp1 = new ReactiveProperty<int>(99);
|
||||
// //[UnityTest]
|
||||
// //public IEnumerator AwaitableReactiveProperty() => UniTask.ToCoroutine(async () =>
|
||||
// //{
|
||||
// // var rp1 = new ReactiveProperty<int>(99);
|
||||
|
||||
// UniTask.DelayFrame(100).ContinueWith(x => rp1.Value = x).Forget();
|
||||
// // UniTask.DelayFrame(100).ContinueWith(x => rp1.Value = x).Forget();
|
||||
|
||||
// await rp1;
|
||||
// // await rp1;
|
||||
|
||||
// rp1.Value.Is(100);
|
||||
// // rp1.Value.Is(100);
|
||||
|
||||
// // var delay2 = UniTask.DelayFrame(10);
|
||||
// // var (a, b ) = await UniTask.WhenAll(rp1.WaitUntilValueChangedAsync(), delay2);
|
||||
// // // var delay2 = UniTask.DelayFrame(10);
|
||||
// // // var (a, b ) = await UniTask.WhenAll(rp1.WaitUntilValueChangedAsync(), delay2);
|
||||
|
||||
//});
|
||||
// //});
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator AwaitableReactiveCommand() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// var rc = new ReactiveCommand<int>();
|
||||
// //[UnityTest]
|
||||
// //public IEnumerator AwaitableReactiveCommand() => UniTask.ToCoroutine(async () =>
|
||||
// //{
|
||||
// // var rc = new ReactiveCommand<int>();
|
||||
|
||||
// UniTask.DelayFrame(100).ContinueWith(x => rc.Execute(x)).Forget();
|
||||
// // UniTask.DelayFrame(100).ContinueWith(x => rc.Execute(x)).Forget();
|
||||
|
||||
// var v = await rc;
|
||||
// // var v = await rc;
|
||||
|
||||
// v.Is(100);
|
||||
//});
|
||||
// // v.Is(100);
|
||||
// //});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ExceptionlessCancellation() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
// [UnityTest]
|
||||
// public IEnumerator ExceptionlessCancellation() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var cts = new CancellationTokenSource();
|
||||
|
||||
UniTask.DelayFrame(10).ContinueWith(() => cts.Cancel()).Forget();
|
||||
// UniTask.DelayFrame(10).ContinueWith(() => cts.Cancel()).Forget();
|
||||
|
||||
var first = Time.frameCount;
|
||||
var canceled = await UniTask.DelayFrame(100, cancellationToken: cts.Token).SuppressCancellationThrow();
|
||||
// var first = Time.frameCount;
|
||||
// var canceled = await UniTask.DelayFrame(100, cancellationToken: cts.Token).SuppressCancellationThrow();
|
||||
|
||||
(Time.frameCount - first).Should().Be(11); // 10 frame canceled
|
||||
canceled.Should().Be(true);
|
||||
});
|
||||
// (Time.frameCount - first).Should().Be(11); // 10 frame canceled
|
||||
// canceled.Should().Be(true);
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ExceptionCancellation() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
// [UnityTest]
|
||||
// public IEnumerator ExceptionCancellation() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var cts = new CancellationTokenSource();
|
||||
|
||||
UniTask.DelayFrame(10).ContinueWith(() => cts.Cancel()).Forget();
|
||||
// UniTask.DelayFrame(10).ContinueWith(() => cts.Cancel()).Forget();
|
||||
|
||||
bool occur = false;
|
||||
try
|
||||
{
|
||||
await UniTask.DelayFrame(100, cancellationToken: cts.Token);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
occur = true;
|
||||
}
|
||||
occur.Should().BeTrue();
|
||||
});
|
||||
// bool occur = false;
|
||||
// try
|
||||
// {
|
||||
// await UniTask.DelayFrame(100, cancellationToken: cts.Token);
|
||||
// }
|
||||
// catch (OperationCanceledException)
|
||||
// {
|
||||
// occur = true;
|
||||
// }
|
||||
// occur.Should().BeTrue();
|
||||
// });
|
||||
|
||||
IEnumerator ToaruCoroutineEnumerator()
|
||||
{
|
||||
yield return null;
|
||||
yield return null;
|
||||
yield return null;
|
||||
yield return null;
|
||||
yield return null;
|
||||
}
|
||||
// IEnumerator ToaruCoroutineEnumerator()
|
||||
// {
|
||||
// yield return null;
|
||||
// yield return null;
|
||||
// yield return null;
|
||||
// yield return null;
|
||||
// yield return null;
|
||||
// }
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ExceptionUnobserved1() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
bool calledEx = false;
|
||||
Action<Exception> action = exx =>
|
||||
{
|
||||
calledEx = true;
|
||||
exx.Message.Should().Be("MyException");
|
||||
};
|
||||
// [UnityTest]
|
||||
// public IEnumerator ExceptionUnobserved1() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// bool calledEx = false;
|
||||
// Action<Exception> action = exx =>
|
||||
// {
|
||||
// calledEx = true;
|
||||
// exx.Message.Should().Be("MyException");
|
||||
// };
|
||||
|
||||
UniTaskScheduler.UnobservedTaskException += action;
|
||||
// UniTaskScheduler.UnobservedTaskException += action;
|
||||
|
||||
var ex = InException1();
|
||||
ex = default(UniTask);
|
||||
// var ex = InException1();
|
||||
// ex = default(UniTask);
|
||||
|
||||
await UniTask.DelayFrame(3);
|
||||
// await UniTask.DelayFrame(3);
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
// GC.Collect();
|
||||
// GC.WaitForPendingFinalizers();
|
||||
// GC.Collect();
|
||||
|
||||
await UniTask.DelayFrame(1);
|
||||
// await UniTask.DelayFrame(1);
|
||||
|
||||
calledEx.Should().BeTrue();
|
||||
// calledEx.Should().BeTrue();
|
||||
|
||||
UniTaskScheduler.UnobservedTaskException -= action;
|
||||
});
|
||||
// UniTaskScheduler.UnobservedTaskException -= action;
|
||||
// });
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator ExceptionUnobserved2() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
bool calledEx = false;
|
||||
Action<Exception> action = exx =>
|
||||
{
|
||||
calledEx = true;
|
||||
exx.Message.Should().Be("MyException");
|
||||
};
|
||||
// [UnityTest]
|
||||
// public IEnumerator ExceptionUnobserved2() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// bool calledEx = false;
|
||||
// Action<Exception> action = exx =>
|
||||
// {
|
||||
// calledEx = true;
|
||||
// exx.Message.Should().Be("MyException");
|
||||
// };
|
||||
|
||||
UniTaskScheduler.UnobservedTaskException += action;
|
||||
// UniTaskScheduler.UnobservedTaskException += action;
|
||||
|
||||
var ex = InException2();
|
||||
ex = default(UniTask<int>);
|
||||
// var ex = InException2();
|
||||
// ex = default(UniTask<int>);
|
||||
|
||||
await UniTask.DelayFrame(3);
|
||||
// await UniTask.DelayFrame(3);
|
||||
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
GC.Collect();
|
||||
// GC.Collect();
|
||||
// GC.WaitForPendingFinalizers();
|
||||
// GC.Collect();
|
||||
|
||||
await UniTask.DelayFrame(1);
|
||||
// await UniTask.DelayFrame(1);
|
||||
|
||||
calledEx.Should().BeTrue();
|
||||
// calledEx.Should().BeTrue();
|
||||
|
||||
UniTaskScheduler.UnobservedTaskException -= action;
|
||||
});
|
||||
// UniTaskScheduler.UnobservedTaskException -= action;
|
||||
// });
|
||||
|
||||
async UniTask InException1()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
throw new Exception("MyException");
|
||||
}
|
||||
// async UniTask InException1()
|
||||
// {
|
||||
// await UniTask.Yield();
|
||||
// throw new Exception("MyException");
|
||||
// }
|
||||
|
||||
async UniTask<int> InException2()
|
||||
{
|
||||
await UniTask.Yield();
|
||||
throw new Exception("MyException");
|
||||
}
|
||||
// async UniTask<int> InException2()
|
||||
// {
|
||||
// await UniTask.Yield();
|
||||
// throw new Exception("MyException");
|
||||
// }
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator NestedEnumerator() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var time = Time.realtimeSinceStartup;
|
||||
// [UnityTest]
|
||||
// public IEnumerator NestedEnumerator() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var time = Time.realtimeSinceStartup;
|
||||
|
||||
await ParentCoroutineEnumerator();
|
||||
// await ParentCoroutineEnumerator();
|
||||
|
||||
var elapsed = Time.realtimeSinceStartup - time;
|
||||
((int)Math.Round(TimeSpan.FromSeconds(elapsed).TotalSeconds, MidpointRounding.ToEven)).Should().Be(3);
|
||||
});
|
||||
// var elapsed = Time.realtimeSinceStartup - time;
|
||||
// ((int)Math.Round(TimeSpan.FromSeconds(elapsed).TotalSeconds, MidpointRounding.ToEven)).Should().Be(3);
|
||||
// });
|
||||
|
||||
IEnumerator ParentCoroutineEnumerator()
|
||||
{
|
||||
yield return ChildCoroutineEnumerator();
|
||||
}
|
||||
// IEnumerator ParentCoroutineEnumerator()
|
||||
// {
|
||||
// yield return ChildCoroutineEnumerator();
|
||||
// }
|
||||
|
||||
IEnumerator ChildCoroutineEnumerator()
|
||||
{
|
||||
yield return new WaitForSeconds(3);
|
||||
}
|
||||
// IEnumerator ChildCoroutineEnumerator()
|
||||
// {
|
||||
// yield return new WaitForSeconds(3);
|
||||
// }
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
//#endif
|
||||
// }
|
||||
//}
|
||||
|
||||
#endif
|
||||
//#endif
|
||||
@@ -1,95 +1,95 @@
|
||||
#if !(UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
//#if !(UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_5_0 || UNITY_5_1 || UNITY_5_2)
|
||||
//#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Scripting;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine.SceneManagement;
|
||||
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
using System.Threading.Tasks;
|
||||
#endif
|
||||
using UnityEngine.Networking;
|
||||
//using UnityEngine;
|
||||
//using System;
|
||||
//using System.Collections;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using UnityEngine.UI;
|
||||
//using UnityEngine.Scripting;
|
||||
//using Cysharp.Threading.Tasks;
|
||||
//using UnityEngine.SceneManagement;
|
||||
//#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
//using System.Threading.Tasks;
|
||||
//#endif
|
||||
//using UnityEngine.Networking;
|
||||
|
||||
#if !UNITY_2019_3_OR_NEWER
|
||||
using UnityEngine.Experimental.LowLevel;
|
||||
#else
|
||||
using UnityEngine.LowLevel;
|
||||
#endif
|
||||
//#if !UNITY_2019_3_OR_NEWER
|
||||
//using UnityEngine.Experimental.LowLevel;
|
||||
//#else
|
||||
//using UnityEngine.LowLevel;
|
||||
//#endif
|
||||
|
||||
#if !UNITY_WSA
|
||||
using Unity.Jobs;
|
||||
#endif
|
||||
using Unity.Collections;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
using FluentAssertions;
|
||||
//#if !UNITY_WSA
|
||||
//using Unity.Jobs;
|
||||
//#endif
|
||||
//using Unity.Collections;
|
||||
//using System.Threading;
|
||||
//using NUnit.Framework;
|
||||
//using UnityEngine.TestTools;
|
||||
//using FluentAssertions;
|
||||
|
||||
namespace Cysharp.Threading.TasksTests
|
||||
{
|
||||
public class RunTest
|
||||
{
|
||||
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
#if !UNITY_WSA
|
||||
//namespace Cysharp.Threading.TasksTests
|
||||
//{
|
||||
// public class RunTest
|
||||
// {
|
||||
//#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
//#if !UNITY_WSA
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator RunThread() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// var main = Thread.CurrentThread.ManagedThreadId;
|
||||
// var v = await UniTask.Run(() => { return System.Threading.Thread.CurrentThread.ManagedThreadId; }, false);
|
||||
// UnityEngine.Debug.Log("Ret Value is:" + v);
|
||||
// UnityEngine.Debug.Log("Run Here and id:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
|
||||
// //v.Should().Be(3);
|
||||
// main.Should().NotBe(Thread.CurrentThread.ManagedThreadId);
|
||||
//});
|
||||
// //[UnityTest]
|
||||
// //public IEnumerator RunThread() => UniTask.ToCoroutine(async () =>
|
||||
// //{
|
||||
// // var main = Thread.CurrentThread.ManagedThreadId;
|
||||
// // var v = await UniTask.Run(() => { return System.Threading.Thread.CurrentThread.ManagedThreadId; }, false);
|
||||
// // UnityEngine.Debug.Log("Ret Value is:" + v);
|
||||
// // UnityEngine.Debug.Log("Run Here and id:" + System.Threading.Thread.CurrentThread.ManagedThreadId);
|
||||
// // //v.Should().Be(3);
|
||||
// // main.Should().NotBe(Thread.CurrentThread.ManagedThreadId);
|
||||
// //});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator RunThreadConfigure() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var main = Thread.CurrentThread.ManagedThreadId;
|
||||
var v = await UniTask.Run(() => 3, true);
|
||||
v.Should().Be(3);
|
||||
main.Should().Be(Thread.CurrentThread.ManagedThreadId);
|
||||
});
|
||||
// [UnityTest]
|
||||
// public IEnumerator RunThreadConfigure() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var main = Thread.CurrentThread.ManagedThreadId;
|
||||
// var v = await UniTask.Run(() => 3, true);
|
||||
// v.Should().Be(3);
|
||||
// main.Should().Be(Thread.CurrentThread.ManagedThreadId);
|
||||
// });
|
||||
|
||||
//[UnityTest]
|
||||
//public IEnumerator RunThreadException() => UniTask.ToCoroutine(async () =>
|
||||
//{
|
||||
// var main = Thread.CurrentThread.ManagedThreadId;
|
||||
// try
|
||||
// {
|
||||
// await UniTask.Run<int>(() => throw new Exception(), false);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// main.Should().NotBe(Thread.CurrentThread.ManagedThreadId);
|
||||
// }
|
||||
//});
|
||||
// //[UnityTest]
|
||||
// //public IEnumerator RunThreadException() => UniTask.ToCoroutine(async () =>
|
||||
// //{
|
||||
// // var main = Thread.CurrentThread.ManagedThreadId;
|
||||
// // try
|
||||
// // {
|
||||
// // await UniTask.Run<int>(() => throw new Exception(), false);
|
||||
// // }
|
||||
// // catch
|
||||
// // {
|
||||
// // main.Should().NotBe(Thread.CurrentThread.ManagedThreadId);
|
||||
// // }
|
||||
// //});
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator RunThreadExceptionConfigure() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var main = Thread.CurrentThread.ManagedThreadId;
|
||||
try
|
||||
{
|
||||
await UniTask.Run<int>(() => throw new Exception(), true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
main.Should().Be(Thread.CurrentThread.ManagedThreadId);
|
||||
}
|
||||
});
|
||||
// [UnityTest]
|
||||
// public IEnumerator RunThreadExceptionConfigure() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var main = Thread.CurrentThread.ManagedThreadId;
|
||||
// try
|
||||
// {
|
||||
// await UniTask.Run<int>(() => throw new Exception(), true);
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// main.Should().Be(Thread.CurrentThread.ManagedThreadId);
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
//#endif
|
||||
//#endif
|
||||
// }
|
||||
//}
|
||||
|
||||
#endif
|
||||
//#endif
|
||||
@@ -1,43 +1,43 @@
|
||||
#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
//#if CSHARP_7_OR_LATER || (UNITY_2018_3_OR_NEWER && (NET_STANDARD_2_0 || NET_4_6))
|
||||
//#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Scripting;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Unity.Collections;
|
||||
using System.Threading;
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.TestTools;
|
||||
using FluentAssertions;
|
||||
//using UnityEngine;
|
||||
//using System;
|
||||
//using System.Collections;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using System.Text;
|
||||
//using UnityEngine.UI;
|
||||
//using UnityEngine.Scripting;
|
||||
//using Cysharp.Threading.Tasks;
|
||||
//using Unity.Collections;
|
||||
//using System.Threading;
|
||||
//using NUnit.Framework;
|
||||
//using UnityEngine.TestTools;
|
||||
//using FluentAssertions;
|
||||
|
||||
namespace Cysharp.Threading.TasksTests
|
||||
{
|
||||
public class WhenAnyTest
|
||||
{
|
||||
[UnityTest]
|
||||
public IEnumerator WhenAnyCanceled() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
var cts = new CancellationTokenSource();
|
||||
var successDelayTask = UniTask.Delay(TimeSpan.FromSeconds(1));
|
||||
var cancelTask = UniTask.Delay(TimeSpan.FromSeconds(1), cancellationToken: cts.Token);
|
||||
cts.CancelAfterSlim(200);
|
||||
//namespace Cysharp.Threading.TasksTests
|
||||
//{
|
||||
// public class WhenAnyTest
|
||||
// {
|
||||
// [UnityTest]
|
||||
// public IEnumerator WhenAnyCanceled() => UniTask.ToCoroutine(async () =>
|
||||
// {
|
||||
// var cts = new CancellationTokenSource();
|
||||
// var successDelayTask = UniTask.Delay(TimeSpan.FromSeconds(1));
|
||||
// var cancelTask = UniTask.Delay(TimeSpan.FromSeconds(1), cancellationToken: cts.Token);
|
||||
// cts.CancelAfterSlim(200);
|
||||
|
||||
try
|
||||
{
|
||||
var r = await UniTask.WhenAny(new[] { successDelayTask, cancelTask });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.Should().BeAssignableTo<OperationCanceledException>();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// try
|
||||
// {
|
||||
// var r = await UniTask.WhenAny(new[] { successDelayTask, cancelTask });
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// ex.Should().BeAssignableTo<OperationCanceledException>();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//}
|
||||
|
||||
#endif
|
||||
//#endif
|
||||
@@ -6,13 +6,20 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
|
||||
namespace Cysharp.Threading.TasksTests
|
||||
{
|
||||
public class Preserve
|
||||
{
|
||||
public Preserve()
|
||||
{
|
||||
// TaskPool.SetMaxPoolSize(0);
|
||||
}
|
||||
|
||||
[UnityTest]
|
||||
public IEnumerator AwaitTwice() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
@@ -33,12 +40,17 @@ namespace Cysharp.Threading.TasksTests
|
||||
[UnityTest]
|
||||
public IEnumerator PreserveAllowTwice() => UniTask.ToCoroutine(async () =>
|
||||
{
|
||||
await UniTask.Yield(PlayerLoopTiming.Update);
|
||||
|
||||
var delay = UniTask.DelayFrame(5, PlayerLoopTiming.PostLateUpdate).Preserve();
|
||||
var before = UnityEngine.Time.frameCount;
|
||||
|
||||
var before = UnityEngine.Time.frameCount; // 0
|
||||
|
||||
await delay;
|
||||
var afterOne = UnityEngine.Time.frameCount;
|
||||
var afterOne = UnityEngine.Time.frameCount; // 5
|
||||
|
||||
await delay;
|
||||
var afterTwo = UnityEngine.Time.frameCount;
|
||||
var afterTwo = UnityEngine.Time.frameCount; // 5
|
||||
|
||||
(afterOne - before).Should().Be(5);
|
||||
afterOne.Should().Be(afterTwo);
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
"UnityEditor.TestRunner",
|
||||
"UniTask",
|
||||
"Unity.ResourceManager",
|
||||
"DOTween.Modules"
|
||||
"DOTween.Modules",
|
||||
"UniTask.Linq"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -8,7 +8,7 @@ EditorBuildSettings:
|
||||
- enabled: 1
|
||||
path: Assets/Scenes/SandboxMain.unity
|
||||
guid: 2cda990e2423bbf4892e6590ba056729
|
||||
- enabled: 0
|
||||
path:
|
||||
guid: 00000000000000000000000000000000
|
||||
- enabled: 1
|
||||
path: Assets/Scenes/ExceptionExamples.unity
|
||||
guid: b5fed17e3ece238439bc796d8747df5d
|
||||
m_configObjects: {}
|
||||
|
||||
Reference in New Issue
Block a user