mirror of https://github.com/Cysharp/UniTask
remove legacy UniTask(occurs many compile error)
parent
86fa934510
commit
ef248e2e0a
|
@ -17,7 +17,7 @@ public class SandboxMain : MonoBehaviour
|
||||||
|
|
||||||
CancellationTokenSource cts;
|
CancellationTokenSource cts;
|
||||||
|
|
||||||
UniTaskCompletionSource2 ucs;
|
UniTaskCompletionSource ucs;
|
||||||
|
|
||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
|
@ -38,7 +38,7 @@ public class SandboxMain : MonoBehaviour
|
||||||
Application.logMessageReceived += Application_logMessageReceived;
|
Application.logMessageReceived += Application_logMessageReceived;
|
||||||
|
|
||||||
|
|
||||||
ucs = new UniTaskCompletionSource2();
|
ucs = new UniTaskCompletionSource();
|
||||||
|
|
||||||
okButton.onClick.AddListener(async () =>
|
okButton.onClick.AddListener(async () =>
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@ public class SandboxMain : MonoBehaviour
|
||||||
text.text += "\n" + condition;
|
text.text += "\n" + condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
async UniTask2 OuterAsync(bool b)
|
async UniTask OuterAsync(bool b)
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.Log("START OUTER");
|
UnityEngine.Debug.Log("START OUTER");
|
||||||
|
|
||||||
|
@ -72,14 +72,14 @@ public class SandboxMain : MonoBehaviour
|
||||||
// throw new InvalidOperationException("NAZO ERROR!?"); // error!?
|
// throw new InvalidOperationException("NAZO ERROR!?"); // error!?
|
||||||
}
|
}
|
||||||
|
|
||||||
async UniTask2 InnerAsync(bool b)
|
async UniTask InnerAsync(bool b)
|
||||||
{
|
{
|
||||||
if (b)
|
if (b)
|
||||||
{
|
{
|
||||||
UnityEngine.Debug.Log("Start delay:" + Time.frameCount);
|
UnityEngine.Debug.Log("Start delay:" + Time.frameCount);
|
||||||
await UniTask2.DelayFrame(60);
|
await UniTask.DelayFrame(60);
|
||||||
UnityEngine.Debug.Log("End delay:" + Time.frameCount);
|
UnityEngine.Debug.Log("End delay:" + Time.frameCount);
|
||||||
await UniTask2.DelayFrame(60);
|
await UniTask.DelayFrame(60);
|
||||||
UnityEngine.Debug.Log("Onemore end delay:" + Time.frameCount);
|
UnityEngine.Debug.Log("Onemore end delay:" + Time.frameCount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -10,274 +10,8 @@ using System.Security;
|
||||||
|
|
||||||
namespace UniRx.Async.CompilerServices
|
namespace UniRx.Async.CompilerServices
|
||||||
{
|
{
|
||||||
// TODO:Remove
|
|
||||||
public struct AsyncUniTaskMethodBuilder
|
|
||||||
{
|
|
||||||
UniTaskCompletionSource promise;
|
|
||||||
Action moveNext;
|
|
||||||
|
|
||||||
// 1. Static Create method.
|
|
||||||
[DebuggerHidden]
|
|
||||||
public static AsyncUniTaskMethodBuilder Create()
|
|
||||||
{
|
|
||||||
var builder = new AsyncUniTaskMethodBuilder();
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. TaskLike Task property.
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask Task
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (promise != null)
|
|
||||||
{
|
|
||||||
return promise.Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
return UniTask.CompletedTask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource();
|
|
||||||
return promise.Task;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. SetException
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void SetException(Exception exception)
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource();
|
|
||||||
}
|
|
||||||
if (exception is OperationCanceledException ex)
|
|
||||||
{
|
|
||||||
promise.TrySetCanceled(ex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
promise.TrySetException(exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. SetResult
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void SetResult()
|
|
||||||
{
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource();
|
|
||||||
}
|
|
||||||
promise.TrySetResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. AwaitOnCompleted
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
||||||
where TAwaiter : INotifyCompletion
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource(); // built future.
|
|
||||||
}
|
|
||||||
|
|
||||||
var runner = new MoveNextRunner<TStateMachine>();
|
|
||||||
moveNext = runner.Run;
|
|
||||||
runner.StateMachine = stateMachine; // set after create delegate.
|
|
||||||
}
|
|
||||||
|
|
||||||
awaiter.OnCompleted(moveNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. AwaitUnsafeOnCompleted
|
|
||||||
[DebuggerHidden]
|
|
||||||
[SecuritySafeCritical]
|
|
||||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
||||||
where TAwaiter : ICriticalNotifyCompletion
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource(); // built future.
|
|
||||||
}
|
|
||||||
|
|
||||||
var runner = new MoveNextRunner<TStateMachine>();
|
|
||||||
moveNext = runner.Run;
|
|
||||||
runner.StateMachine = stateMachine; // set after create delegate.
|
|
||||||
}
|
|
||||||
|
|
||||||
awaiter.UnsafeOnCompleted(moveNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Start
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
stateMachine.MoveNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. SetStateMachine
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:Remove
|
|
||||||
public struct AsyncUniTaskMethodBuilder<T>
|
|
||||||
{
|
|
||||||
T result;
|
|
||||||
UniTaskCompletionSource<T> promise;
|
|
||||||
Action moveNext;
|
|
||||||
|
|
||||||
// 1. Static Create method.
|
|
||||||
[DebuggerHidden]
|
|
||||||
public static AsyncUniTaskMethodBuilder<T> Create()
|
|
||||||
{
|
|
||||||
var builder = new AsyncUniTaskMethodBuilder<T>();
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. TaskLike Task property.
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask<T> Task
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (promise != null)
|
|
||||||
{
|
|
||||||
return new UniTask<T>(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
return new UniTask<T>(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource<T>();
|
|
||||||
return new UniTask<T>(promise);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. SetException
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void SetException(Exception exception)
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource<T>();
|
|
||||||
}
|
|
||||||
if (exception is OperationCanceledException ex)
|
|
||||||
{
|
|
||||||
promise.TrySetCanceled(ex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
promise.TrySetException(exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. SetResult
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void SetResult(T result)
|
|
||||||
{
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource<T>();
|
|
||||||
}
|
|
||||||
promise.TrySetResult(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. AwaitOnCompleted
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
||||||
where TAwaiter : INotifyCompletion
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource<T>(); // built future.
|
|
||||||
}
|
|
||||||
|
|
||||||
var runner = new MoveNextRunner<TStateMachine>();
|
|
||||||
moveNext = runner.Run;
|
|
||||||
runner.StateMachine = stateMachine; // set after create delegate.
|
|
||||||
}
|
|
||||||
|
|
||||||
awaiter.OnCompleted(moveNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. AwaitUnsafeOnCompleted
|
|
||||||
[DebuggerHidden]
|
|
||||||
[SecuritySafeCritical]
|
|
||||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
|
||||||
where TAwaiter : ICriticalNotifyCompletion
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
if (moveNext == null)
|
|
||||||
{
|
|
||||||
if (promise == null)
|
|
||||||
{
|
|
||||||
promise = new UniTaskCompletionSource<T>(); // built future.
|
|
||||||
}
|
|
||||||
|
|
||||||
var runner = new MoveNextRunner<TStateMachine>();
|
|
||||||
moveNext = runner.Run;
|
|
||||||
runner.StateMachine = stateMachine; // set after create delegate.
|
|
||||||
}
|
|
||||||
|
|
||||||
awaiter.UnsafeOnCompleted(moveNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Start
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
stateMachine.MoveNext();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. SetStateMachine
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Auto)]
|
[StructLayout(LayoutKind.Auto)]
|
||||||
public struct AsyncUniTask2MethodBuilder
|
public struct AsyncUniTaskMethodBuilder
|
||||||
{
|
{
|
||||||
// cache items.
|
// cache items.
|
||||||
AutoResetUniTaskCompletionSource promise;
|
AutoResetUniTaskCompletionSource promise;
|
||||||
|
@ -286,13 +20,13 @@ namespace UniRx.Async.CompilerServices
|
||||||
// 1. Static Create method.
|
// 1. Static Create method.
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static AsyncUniTask2MethodBuilder Create()
|
public static AsyncUniTaskMethodBuilder Create()
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. TaskLike Task property.
|
// 2. TaskLike Task property.
|
||||||
public UniTask2 Task
|
public UniTask Task
|
||||||
{
|
{
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -305,7 +39,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
|
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
return UniTask2.CompletedTask;
|
return UniTask.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = AutoResetUniTaskCompletionSource.Create();
|
promise = AutoResetUniTaskCompletionSource.Create();
|
||||||
|
@ -363,7 +97,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
}
|
}
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
awaiter.OnCompleted(runner.CallMoveNext);
|
awaiter.OnCompleted(runner.CallMoveNext);
|
||||||
|
@ -382,7 +116,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
}
|
}
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
awaiter.OnCompleted(runner.CallMoveNext);
|
awaiter.OnCompleted(runner.CallMoveNext);
|
||||||
|
@ -405,7 +139,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Auto)]
|
[StructLayout(LayoutKind.Auto)]
|
||||||
public struct AsyncUniTask2MethodBuilder<T>
|
public struct AsyncUniTaskMethodBuilder<T>
|
||||||
{
|
{
|
||||||
// cache items.
|
// cache items.
|
||||||
AutoResetUniTaskCompletionSource<T> promise;
|
AutoResetUniTaskCompletionSource<T> promise;
|
||||||
|
@ -415,14 +149,14 @@ namespace UniRx.Async.CompilerServices
|
||||||
// 1. Static Create method.
|
// 1. Static Create method.
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static AsyncUniTask2MethodBuilder<T> Create()
|
public static AsyncUniTaskMethodBuilder<T> Create()
|
||||||
{
|
{
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. TaskLike Task property.
|
// 2. TaskLike Task property.
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
public UniTask2<T> Task
|
public UniTask<T> Task
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -433,7 +167,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
|
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
return UniTask2.FromResult(result);
|
return UniTask.FromResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||||
|
@ -494,7 +228,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
}
|
}
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
awaiter.OnCompleted(runner.CallMoveNext);
|
awaiter.OnCompleted(runner.CallMoveNext);
|
||||||
|
@ -513,7 +247,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
}
|
}
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
awaiter.OnCompleted(runner.CallMoveNext);
|
awaiter.OnCompleted(runner.CallMoveNext);
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
{
|
{
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
awaiter.OnCompleted(runner.CallMoveNext);
|
awaiter.OnCompleted(runner.CallMoveNext);
|
||||||
|
@ -81,7 +81,7 @@ namespace UniRx.Async.CompilerServices
|
||||||
{
|
{
|
||||||
if (runner == null)
|
if (runner == null)
|
||||||
{
|
{
|
||||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
runner = MoveNextRunner<TStateMachine>.Create(ref stateMachine);
|
||||||
}
|
}
|
||||||
|
|
||||||
awaiter.OnCompleted(runner.CallMoveNext);
|
awaiter.OnCompleted(runner.CallMoveNext);
|
||||||
|
|
|
@ -9,43 +9,30 @@ using UniRx.Async.Internal;
|
||||||
|
|
||||||
namespace UniRx.Async.CompilerServices
|
namespace UniRx.Async.CompilerServices
|
||||||
{
|
{
|
||||||
// TODO: Remove it.
|
|
||||||
internal class MoveNextRunner<TStateMachine>
|
|
||||||
where TStateMachine : IAsyncStateMachine
|
|
||||||
{
|
|
||||||
public TStateMachine StateMachine;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
StateMachine.MoveNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal interface IMoveNextRunner
|
internal interface IMoveNextRunner
|
||||||
{
|
{
|
||||||
Action CallMoveNext { get; }
|
Action CallMoveNext { get; }
|
||||||
void Return();
|
void Return();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class MoveNextRunner2<TStateMachine> : IMoveNextRunner, IPromisePoolItem
|
internal class MoveNextRunner<TStateMachine> : IMoveNextRunner, IPromisePoolItem
|
||||||
where TStateMachine : IAsyncStateMachine
|
where TStateMachine : IAsyncStateMachine
|
||||||
{
|
{
|
||||||
static PromisePool<MoveNextRunner2<TStateMachine>> pool = new PromisePool<MoveNextRunner2<TStateMachine>>();
|
static PromisePool<MoveNextRunner<TStateMachine>> pool = new PromisePool<MoveNextRunner<TStateMachine>>();
|
||||||
|
|
||||||
TStateMachine stateMachine;
|
TStateMachine stateMachine;
|
||||||
internal readonly Action callMoveNext;
|
internal readonly Action callMoveNext;
|
||||||
|
|
||||||
public Action CallMoveNext => callMoveNext;
|
public Action CallMoveNext => callMoveNext;
|
||||||
|
|
||||||
MoveNextRunner2()
|
MoveNextRunner()
|
||||||
{
|
{
|
||||||
callMoveNext = MoveNext;
|
callMoveNext = MoveNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MoveNextRunner2<TStateMachine> Create(ref TStateMachine stateMachine)
|
public static MoveNextRunner<TStateMachine> Create(ref TStateMachine stateMachine)
|
||||||
{
|
{
|
||||||
var result = pool.TryRent() ?? new MoveNextRunner2<TStateMachine>();
|
var result = pool.TryRent() ?? new MoveNextRunner<TStateMachine>();
|
||||||
result.stateMachine = stateMachine;
|
result.stateMachine = stateMachine;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,6 @@ namespace UniRx.Async
|
||||||
{
|
{
|
||||||
// UnityEngine Bridges.
|
// UnityEngine Bridges.
|
||||||
|
|
||||||
public partial struct UniTask2
|
|
||||||
{
|
|
||||||
public static IEnumerator ToCoroutine(Func<UniTask2> taskFactory)
|
|
||||||
{
|
|
||||||
return taskFactory().ToCoroutine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public partial struct UniTask
|
public partial struct UniTask
|
||||||
{
|
{
|
||||||
public static IEnumerator ToCoroutine(Func<UniTask> taskFactory)
|
public static IEnumerator ToCoroutine(Func<UniTask> taskFactory)
|
||||||
|
|
|
@ -9,31 +9,30 @@ using UnityEngine;
|
||||||
|
|
||||||
namespace UniRx.Async
|
namespace UniRx.Async
|
||||||
{
|
{
|
||||||
// TODO:rename
|
public partial struct UniTask
|
||||||
public partial struct UniTask2
|
|
||||||
{
|
{
|
||||||
public static YieldAwaitable2 Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
public static YieldAwaitable Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
||||||
{
|
{
|
||||||
// optimized for single continuation
|
// optimized for single continuation
|
||||||
return new YieldAwaitable2(timing);
|
return new YieldAwaitable(timing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2 Yield(PlayerLoopTiming timing, CancellationToken cancellationToken)
|
public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
return new UniTask2(YieldPromise.Create(timing, cancellationToken, out var token), token);
|
return new UniTask(YieldPromise.Create(timing, cancellationToken, out var token), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2 DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
if (delayFrameCount < 0)
|
if (delayFrameCount < 0)
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount);
|
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UniTask2(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, out var token), token);
|
return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, out var token), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2 Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
|
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
|
||||||
if (delayTimeSpan < TimeSpan.Zero)
|
if (delayTimeSpan < TimeSpan.Zero)
|
||||||
|
@ -42,11 +41,11 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ignoreTimeScale)
|
return (ignoreTimeScale)
|
||||||
? new UniTask2(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token)
|
? new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token)
|
||||||
: new UniTask2(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token);
|
: new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2 Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
if (delayTimeSpan < TimeSpan.Zero)
|
if (delayTimeSpan < TimeSpan.Zero)
|
||||||
{
|
{
|
||||||
|
@ -54,8 +53,8 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ignoreTimeScale)
|
return (ignoreTimeScale)
|
||||||
? new UniTask2(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token)
|
? new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token)
|
||||||
: new UniTask2(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token);
|
: new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
class YieldPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
|
class YieldPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
|
||||||
|
@ -405,244 +404,6 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:rename
|
|
||||||
public struct YieldAwaitable2
|
|
||||||
{
|
|
||||||
readonly PlayerLoopTiming timing;
|
|
||||||
|
|
||||||
public YieldAwaitable2(PlayerLoopTiming timing)
|
|
||||||
{
|
|
||||||
this.timing = timing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Awaiter GetAwaiter()
|
|
||||||
{
|
|
||||||
return new Awaiter(timing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniTask2 ToUniTask()
|
|
||||||
{
|
|
||||||
return UniTask2.Yield(timing, CancellationToken.None);
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Awaiter : ICriticalNotifyCompletion
|
|
||||||
{
|
|
||||||
readonly PlayerLoopTiming timing;
|
|
||||||
|
|
||||||
public Awaiter(PlayerLoopTiming timing)
|
|
||||||
{
|
|
||||||
this.timing = timing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCompleted => false;
|
|
||||||
|
|
||||||
public void GetResult() { }
|
|
||||||
|
|
||||||
public void OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
PlayerLoopHelper.AddContinuation(timing, continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
PlayerLoopHelper.AddContinuation(timing, continuation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO:remove
|
|
||||||
public partial struct UniTask
|
|
||||||
{
|
|
||||||
public static YieldAwaitable Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
|
||||||
{
|
|
||||||
// optimized for single continuation
|
|
||||||
return new YieldAwaitable(timing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
return new UniTask(new YieldPromise(timing, cancellationToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask<int> DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
|
||||||
if (delayFrameCount < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
var source = new DelayFramePromise(delayFrameCount, delayTiming, cancellationToken);
|
|
||||||
return source.Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
|
||||||
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
|
|
||||||
if (delayTimeSpan < TimeSpan.Zero)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayTimeSpan:" + delayTimeSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ignoreTimeScale)
|
|
||||||
? new DelayIgnoreTimeScalePromise(delayTimeSpan, delayTiming, cancellationToken).Task
|
|
||||||
: new DelayPromise(delayTimeSpan, delayTiming, cancellationToken).Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
|
||||||
{
|
|
||||||
if (delayTimeSpan < TimeSpan.Zero)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayTimeSpan:" + delayTimeSpan);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ignoreTimeScale)
|
|
||||||
? new DelayIgnoreTimeScalePromise(delayTimeSpan, delayTiming, cancellationToken).Task
|
|
||||||
: new DelayPromise(delayTimeSpan, delayTiming, cancellationToken).Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
class YieldPromise : PlayerLoopReusablePromiseBase
|
|
||||||
{
|
|
||||||
public YieldPromise(PlayerLoopTiming timing, CancellationToken cancellationToken)
|
|
||||||
: base(timing, cancellationToken, 2)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRunningStart()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool MoveNext()
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
if (cancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
TrySetCanceled();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TrySetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelayFramePromise : PlayerLoopReusablePromiseBase<int>
|
|
||||||
{
|
|
||||||
readonly int delayFrameCount;
|
|
||||||
int currentFrameCount;
|
|
||||||
|
|
||||||
public DelayFramePromise(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken)
|
|
||||||
: base(timing, cancellationToken, 2)
|
|
||||||
{
|
|
||||||
this.delayFrameCount = delayFrameCount;
|
|
||||||
this.currentFrameCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRunningStart()
|
|
||||||
{
|
|
||||||
currentFrameCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool MoveNext()
|
|
||||||
{
|
|
||||||
if (cancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
TrySetCanceled();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentFrameCount == delayFrameCount)
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
TrySetResult(currentFrameCount);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentFrameCount++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelayPromise : PlayerLoopReusablePromiseBase
|
|
||||||
{
|
|
||||||
readonly float delayFrameTimeSpan;
|
|
||||||
float elapsed;
|
|
||||||
|
|
||||||
public DelayPromise(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken)
|
|
||||||
: base(timing, cancellationToken, 2)
|
|
||||||
{
|
|
||||||
this.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRunningStart()
|
|
||||||
{
|
|
||||||
this.elapsed = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool MoveNext()
|
|
||||||
{
|
|
||||||
if (cancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
TrySetCanceled();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
elapsed += Time.deltaTime;
|
|
||||||
if (elapsed >= delayFrameTimeSpan)
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
TrySetResult();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelayIgnoreTimeScalePromise : PlayerLoopReusablePromiseBase
|
|
||||||
{
|
|
||||||
readonly float delayFrameTimeSpan;
|
|
||||||
float elapsed;
|
|
||||||
|
|
||||||
public DelayIgnoreTimeScalePromise(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken)
|
|
||||||
: base(timing, cancellationToken, 2)
|
|
||||||
{
|
|
||||||
this.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnRunningStart()
|
|
||||||
{
|
|
||||||
this.elapsed = 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool MoveNext()
|
|
||||||
{
|
|
||||||
if (cancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
TrySetCanceled();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
elapsed += Time.unscaledDeltaTime;
|
|
||||||
|
|
||||||
if (elapsed >= delayFrameTimeSpan)
|
|
||||||
{
|
|
||||||
Complete();
|
|
||||||
TrySetResult();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:remove
|
|
||||||
public struct YieldAwaitable
|
public struct YieldAwaitable
|
||||||
{
|
{
|
||||||
readonly PlayerLoopTiming timing;
|
readonly PlayerLoopTiming timing;
|
||||||
|
|
|
@ -7,11 +7,11 @@ using UnityEngine.Events;
|
||||||
|
|
||||||
namespace UniRx.Async
|
namespace UniRx.Async
|
||||||
{
|
{
|
||||||
public partial struct UniTask2
|
public partial struct UniTask
|
||||||
{
|
{
|
||||||
static readonly UniTask2 CanceledUniTask = new Func<UniTask2>(() =>
|
static readonly UniTask CanceledUniTask = new Func<UniTask>(() =>
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2();
|
var promise = new UniTaskCompletionSource();
|
||||||
promise.SetCanceled(CancellationToken.None);
|
promise.SetCanceled(CancellationToken.None);
|
||||||
promise.MarkHandled();
|
promise.MarkHandled();
|
||||||
return promise.Task;
|
return promise.Task;
|
||||||
|
@ -19,41 +19,41 @@ namespace UniRx.Async
|
||||||
|
|
||||||
static class CanceledUniTaskCache<T>
|
static class CanceledUniTaskCache<T>
|
||||||
{
|
{
|
||||||
public static readonly UniTask2<T> Task;
|
public static readonly UniTask<T> Task;
|
||||||
|
|
||||||
static CanceledUniTaskCache()
|
static CanceledUniTaskCache()
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2<T>();
|
var promise = new UniTaskCompletionSource<T>();
|
||||||
promise.SetCanceled(CancellationToken.None);
|
promise.SetCanceled(CancellationToken.None);
|
||||||
promise.MarkHandled();
|
promise.MarkHandled();
|
||||||
Task = promise.Task;
|
Task = promise.Task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly UniTask2 CompletedTask = new UniTask2();
|
public static readonly UniTask CompletedTask = new UniTask();
|
||||||
|
|
||||||
public static UniTask2 FromException(Exception ex)
|
public static UniTask FromException(Exception ex)
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2();
|
var promise = new UniTaskCompletionSource();
|
||||||
promise.SetException(ex);
|
promise.SetException(ex);
|
||||||
promise.MarkHandled();
|
promise.MarkHandled();
|
||||||
return promise.Task;
|
return promise.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2<T> FromException<T>(Exception ex)
|
public static UniTask<T> FromException<T>(Exception ex)
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2<T>();
|
var promise = new UniTaskCompletionSource<T>();
|
||||||
promise.SetException(ex);
|
promise.SetException(ex);
|
||||||
promise.MarkHandled();
|
promise.MarkHandled();
|
||||||
return promise.Task;
|
return promise.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2<T> FromResult<T>(T value)
|
public static UniTask<T> FromResult<T>(T value)
|
||||||
{
|
{
|
||||||
return new UniTask2<T>(value);
|
return new UniTask<T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2 FromCanceled(CancellationToken cancellationToken = default)
|
public static UniTask FromCanceled(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (cancellationToken == CancellationToken.None)
|
if (cancellationToken == CancellationToken.None)
|
||||||
{
|
{
|
||||||
|
@ -61,14 +61,14 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2();
|
var promise = new UniTaskCompletionSource();
|
||||||
promise.SetCanceled(cancellationToken);
|
promise.SetCanceled(cancellationToken);
|
||||||
promise.MarkHandled();
|
promise.MarkHandled();
|
||||||
return promise.Task;
|
return promise.Task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UniTask2<T> FromCanceled<T>(CancellationToken cancellationToken = default)
|
public static UniTask<T> FromCanceled<T>(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (cancellationToken == CancellationToken.None)
|
if (cancellationToken == CancellationToken.None)
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2<T>();
|
var promise = new UniTaskCompletionSource<T>();
|
||||||
promise.SetCanceled(cancellationToken);
|
promise.SetCanceled(cancellationToken);
|
||||||
promise.MarkHandled();
|
promise.MarkHandled();
|
||||||
return promise.Task;
|
return promise.Task;
|
||||||
|
@ -120,143 +120,15 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO:remove
|
|
||||||
public partial struct UniTask
|
|
||||||
{
|
|
||||||
static readonly UniTask CanceledUniTask = new Func<UniTask>(() =>
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<AsyncUnit>();
|
|
||||||
promise.TrySetCanceled();
|
|
||||||
promise.MarkHandled();
|
|
||||||
return new UniTask(promise);
|
|
||||||
})();
|
|
||||||
|
|
||||||
public static UniTask CompletedTask
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new UniTask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask FromException(Exception ex)
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<AsyncUnit>();
|
|
||||||
promise.TrySetException(ex);
|
|
||||||
promise.MarkHandled();
|
|
||||||
return new UniTask(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask<T> FromException<T>(Exception ex)
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<T>();
|
|
||||||
promise.TrySetException(ex);
|
|
||||||
promise.MarkHandled();
|
|
||||||
return new UniTask<T>(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask<T> FromResult<T>(T value)
|
|
||||||
{
|
|
||||||
return new UniTask<T>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask FromCanceled()
|
|
||||||
{
|
|
||||||
return CanceledUniTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask<T> FromCanceled<T>()
|
|
||||||
{
|
|
||||||
return CanceledUniTaskCache<T>.Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask FromCanceled(CancellationToken token)
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<AsyncUnit>();
|
|
||||||
promise.TrySetException(new OperationCanceledException(token));
|
|
||||||
promise.MarkHandled();
|
|
||||||
return new UniTask(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask<T> FromCanceled<T>(CancellationToken token)
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<T>();
|
|
||||||
promise.TrySetException(new OperationCanceledException(token));
|
|
||||||
promise.MarkHandled();
|
|
||||||
return new UniTask<T>(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>shorthand of new UniTask[T](Func[UniTask[T]] factory)</summary>
|
|
||||||
public static UniTask<T> Lazy<T>(Func<UniTask<T>> factory)
|
|
||||||
{
|
|
||||||
return new UniTask<T>(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// helper of create add UniTaskVoid to delegate.
|
|
||||||
/// For example: FooEvent += () => UniTask.Void(async () => { /* */ })
|
|
||||||
/// </summary>
|
|
||||||
public static void Void(Func<UniTask> asyncAction)
|
|
||||||
{
|
|
||||||
asyncAction().Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Action VoidAction(Func<UniTask> asyncAction)
|
|
||||||
{
|
|
||||||
return () => Void(asyncAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UnityAction VoidUnityAction(Func<UniTask> asyncAction)
|
|
||||||
{
|
|
||||||
return () => Void(asyncAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// helper of create add UniTaskVoid to delegate.
|
|
||||||
/// For example: FooEvent += (sender, e) => UniTask.Void(async arg => { /* */ }, (sender, e))
|
|
||||||
/// </summary>
|
|
||||||
public static void Void<T>(Func<T, UniTask> asyncAction, T state)
|
|
||||||
{
|
|
||||||
asyncAction(state).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
static class CanceledUniTaskCache<T>
|
|
||||||
{
|
|
||||||
public static readonly UniTask<T> Task;
|
|
||||||
|
|
||||||
static CanceledUniTaskCache()
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<T>();
|
|
||||||
promise.TrySetCanceled();
|
|
||||||
promise.MarkHandled();
|
|
||||||
Task = new UniTask<T>(promise);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO:remove
|
|
||||||
internal static class CompletedTasks
|
internal static class CompletedTasks
|
||||||
{
|
{
|
||||||
|
public static readonly UniTask Completed = new UniTask();
|
||||||
|
public static readonly UniTask<AsyncUnit> AsyncUnit = UniTask.FromResult(UniRx.Async.AsyncUnit.Default);
|
||||||
public static readonly UniTask<bool> True = UniTask.FromResult(true);
|
public static readonly UniTask<bool> True = UniTask.FromResult(true);
|
||||||
public static readonly UniTask<bool> False = UniTask.FromResult(false);
|
public static readonly UniTask<bool> False = UniTask.FromResult(false);
|
||||||
public static readonly UniTask<int> Zero = UniTask.FromResult(0);
|
public static readonly UniTask<int> Zero = UniTask.FromResult(0);
|
||||||
public static readonly UniTask<int> MinusOne = UniTask.FromResult(-1);
|
public static readonly UniTask<int> MinusOne = UniTask.FromResult(-1);
|
||||||
public static readonly UniTask<int> One = UniTask.FromResult(1);
|
public static readonly UniTask<int> One = UniTask.FromResult(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO:rename
|
|
||||||
internal static class CompletedTasks2
|
|
||||||
{
|
|
||||||
public static readonly UniTask2 Completed = new UniTask2();
|
|
||||||
public static readonly UniTask2<AsyncUnit> AsyncUnit = UniTask2.FromResult(UniRx.Async.AsyncUnit.Default);
|
|
||||||
public static readonly UniTask2<bool> True = UniTask2.FromResult(true);
|
|
||||||
public static readonly UniTask2<bool> False = UniTask2.FromResult(false);
|
|
||||||
public static readonly UniTask2<int> Zero = UniTask2.FromResult(0);
|
|
||||||
public static readonly UniTask2<int> MinusOne = UniTask2.FromResult(-1);
|
|
||||||
public static readonly UniTask2<int> One = UniTask2.FromResult(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -25,15 +25,15 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lightweight unity specified task-like object.
|
/// Lightweight unity specified task-like object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AsyncMethodBuilder(typeof(AsyncUniTask2MethodBuilder))]
|
[AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder))]
|
||||||
public readonly partial struct UniTask2
|
public readonly partial struct UniTask
|
||||||
{
|
{
|
||||||
readonly IUniTaskSource source;
|
readonly IUniTaskSource source;
|
||||||
readonly short token;
|
readonly short token;
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UniTask2(IUniTaskSource source, short token)
|
public UniTask(IUniTaskSource source, short token)
|
||||||
{
|
{
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
|
@ -60,12 +60,12 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// returns (bool IsCanceled) instead of throws OperationCanceledException.
|
/// returns (bool IsCanceled) instead of throws OperationCanceledException.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UniTask2<bool> SuppressCancellationThrow()
|
public UniTask<bool> SuppressCancellationThrow()
|
||||||
{
|
{
|
||||||
var status = Status;
|
var status = Status;
|
||||||
if (status == AwaiterStatus.Succeeded) return CompletedTasks2.False;
|
if (status == AwaiterStatus.Succeeded) return CompletedTasks.False;
|
||||||
if (status == AwaiterStatus.Canceled) return CompletedTasks2.True;
|
if (status == AwaiterStatus.Canceled) return CompletedTasks.True;
|
||||||
return new UniTask2<bool>(new IsCanceledSource(source), token);
|
return new UniTask<bool>(new IsCanceledSource(source), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@ -77,7 +77,7 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Memoizing inner IValueTaskSource. The result UniTask can await multiple.
|
/// Memoizing inner IValueTaskSource. The result UniTask can await multiple.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UniTask2 Preserve()
|
public UniTask Preserve()
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
@ -85,21 +85,21 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new UniTask2(new MemoizeSource(source), token);
|
return new UniTask(new MemoizeSource(source), token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator UniTask2<AsyncUnit>(UniTask2 task)
|
public static implicit operator UniTask<AsyncUnit>(UniTask task)
|
||||||
{
|
{
|
||||||
if (task.source == null) return CompletedTasks2.AsyncUnit;
|
if (task.source == null) return CompletedTasks.AsyncUnit;
|
||||||
|
|
||||||
var status = task.source.GetStatus(task.token);
|
var status = task.source.GetStatus(task.token);
|
||||||
if (status.IsCompletedSuccessfully())
|
if (status.IsCompletedSuccessfully())
|
||||||
{
|
{
|
||||||
return CompletedTasks2.AsyncUnit;
|
return CompletedTasks.AsyncUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UniTask2<AsyncUnit>(new AsyncUnitSource(task.source), task.token);
|
return new UniTask<AsyncUnit>(new AsyncUnitSource(task.source), task.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AsyncUnitSource : IUniTaskSource<AsyncUnit>
|
class AsyncUnitSource : IUniTaskSource<AsyncUnit>
|
||||||
|
@ -261,11 +261,11 @@ namespace UniRx.Async
|
||||||
|
|
||||||
public readonly struct Awaiter : ICriticalNotifyCompletion
|
public readonly struct Awaiter : ICriticalNotifyCompletion
|
||||||
{
|
{
|
||||||
readonly UniTask2 task;
|
readonly UniTask task;
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Awaiter(in UniTask2 task)
|
public Awaiter(in UniTask task)
|
||||||
{
|
{
|
||||||
this.task = task;
|
this.task = task;
|
||||||
}
|
}
|
||||||
|
@ -336,8 +336,8 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lightweight unity specified task-like object.
|
/// Lightweight unity specified task-like object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AsyncMethodBuilder(typeof(AsyncUniTask2MethodBuilder<>))]
|
[AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder<>))]
|
||||||
public readonly struct UniTask2<T>
|
public readonly struct UniTask<T>
|
||||||
{
|
{
|
||||||
readonly IUniTaskSource<T> source;
|
readonly IUniTaskSource<T> source;
|
||||||
readonly T result;
|
readonly T result;
|
||||||
|
@ -345,7 +345,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UniTask2(T result)
|
public UniTask(T result)
|
||||||
{
|
{
|
||||||
this.source = default;
|
this.source = default;
|
||||||
this.token = default;
|
this.token = default;
|
||||||
|
@ -354,7 +354,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public UniTask2(IUniTaskSource<T> source, short token)
|
public UniTask(IUniTaskSource<T> source, short token)
|
||||||
{
|
{
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
|
@ -381,7 +381,7 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Memoizing inner IValueTaskSource. The result UniTask can await multiple.
|
/// Memoizing inner IValueTaskSource. The result UniTask can await multiple.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UniTask2<T> Preserve()
|
public UniTask<T> Preserve()
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
|
@ -389,34 +389,34 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return new UniTask2<T>(new MemoizeSource(source), token);
|
return new UniTask<T>(new MemoizeSource(source), token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator UniTask2(UniTask2<T> task)
|
public static implicit operator UniTask(UniTask<T> task)
|
||||||
{
|
{
|
||||||
if (task.source == null) return UniTask2.CompletedTask;
|
if (task.source == null) return UniTask.CompletedTask;
|
||||||
|
|
||||||
var status = task.source.GetStatus(task.token);
|
var status = task.source.GetStatus(task.token);
|
||||||
if (status.IsCompletedSuccessfully())
|
if (status.IsCompletedSuccessfully())
|
||||||
{
|
{
|
||||||
return UniTask2.CompletedTask;
|
return UniTask.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UniTask2(task.source, task.token);
|
return new UniTask(task.source, task.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException.
|
/// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UniTask2<(bool IsCanceled, T Result)> SuppressCancellationThrow()
|
public UniTask<(bool IsCanceled, T Result)> SuppressCancellationThrow()
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
{
|
{
|
||||||
return new UniTask2<(bool IsCanceled, T Result)>((false, result));
|
return new UniTask<(bool IsCanceled, T Result)>((false, result));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UniTask2<(bool, T)>(new IsCanceledSource(source), token);
|
return new UniTask<(bool, T)>(new IsCanceledSource(source), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
@ -568,11 +568,11 @@ namespace UniRx.Async
|
||||||
|
|
||||||
public readonly struct Awaiter : ICriticalNotifyCompletion
|
public readonly struct Awaiter : ICriticalNotifyCompletion
|
||||||
{
|
{
|
||||||
readonly UniTask2<T> task;
|
readonly UniTask<T> task;
|
||||||
|
|
||||||
[DebuggerHidden]
|
[DebuggerHidden]
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public Awaiter(in UniTask2<T> task)
|
public Awaiter(in UniTask<T> task)
|
||||||
{
|
{
|
||||||
this.task = task;
|
this.task = task;
|
||||||
}
|
}
|
||||||
|
@ -649,472 +649,6 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lightweight unity specified task-like object.
|
|
||||||
/// </summary>
|
|
||||||
[AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder))]
|
|
||||||
public partial struct UniTask : IEquatable<UniTask>
|
|
||||||
{
|
|
||||||
static readonly UniTask<AsyncUnit> DefaultAsyncUnitTask = new UniTask<AsyncUnit>(AsyncUnit.Default);
|
|
||||||
|
|
||||||
readonly IAwaiter awaiter;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask(IAwaiter awaiter)
|
|
||||||
{
|
|
||||||
this.awaiter = awaiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask(Func<UniTask> factory)
|
|
||||||
{
|
|
||||||
this.awaiter = new LazyPromise(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public AwaiterStatus Status
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return awaiter == null ? AwaiterStatus.Succeeded : awaiter.Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public bool IsCompleted
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return awaiter == null ? true : awaiter.IsCompleted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void GetResult()
|
|
||||||
{
|
|
||||||
if (awaiter != null)
|
|
||||||
{
|
|
||||||
awaiter.GetResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public Awaiter GetAwaiter()
|
|
||||||
{
|
|
||||||
return new Awaiter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// returns (bool IsCanceled) instead of throws OperationCanceledException.
|
|
||||||
/// </summary>
|
|
||||||
public UniTask<bool> SuppressCancellationThrow()
|
|
||||||
{
|
|
||||||
var status = Status;
|
|
||||||
if (status == AwaiterStatus.Succeeded) return CompletedTasks.False;
|
|
||||||
if (status == AwaiterStatus.Canceled) return CompletedTasks.True;
|
|
||||||
return new UniTask<bool>(new IsCanceledAwaiter(awaiter));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(UniTask other)
|
|
||||||
{
|
|
||||||
if (this.awaiter == null && other.awaiter == null)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (this.awaiter != null && other.awaiter != null)
|
|
||||||
{
|
|
||||||
return this.awaiter == other.awaiter;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
if (this.awaiter == null)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.awaiter.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return (this.awaiter == null) ? "()"
|
|
||||||
: (this.awaiter.Status == AwaiterStatus.Succeeded) ? "()"
|
|
||||||
: "(" + this.awaiter.Status + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator UniTask<AsyncUnit>(UniTask task)
|
|
||||||
{
|
|
||||||
if (task.awaiter != null)
|
|
||||||
{
|
|
||||||
if (task.awaiter.IsCompleted)
|
|
||||||
{
|
|
||||||
return DefaultAsyncUnitTask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// UniTask<T> -> UniTask is free but UniTask -> UniTask<T> requires wrapping cost.
|
|
||||||
return new UniTask<AsyncUnit>(new AsyncUnitAwaiter(task.awaiter));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return DefaultAsyncUnitTask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class AsyncUnitAwaiter : IAwaiter<AsyncUnit>
|
|
||||||
{
|
|
||||||
readonly IAwaiter awaiter;
|
|
||||||
|
|
||||||
public AsyncUnitAwaiter(IAwaiter awaiter)
|
|
||||||
{
|
|
||||||
this.awaiter = awaiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCompleted => awaiter.IsCompleted;
|
|
||||||
|
|
||||||
public AwaiterStatus Status => awaiter.Status;
|
|
||||||
|
|
||||||
public AsyncUnit GetResult()
|
|
||||||
{
|
|
||||||
awaiter.GetResult();
|
|
||||||
return AsyncUnit.Default;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
awaiter.OnCompleted(continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
awaiter.UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IAwaiter.GetResult()
|
|
||||||
{
|
|
||||||
awaiter.GetResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class IsCanceledAwaiter : IAwaiter<bool>
|
|
||||||
{
|
|
||||||
readonly IAwaiter awaiter;
|
|
||||||
|
|
||||||
public IsCanceledAwaiter(IAwaiter awaiter)
|
|
||||||
{
|
|
||||||
this.awaiter = awaiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCompleted => awaiter.IsCompleted;
|
|
||||||
|
|
||||||
public AwaiterStatus Status => awaiter.Status;
|
|
||||||
|
|
||||||
public bool GetResult()
|
|
||||||
{
|
|
||||||
if (awaiter.Status == AwaiterStatus.Canceled)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
awaiter.GetResult();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
awaiter.OnCompleted(continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
awaiter.UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IAwaiter.GetResult()
|
|
||||||
{
|
|
||||||
awaiter.GetResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Awaiter : IAwaiter
|
|
||||||
{
|
|
||||||
readonly UniTask task;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public Awaiter(UniTask task)
|
|
||||||
{
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public bool IsCompleted => task.IsCompleted;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public AwaiterStatus Status => task.Status;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void GetResult() => task.GetResult();
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
if (task.awaiter != null)
|
|
||||||
{
|
|
||||||
task.awaiter.OnCompleted(continuation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
if (task.awaiter != null)
|
|
||||||
{
|
|
||||||
task.awaiter.UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Lightweight unity specified task-like object.
|
|
||||||
/// </summary>
|
|
||||||
[AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder<>))]
|
|
||||||
public struct UniTask<T> : IEquatable<UniTask<T>>
|
|
||||||
{
|
|
||||||
readonly T result;
|
|
||||||
readonly IAwaiter<T> awaiter;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask(T result)
|
|
||||||
{
|
|
||||||
this.result = result;
|
|
||||||
this.awaiter = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask(IAwaiter<T> awaiter)
|
|
||||||
{
|
|
||||||
this.result = default(T);
|
|
||||||
this.awaiter = awaiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public UniTask(Func<UniTask<T>> factory)
|
|
||||||
{
|
|
||||||
this.result = default(T);
|
|
||||||
this.awaiter = new LazyPromise<T>(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public AwaiterStatus Status
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return awaiter == null ? AwaiterStatus.Succeeded : awaiter.Status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public bool IsCompleted
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return awaiter == null ? true : awaiter.IsCompleted;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public T Result
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (awaiter == null)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return awaiter.GetResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public Awaiter GetAwaiter()
|
|
||||||
{
|
|
||||||
return new Awaiter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException.
|
|
||||||
/// </summary>
|
|
||||||
public UniTask<(bool IsCanceled, T Result)> SuppressCancellationThrow()
|
|
||||||
{
|
|
||||||
var status = Status;
|
|
||||||
if (status == AwaiterStatus.Succeeded)
|
|
||||||
{
|
|
||||||
return new UniTask<(bool, T)>((false, Result));
|
|
||||||
}
|
|
||||||
else if (status == AwaiterStatus.Canceled)
|
|
||||||
{
|
|
||||||
return new UniTask<(bool, T)>((true, default(T)));
|
|
||||||
}
|
|
||||||
return new UniTask<(bool, T)>(new IsCanceledAwaiter(awaiter));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Equals(UniTask<T> other)
|
|
||||||
{
|
|
||||||
if (this.awaiter == null && other.awaiter == null)
|
|
||||||
{
|
|
||||||
return EqualityComparer<T>.Default.Equals(this.result, other.result);
|
|
||||||
}
|
|
||||||
else if (this.awaiter != null && other.awaiter != null)
|
|
||||||
{
|
|
||||||
return this.awaiter == other.awaiter;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
if (this.awaiter == null)
|
|
||||||
{
|
|
||||||
if (result == null) return 0;
|
|
||||||
return result.GetHashCode();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.awaiter.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return (this.awaiter == null) ? result.ToString()
|
|
||||||
: (this.awaiter.Status == AwaiterStatus.Succeeded) ? this.awaiter.GetResult().ToString()
|
|
||||||
: "(" + this.awaiter.Status + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator UniTask(UniTask<T> task)
|
|
||||||
{
|
|
||||||
if (task.awaiter != null)
|
|
||||||
{
|
|
||||||
return new UniTask(task.awaiter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new UniTask();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class IsCanceledAwaiter : IAwaiter<(bool, T)>
|
|
||||||
{
|
|
||||||
readonly IAwaiter<T> awaiter;
|
|
||||||
|
|
||||||
public IsCanceledAwaiter(IAwaiter<T> awaiter)
|
|
||||||
{
|
|
||||||
this.awaiter = awaiter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsCompleted => awaiter.IsCompleted;
|
|
||||||
|
|
||||||
public AwaiterStatus Status => awaiter.Status;
|
|
||||||
|
|
||||||
public (bool, T) GetResult()
|
|
||||||
{
|
|
||||||
if (awaiter.Status == AwaiterStatus.Canceled)
|
|
||||||
{
|
|
||||||
return (true, default(T));
|
|
||||||
}
|
|
||||||
return (false, awaiter.GetResult());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
awaiter.OnCompleted(continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
awaiter.UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IAwaiter.GetResult()
|
|
||||||
{
|
|
||||||
awaiter.GetResult();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Awaiter : IAwaiter<T>
|
|
||||||
{
|
|
||||||
readonly UniTask<T> task;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public Awaiter(in UniTask<T> task)
|
|
||||||
{
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public bool IsCompleted => task.IsCompleted;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public AwaiterStatus Status => task.Status;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
void IAwaiter.GetResult() => GetResult();
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public T GetResult() => task.Result;
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
if (task.awaiter != null)
|
|
||||||
{
|
|
||||||
task.awaiter.OnCompleted(continuation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[DebuggerHidden]
|
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
if (task.awaiter != null)
|
|
||||||
{
|
|
||||||
task.awaiter.UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
continuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.ExceptionServices;
|
using System.Runtime.ExceptionServices;
|
||||||
|
@ -12,52 +11,24 @@ using UniRx.Async.Internal;
|
||||||
|
|
||||||
namespace UniRx.Async
|
namespace UniRx.Async
|
||||||
{
|
{
|
||||||
// TODO: Remove all?
|
|
||||||
|
|
||||||
internal class ExceptionHolder
|
|
||||||
{
|
|
||||||
ExceptionDispatchInfo exception;
|
|
||||||
bool calledGet = false;
|
|
||||||
|
|
||||||
public ExceptionHolder(ExceptionDispatchInfo exception)
|
|
||||||
{
|
|
||||||
this.exception = exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ExceptionDispatchInfo GetException()
|
|
||||||
{
|
|
||||||
if (!calledGet)
|
|
||||||
{
|
|
||||||
calledGet = true;
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
return exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ExceptionHolder()
|
|
||||||
{
|
|
||||||
UniTaskScheduler.PublishUnobservedTaskException(exception.SourceException);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IResolvePromise
|
public interface IResolvePromise
|
||||||
{
|
{
|
||||||
bool TrySetResult();
|
void SetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IResolvePromise<T>
|
public interface IResolvePromise<T>
|
||||||
{
|
{
|
||||||
bool TrySetResult(T value);
|
void SetResult(T value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IRejectPromise
|
public interface IRejectPromise
|
||||||
{
|
{
|
||||||
bool TrySetException(Exception exception);
|
void SetException(Exception exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ICancelPromise
|
public interface ICancelPromise
|
||||||
{
|
{
|
||||||
bool TrySetCanceled();
|
void SetCanceled(CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IPromise<T> : IResolvePromise<T>, IRejectPromise, ICancelPromise
|
public interface IPromise<T> : IResolvePromise<T>, IRejectPromise, ICancelPromise
|
||||||
|
@ -68,350 +39,6 @@ namespace UniRx.Async
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UniTaskCompletionSource : IAwaiter, IPromise
|
|
||||||
{
|
|
||||||
// State(= AwaiterStatus)
|
|
||||||
const int Pending = 0;
|
|
||||||
const int Succeeded = 1;
|
|
||||||
const int Faulted = 2;
|
|
||||||
const int Canceled = 3;
|
|
||||||
|
|
||||||
int state = 0;
|
|
||||||
bool handled = false;
|
|
||||||
ExceptionHolder exception;
|
|
||||||
object continuation; // action or list
|
|
||||||
|
|
||||||
AwaiterStatus IAwaiter.Status => (AwaiterStatus)state;
|
|
||||||
|
|
||||||
bool IAwaiter.IsCompleted => state != Pending;
|
|
||||||
|
|
||||||
public UniTask Task => new UniTask(this);
|
|
||||||
|
|
||||||
public UniTaskCompletionSource()
|
|
||||||
{
|
|
||||||
TaskTracker.TrackActiveTask(this, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Conditional("UNITY_EDITOR")]
|
|
||||||
internal void MarkHandled()
|
|
||||||
{
|
|
||||||
if (!handled)
|
|
||||||
{
|
|
||||||
handled = true;
|
|
||||||
TaskTracker.RemoveTracking(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void IAwaiter.GetResult()
|
|
||||||
{
|
|
||||||
MarkHandled();
|
|
||||||
|
|
||||||
if (state == Succeeded)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (state == Faulted)
|
|
||||||
{
|
|
||||||
exception.GetException().Throw();
|
|
||||||
}
|
|
||||||
else if (state == Canceled)
|
|
||||||
{
|
|
||||||
if (exception != null)
|
|
||||||
{
|
|
||||||
exception.GetException().Throw(); // guranteed operation canceled exception.
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new OperationCanceledException();
|
|
||||||
}
|
|
||||||
else // Pending
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("UniTask does not allow call GetResult directly when task not completed. Please use 'await'.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICriticalNotifyCompletion.UnsafeOnCompleted(Action action)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref continuation, (object)action, null) == null)
|
|
||||||
{
|
|
||||||
if (state != Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var c = continuation;
|
|
||||||
if (c is Action)
|
|
||||||
{
|
|
||||||
var list = new List<Action>();
|
|
||||||
list.Add((Action)c);
|
|
||||||
list.Add(action);
|
|
||||||
if (Interlocked.CompareExchange(ref continuation, list, c) == c)
|
|
||||||
{
|
|
||||||
goto TRYINVOKE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var l = (List<Action>)continuation;
|
|
||||||
lock (l)
|
|
||||||
{
|
|
||||||
l.Add(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRYINVOKE:
|
|
||||||
if (state != Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TryInvokeContinuation()
|
|
||||||
{
|
|
||||||
var c = Interlocked.Exchange(ref continuation, null);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
if (c is Action)
|
|
||||||
{
|
|
||||||
((Action)c).Invoke();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var l = (List<Action>)c;
|
|
||||||
var cnt = l.Count;
|
|
||||||
for (int i = 0; i < cnt; i++)
|
|
||||||
{
|
|
||||||
l[i].Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetResult()
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Succeeded, Pending) == Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetException(Exception exception)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Faulted, Pending) == Pending)
|
|
||||||
{
|
|
||||||
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(exception));
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetCanceled()
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Canceled, Pending) == Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetCanceled(OperationCanceledException exception)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Canceled, Pending) == Pending)
|
|
||||||
{
|
|
||||||
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(exception));
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void INotifyCompletion.OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
((ICriticalNotifyCompletion)this).UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class UniTaskCompletionSource<T> : IAwaiter<T>, IPromise<T>
|
|
||||||
{
|
|
||||||
// State(= AwaiterStatus)
|
|
||||||
const int Pending = 0;
|
|
||||||
const int Succeeded = 1;
|
|
||||||
const int Faulted = 2;
|
|
||||||
const int Canceled = 3;
|
|
||||||
|
|
||||||
int state = 0;
|
|
||||||
T value;
|
|
||||||
bool handled = false;
|
|
||||||
ExceptionHolder exception;
|
|
||||||
object continuation; // action or list
|
|
||||||
|
|
||||||
bool IAwaiter.IsCompleted => state != Pending;
|
|
||||||
|
|
||||||
public UniTask<T> Task => new UniTask<T>(this);
|
|
||||||
public UniTask UnitTask => new UniTask(this);
|
|
||||||
|
|
||||||
AwaiterStatus IAwaiter.Status => (AwaiterStatus)state;
|
|
||||||
|
|
||||||
public UniTaskCompletionSource()
|
|
||||||
{
|
|
||||||
TaskTracker.TrackActiveTask(this, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Conditional("UNITY_EDITOR")]
|
|
||||||
internal void MarkHandled()
|
|
||||||
{
|
|
||||||
if (!handled)
|
|
||||||
{
|
|
||||||
handled = true;
|
|
||||||
TaskTracker.RemoveTracking(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T IAwaiter<T>.GetResult()
|
|
||||||
{
|
|
||||||
MarkHandled();
|
|
||||||
|
|
||||||
if (state == Succeeded)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
else if (state == Faulted)
|
|
||||||
{
|
|
||||||
exception.GetException().Throw();
|
|
||||||
}
|
|
||||||
else if (state == Canceled)
|
|
||||||
{
|
|
||||||
if (exception != null)
|
|
||||||
{
|
|
||||||
exception.GetException().Throw(); // guranteed operation canceled exception.
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new OperationCanceledException();
|
|
||||||
}
|
|
||||||
else // Pending
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("UniTask does not allow call GetResult directly when task not completed. Please use 'await'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return default(T);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICriticalNotifyCompletion.UnsafeOnCompleted(Action action)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref continuation, (object)action, null) == null)
|
|
||||||
{
|
|
||||||
if (state != Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var c = continuation;
|
|
||||||
if (c is Action)
|
|
||||||
{
|
|
||||||
var list = new List<Action>();
|
|
||||||
list.Add((Action)c);
|
|
||||||
list.Add(action);
|
|
||||||
if (Interlocked.CompareExchange(ref continuation, list, c) == c)
|
|
||||||
{
|
|
||||||
goto TRYINVOKE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var l = (List<Action>)continuation;
|
|
||||||
lock (l)
|
|
||||||
{
|
|
||||||
l.Add(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRYINVOKE:
|
|
||||||
if (state != Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TryInvokeContinuation()
|
|
||||||
{
|
|
||||||
var c = Interlocked.Exchange(ref continuation, null);
|
|
||||||
if (c != null)
|
|
||||||
{
|
|
||||||
if (c is Action)
|
|
||||||
{
|
|
||||||
((Action)c).Invoke();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var l = (List<Action>)c;
|
|
||||||
var cnt = l.Count;
|
|
||||||
for (int i = 0; i < cnt; i++)
|
|
||||||
{
|
|
||||||
l[i].Invoke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetResult(T value)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Succeeded, Pending) == Pending)
|
|
||||||
{
|
|
||||||
this.value = value;
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetException(Exception exception)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Faulted, Pending) == Pending)
|
|
||||||
{
|
|
||||||
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(exception));
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetCanceled()
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Canceled, Pending) == Pending)
|
|
||||||
{
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TrySetCanceled(OperationCanceledException exception)
|
|
||||||
{
|
|
||||||
if (Interlocked.CompareExchange(ref state, Canceled, Pending) == Pending)
|
|
||||||
{
|
|
||||||
this.exception = new ExceptionHolder(ExceptionDispatchInfo.Capture(exception));
|
|
||||||
TryInvokeContinuation();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IAwaiter.GetResult()
|
|
||||||
{
|
|
||||||
((IAwaiter<T>)this).GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
void INotifyCompletion.OnCompleted(Action continuation)
|
|
||||||
{
|
|
||||||
((ICriticalNotifyCompletion)this).UnsafeOnCompleted(continuation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Auto)]
|
[StructLayout(LayoutKind.Auto)]
|
||||||
public struct UniTaskCompletionSourceCore<TResult>
|
public struct UniTaskCompletionSourceCore<TResult>
|
||||||
{
|
{
|
||||||
|
@ -602,12 +229,22 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UniTaskCompletionSource2 : IUniTaskSource
|
internal static class UniTaskCompletionSourceCoreShared // separated out of generic to avoid unnecessary duplication
|
||||||
|
{
|
||||||
|
internal static readonly Action<object> s_sentinel = CompletionSentinel;
|
||||||
|
|
||||||
|
private static void CompletionSentinel(object _) // named method to aid debugging
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("The sentinel delegate should never be invoked.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UniTaskCompletionSource : IUniTaskSource, IPromise
|
||||||
{
|
{
|
||||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
public UniTaskCompletionSource2()
|
public UniTaskCompletionSource()
|
||||||
{
|
{
|
||||||
TaskTracker2.TrackActiveTask(this, 2);
|
TaskTracker2.TrackActiveTask(this, 2);
|
||||||
}
|
}
|
||||||
|
@ -622,11 +259,11 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniTask2 Task
|
public UniTask Task
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new UniTask2(this, core.Version);
|
return new UniTask(this, core.Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -674,14 +311,14 @@ namespace UniRx.Async
|
||||||
core.OnCompleted(continuation, state, token);
|
core.OnCompleted(continuation, state, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
~UniTaskCompletionSource2()
|
~UniTaskCompletionSource()
|
||||||
{
|
{
|
||||||
// clear error information.
|
// clear error information.
|
||||||
core.Reset();
|
core.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoResetUniTaskCompletionSource : IUniTaskSource, IPromisePoolItem
|
public class AutoResetUniTaskCompletionSource : IUniTaskSource, IPromisePoolItem, IPromise
|
||||||
{
|
{
|
||||||
static readonly PromisePool<AutoResetUniTaskCompletionSource> pool = new PromisePool<AutoResetUniTaskCompletionSource>();
|
static readonly PromisePool<AutoResetUniTaskCompletionSource> pool = new PromisePool<AutoResetUniTaskCompletionSource>();
|
||||||
|
|
||||||
|
@ -722,11 +359,11 @@ namespace UniRx.Async
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniTask2 Task
|
public UniTask Task
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new UniTask2(this, core.Version);
|
return new UniTask(this, core.Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,7 +374,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
public void SetCanceled(CancellationToken cancellationToken = default)
|
public void SetCanceled(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
core.SetCancellation(cancellationToken);
|
core.SetCanceled(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetException(Exception exception)
|
public void SetException(Exception exception)
|
||||||
|
@ -789,12 +426,12 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UniTaskCompletionSource2<T> : IUniTaskSource<T>
|
public class UniTaskCompletionSource<T> : IUniTaskSource<T>, IPromise<T>
|
||||||
{
|
{
|
||||||
UniTaskCompletionSourceCore<T> core;
|
UniTaskCompletionSourceCore<T> core;
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
|
|
||||||
public UniTaskCompletionSource2()
|
public UniTaskCompletionSource()
|
||||||
{
|
{
|
||||||
TaskTracker2.TrackActiveTask(this, 2);
|
TaskTracker2.TrackActiveTask(this, 2);
|
||||||
}
|
}
|
||||||
|
@ -809,11 +446,11 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniTask2<T> Task
|
public UniTask<T> Task
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new UniTask2<T>(this, core.Version);
|
return new UniTask<T>(this, core.Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -831,7 +468,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
public void SetCanceled(CancellationToken cancellationToken = default)
|
public void SetCanceled(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
core.SetCancellation(cancellationToken);
|
core.SetCanceled(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetException(Exception exception)
|
public void SetException(Exception exception)
|
||||||
|
@ -865,14 +502,14 @@ namespace UniRx.Async
|
||||||
core.OnCompleted(continuation, state, token);
|
core.OnCompleted(continuation, state, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
~UniTaskCompletionSource2()
|
~UniTaskCompletionSource()
|
||||||
{
|
{
|
||||||
// clear error information.
|
// clear error information.
|
||||||
core.Reset();
|
core.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AutoResetUniTaskCompletionSource<T> : IUniTaskSource<T>, IPromisePoolItem
|
public class AutoResetUniTaskCompletionSource<T> : IUniTaskSource<T>, IPromisePoolItem, IPromise<T>
|
||||||
{
|
{
|
||||||
static readonly PromisePool<AutoResetUniTaskCompletionSource<T>> pool = new PromisePool<AutoResetUniTaskCompletionSource<T>>();
|
static readonly PromisePool<AutoResetUniTaskCompletionSource<T>> pool = new PromisePool<AutoResetUniTaskCompletionSource<T>>();
|
||||||
|
|
||||||
|
@ -892,7 +529,7 @@ namespace UniRx.Async
|
||||||
public static AutoResetUniTaskCompletionSource<T> CreateFromCanceled(CancellationToken cancellationToken, out short token)
|
public static AutoResetUniTaskCompletionSource<T> CreateFromCanceled(CancellationToken cancellationToken, out short token)
|
||||||
{
|
{
|
||||||
var source = Create();
|
var source = Create();
|
||||||
source.SetCancellation(cancellationToken);
|
source.SetCanceled(cancellationToken);
|
||||||
token = source.core.Version;
|
token = source.core.Version;
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
@ -913,11 +550,11 @@ namespace UniRx.Async
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UniTask2<T> Task
|
public UniTask<T> Task
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return new UniTask2<T>(this, core.Version);
|
return new UniTask<T>(this, core.Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,7 +565,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
public void SetCanceled(CancellationToken cancellationToken = default)
|
public void SetCanceled(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
core.SetCancellation(cancellationToken);
|
core.SetCanceled(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetException(Exception exception)
|
public void SetException(Exception exception)
|
||||||
|
@ -983,16 +620,6 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static class UniTaskCompletionSourceCoreShared // separated out of generic to avoid unnecessary duplication
|
|
||||||
{
|
|
||||||
internal static readonly Action<object> s_sentinel = CompletionSentinel;
|
|
||||||
|
|
||||||
private static void CompletionSentinel(object _) // named method to aid debugging
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("The sentinel delegate should never be invoked.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -10,12 +10,12 @@ using UniRx.Async.Internal;
|
||||||
|
|
||||||
namespace UniRx.Async
|
namespace UniRx.Async
|
||||||
{
|
{
|
||||||
public static partial class UniTaskExtensions2
|
public static partial class UniTaskExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert UniTask -> UniTask[AsyncUnit].
|
/// Convert UniTask -> UniTask[AsyncUnit].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static UniTask2<AsyncUnit> AsAsyncUnitUniTask(this UniTask2 task)
|
public static UniTask<AsyncUnit> AsAsyncUnitUniTask(this UniTask task)
|
||||||
{
|
{
|
||||||
// use implicit conversion
|
// use implicit conversion
|
||||||
return task;
|
return task;
|
||||||
|
@ -24,7 +24,7 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert UniTask[T] -> UniTask.
|
/// Convert UniTask[T] -> UniTask.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static UniTask2 AsUniTask<T>(this UniTask2<T> task)
|
public static UniTask AsUniTask<T>(this UniTask<T> task)
|
||||||
{
|
{
|
||||||
// use implicit conversion
|
// use implicit conversion
|
||||||
return task;
|
return task;
|
||||||
|
@ -33,13 +33,13 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert Task[T] -> UniTask[T].
|
/// Convert Task[T] -> UniTask[T].
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static UniTask2<T> AsUniTask<T>(this Task<T> task, bool useCurrentSynchronizationContext = true)
|
public static UniTask<T> AsUniTask<T>(this Task<T> task, bool useCurrentSynchronizationContext = true)
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2<T>();
|
var promise = new UniTaskCompletionSource<T>();
|
||||||
|
|
||||||
task.ContinueWith((x, state) =>
|
task.ContinueWith((x, state) =>
|
||||||
{
|
{
|
||||||
var p = (UniTaskCompletionSource2<T>)state;
|
var p = (UniTaskCompletionSource<T>)state;
|
||||||
|
|
||||||
switch (x.Status)
|
switch (x.Status)
|
||||||
{
|
{
|
||||||
|
@ -63,13 +63,13 @@ namespace UniRx.Async
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert Task -> UniTask.
|
/// Convert Task -> UniTask.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static UniTask2 AsUniTask(this Task task, bool useCurrentSynchronizationContext = true)
|
public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true)
|
||||||
{
|
{
|
||||||
var promise = new UniTaskCompletionSource2();
|
var promise = new UniTaskCompletionSource();
|
||||||
|
|
||||||
task.ContinueWith((x, state) =>
|
task.ContinueWith((x, state) =>
|
||||||
{
|
{
|
||||||
var p = (UniTaskCompletionSource2)state;
|
var p = (UniTaskCompletionSource)state;
|
||||||
|
|
||||||
switch (x.Status)
|
switch (x.Status)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +90,7 @@ namespace UniRx.Async
|
||||||
return promise.Task;
|
return promise.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task<T> AsTask<T>(this UniTask2<T> task)
|
public static Task<T> AsTask<T>(this UniTask<T> task)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -112,7 +112,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
awaiter.SourceOnCompleted(state =>
|
awaiter.SourceOnCompleted(state =>
|
||||||
{
|
{
|
||||||
var (inTcs, inAwaiter) = ((TaskCompletionSource<T>, UniTask2<T>.Awaiter))state;
|
var (inTcs, inAwaiter) = ((TaskCompletionSource<T>, UniTask<T>.Awaiter))state;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = inAwaiter.GetResult();
|
var result = inAwaiter.GetResult();
|
||||||
|
@ -132,7 +132,7 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task AsTask(this UniTask2 task)
|
public static Task AsTask(this UniTask task)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -154,7 +154,7 @@ namespace UniRx.Async
|
||||||
|
|
||||||
awaiter.SourceOnCompleted(state =>
|
awaiter.SourceOnCompleted(state =>
|
||||||
{
|
{
|
||||||
var (inTcs, inAwaiter) = ((TaskCompletionSource<object>, UniTask2.Awaiter))state;
|
var (inTcs, inAwaiter) = ((TaskCompletionSource<object>, UniTask.Awaiter))state;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
inAwaiter.GetResult();
|
inAwaiter.GetResult();
|
||||||
|
@ -174,481 +174,6 @@ namespace UniRx.Async
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerator ToCoroutine<T>(this UniTask2<T> task, Action<T> resultHandler = null, Action<Exception> exceptionHandler = null)
|
|
||||||
{
|
|
||||||
return new ToCoroutineEnumerator<T>(task, resultHandler, exceptionHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerator ToCoroutine(this UniTask2 task, Action<Exception> exceptionHandler = null)
|
|
||||||
{
|
|
||||||
return new ToCoroutineEnumerator(task, exceptionHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniTask Timeout(this UniTask2 task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
|
||||||
{
|
|
||||||
return Timeout(task.AsAsyncUnitUniTask(), timeout, ignoreTimeScale, timeoutCheckTiming, taskCancellationTokenSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: require UniTask2.Delay, WhenAny, etc...
|
|
||||||
|
|
||||||
public static async UniTask<T> Timeout<T>(this UniTask2<T> task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
|
||||||
{
|
|
||||||
// left, right both suppress operation canceled exception.
|
|
||||||
|
|
||||||
var delayCancellationTokenSource = new CancellationTokenSource();
|
|
||||||
var timeoutTask = (UniTask)UniTask.Delay(timeout, ignoreTimeScale, timeoutCheckTiming).SuppressCancellationThrow();
|
|
||||||
|
|
||||||
var (hasValue, value) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask);
|
|
||||||
|
|
||||||
if (!hasValue)
|
|
||||||
{
|
|
||||||
if (taskCancellationTokenSource != null)
|
|
||||||
{
|
|
||||||
taskCancellationTokenSource.Cancel();
|
|
||||||
taskCancellationTokenSource.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new TimeoutException("Exceed Timeout:" + timeout);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delayCancellationTokenSource.Cancel();
|
|
||||||
delayCancellationTokenSource.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.IsCanceled)
|
|
||||||
{
|
|
||||||
Error.ThrowOperationCanceledException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return value.Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled).
|
|
||||||
/// </summary>
|
|
||||||
public static async UniTask2<bool> TimeoutWithoutException(this UniTask2 task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
|
||||||
{
|
|
||||||
var v = await TimeoutWithoutException(task.AsAsyncUnitUniTask(), timeout, ignoreTimeScale, timeoutCheckTiming, taskCancellationTokenSource);
|
|
||||||
return v.IsTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Timeout with suppress OperationCanceledException. Returns (bool IsTimeout, T Result).
|
|
||||||
/// </summary>
|
|
||||||
public static async UniTask2<(bool IsTimeout, T Result)> TimeoutWithoutException<T>(this UniTask2<T> task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
|
||||||
{
|
|
||||||
// left, right both suppress operation canceled exception.
|
|
||||||
|
|
||||||
var delayCancellationTokenSource = new CancellationTokenSource();
|
|
||||||
var timeoutTask = (UniTask)UniTask.Delay(timeout, ignoreTimeScale, timeoutCheckTiming).SuppressCancellationThrow();
|
|
||||||
|
|
||||||
var (hasValue, value) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask);
|
|
||||||
|
|
||||||
if (!hasValue)
|
|
||||||
{
|
|
||||||
if (taskCancellationTokenSource != null)
|
|
||||||
{
|
|
||||||
taskCancellationTokenSource.Cancel();
|
|
||||||
taskCancellationTokenSource.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (true, default(T));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delayCancellationTokenSource.Cancel();
|
|
||||||
delayCancellationTokenSource.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.IsCanceled)
|
|
||||||
{
|
|
||||||
Error.ThrowOperationCanceledException();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (false, value.Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Forget(this UniTask2 task)
|
|
||||||
{
|
|
||||||
ForgetCore(task).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Forget(this UniTask2 task, Action<Exception> exceptionHandler, bool handleExceptionOnMainThread = true)
|
|
||||||
{
|
|
||||||
if (exceptionHandler == null)
|
|
||||||
{
|
|
||||||
ForgetCore(task).Forget();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ForgetCoreWithCatch(task, exceptionHandler, handleExceptionOnMainThread).Forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UniTask to UniTaskVoid
|
|
||||||
static async UniTaskVoid ForgetCore(UniTask2 task)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async UniTaskVoid ForgetCoreWithCatch(UniTask2 task, Action<Exception> exceptionHandler, bool handleExceptionOnMainThread)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (handleExceptionOnMainThread)
|
|
||||||
{
|
|
||||||
await UniTask2.SwitchToMainThread();
|
|
||||||
}
|
|
||||||
exceptionHandler(ex);
|
|
||||||
}
|
|
||||||
catch (Exception ex2)
|
|
||||||
{
|
|
||||||
UniTaskScheduler.PublishUnobservedTaskException(ex2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Forget<T>(this UniTask2<T> task)
|
|
||||||
{
|
|
||||||
ForgetCore(task).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Forget<T>(this UniTask2<T> task, Action<Exception> exceptionHandler, bool handleExceptionOnMainThread = true)
|
|
||||||
{
|
|
||||||
if (exceptionHandler == null)
|
|
||||||
{
|
|
||||||
ForgetCore(task).Forget();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ForgetCoreWithCatch(task, exceptionHandler, handleExceptionOnMainThread).Forget();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UniTask to UniTaskVoid
|
|
||||||
static async UniTaskVoid ForgetCore<T>(UniTask2<T> task)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async UniTaskVoid ForgetCoreWithCatch<T>(UniTask2<T> task, Action<Exception> exceptionHandler, bool handleExceptionOnMainThread)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (handleExceptionOnMainThread)
|
|
||||||
{
|
|
||||||
await UniTask.SwitchToMainThread();
|
|
||||||
}
|
|
||||||
exceptionHandler(ex);
|
|
||||||
}
|
|
||||||
catch (Exception ex2)
|
|
||||||
{
|
|
||||||
UniTaskScheduler.PublishUnobservedTaskException(ex2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 ContinueWith<T>(this UniTask2<T> task, Action<T> continuationFunction)
|
|
||||||
{
|
|
||||||
continuationFunction(await task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 ContinueWith<T>(this UniTask2<T> task, Func<T, UniTask2> continuationFunction)
|
|
||||||
{
|
|
||||||
await continuationFunction(await task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<TR> ContinueWith<T, TR>(this UniTask2<T> task, Func<T, TR> continuationFunction)
|
|
||||||
{
|
|
||||||
return continuationFunction(await task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<TR> ContinueWith<T, TR>(this UniTask2<T> task, Func<T, UniTask2<TR>> continuationFunction)
|
|
||||||
{
|
|
||||||
return await continuationFunction(await task);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 ContinueWith(this UniTask2 task, Action continuationFunction)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
continuationFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 ContinueWith(this UniTask2 task, Func<UniTask2> continuationFunction)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
await continuationFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<T> ContinueWith<T>(this UniTask2 task, Func<T> continuationFunction)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
return continuationFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<T> ContinueWith<T>(this UniTask2 task, Func<UniTask2<T>> continuationFunction)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
return await continuationFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 ConfigureAwait(this Task task, PlayerLoopTiming timing)
|
|
||||||
{
|
|
||||||
await task.ConfigureAwait(false);
|
|
||||||
await UniTask2.Yield(timing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<T> ConfigureAwait<T>(this Task<T> task, PlayerLoopTiming timing)
|
|
||||||
{
|
|
||||||
var v = await task.ConfigureAwait(false);
|
|
||||||
await UniTask2.Yield(timing);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 ConfigureAwait(this UniTask2 task, PlayerLoopTiming timing)
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
await UniTask2.Yield(timing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<T> ConfigureAwait<T>(this UniTask2<T> task, PlayerLoopTiming timing)
|
|
||||||
{
|
|
||||||
var v = await task;
|
|
||||||
await UniTask2.Yield(timing);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2<T> Unwrap<T>(this UniTask2<UniTask2<T>> task)
|
|
||||||
{
|
|
||||||
return await await task;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async UniTask2 Unwrap<T>(this UniTask2<UniTask2> task)
|
|
||||||
{
|
|
||||||
await await task;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToCoroutineEnumerator : IEnumerator
|
|
||||||
{
|
|
||||||
bool completed;
|
|
||||||
UniTask2 task;
|
|
||||||
Action<Exception> exceptionHandler = null;
|
|
||||||
bool isStarted = false;
|
|
||||||
ExceptionDispatchInfo exception;
|
|
||||||
|
|
||||||
public ToCoroutineEnumerator(UniTask2 task, Action<Exception> exceptionHandler)
|
|
||||||
{
|
|
||||||
completed = false;
|
|
||||||
this.exceptionHandler = exceptionHandler;
|
|
||||||
this.task = task;
|
|
||||||
}
|
|
||||||
|
|
||||||
async UniTaskVoid RunTask(UniTask2 task)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await task;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (exceptionHandler != null)
|
|
||||||
{
|
|
||||||
exceptionHandler(ex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.exception = ExceptionDispatchInfo.Capture(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
completed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Current => null;
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
if (!isStarted)
|
|
||||||
{
|
|
||||||
isStarted = true;
|
|
||||||
RunTask(task).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ToCoroutineEnumerator<T> : IEnumerator
|
|
||||||
{
|
|
||||||
bool completed;
|
|
||||||
Action<T> resultHandler = null;
|
|
||||||
Action<Exception> exceptionHandler = null;
|
|
||||||
bool isStarted = false;
|
|
||||||
UniTask2<T> task;
|
|
||||||
object current = null;
|
|
||||||
ExceptionDispatchInfo exception;
|
|
||||||
|
|
||||||
public ToCoroutineEnumerator(UniTask2<T> task, Action<T> resultHandler, Action<Exception> exceptionHandler)
|
|
||||||
{
|
|
||||||
completed = false;
|
|
||||||
this.task = task;
|
|
||||||
this.resultHandler = resultHandler;
|
|
||||||
this.exceptionHandler = exceptionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
async UniTaskVoid RunTask(UniTask2<T> task)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var value = await task;
|
|
||||||
current = value; // boxed if T is struct...
|
|
||||||
if (resultHandler != null)
|
|
||||||
{
|
|
||||||
resultHandler(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (exceptionHandler != null)
|
|
||||||
{
|
|
||||||
exceptionHandler(ex);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this.exception = ExceptionDispatchInfo.Capture(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
completed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Current => current;
|
|
||||||
|
|
||||||
public bool MoveNext()
|
|
||||||
{
|
|
||||||
if (!isStarted)
|
|
||||||
{
|
|
||||||
isStarted = true;
|
|
||||||
RunTask(task).Forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !completed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO:remove
|
|
||||||
public static partial class UniTaskExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Convert UniTask -> UniTask[AsyncUnit].
|
|
||||||
/// </summary>
|
|
||||||
public static UniTask<AsyncUnit> AsAsyncUnitUniTask(this UniTask task)
|
|
||||||
{
|
|
||||||
// use implicit conversion
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convert Task[T] -> UniTask[T].
|
|
||||||
/// </summary>
|
|
||||||
public static UniTask<T> AsUniTask<T>(this Task<T> task, bool useCurrentSynchronizationContext = true)
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<T>();
|
|
||||||
|
|
||||||
task.ContinueWith((x, state) =>
|
|
||||||
{
|
|
||||||
var p = (UniTaskCompletionSource<T>)state;
|
|
||||||
|
|
||||||
switch (x.Status)
|
|
||||||
{
|
|
||||||
case TaskStatus.Canceled:
|
|
||||||
p.TrySetCanceled();
|
|
||||||
break;
|
|
||||||
case TaskStatus.Faulted:
|
|
||||||
p.TrySetException(x.Exception);
|
|
||||||
break;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
p.TrySetResult(x.Result);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current);
|
|
||||||
|
|
||||||
return new UniTask<T>(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convert Task -> UniTask.
|
|
||||||
/// </summary>
|
|
||||||
public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true)
|
|
||||||
{
|
|
||||||
var promise = new UniTaskCompletionSource<AsyncUnit>();
|
|
||||||
|
|
||||||
task.ContinueWith((x, state) =>
|
|
||||||
{
|
|
||||||
var p = (UniTaskCompletionSource<AsyncUnit>)state;
|
|
||||||
|
|
||||||
switch (x.Status)
|
|
||||||
{
|
|
||||||
case TaskStatus.Canceled:
|
|
||||||
p.TrySetCanceled();
|
|
||||||
break;
|
|
||||||
case TaskStatus.Faulted:
|
|
||||||
p.TrySetException(x.Exception);
|
|
||||||
break;
|
|
||||||
case TaskStatus.RanToCompletion:
|
|
||||||
p.TrySetResult(default(AsyncUnit));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new NotSupportedException();
|
|
||||||
}
|
|
||||||
}, promise, useCurrentSynchronizationContext ? TaskScheduler.FromCurrentSynchronizationContext() : TaskScheduler.Current);
|
|
||||||
|
|
||||||
return new UniTask(promise);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerator ToCoroutine<T>(this UniTask<T> task, Action<T> resultHandler = null, Action<Exception> exceptionHandler = null)
|
public static IEnumerator ToCoroutine<T>(this UniTask<T> task, Action<T> resultHandler = null, Action<Exception> exceptionHandler = null)
|
||||||
{
|
{
|
||||||
return new ToCoroutineEnumerator<T>(task, resultHandler, exceptionHandler);
|
return new ToCoroutineEnumerator<T>(task, resultHandler, exceptionHandler);
|
||||||
|
@ -664,6 +189,8 @@ namespace UniRx.Async
|
||||||
return Timeout(task.AsAsyncUnitUniTask(), timeout, ignoreTimeScale, timeoutCheckTiming, taskCancellationTokenSource);
|
return Timeout(task.AsAsyncUnitUniTask(), timeout, ignoreTimeScale, timeoutCheckTiming, taskCancellationTokenSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: require UniTask2.Delay, WhenAny, etc...
|
||||||
|
|
||||||
public static async UniTask<T> Timeout<T>(this UniTask<T> task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
public static async UniTask<T> Timeout<T>(this UniTask<T> task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
||||||
{
|
{
|
||||||
// left, right both suppress operation canceled exception.
|
// left, right both suppress operation canceled exception.
|
||||||
|
@ -1001,7 +528,7 @@ namespace UniRx.Async
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var value = await task;
|
var value = await task;
|
||||||
current = value;
|
current = value; // boxed if T is struct...
|
||||||
if (resultHandler != null)
|
if (resultHandler != null)
|
||||||
{
|
{
|
||||||
resultHandler(value);
|
resultHandler(value);
|
||||||
|
|
Loading…
Reference in New Issue