diff --git a/Assets/Scenes/SandboxMain.cs b/Assets/Scenes/SandboxMain.cs index 459aac0..528040e 100644 --- a/Assets/Scenes/SandboxMain.cs +++ b/Assets/Scenes/SandboxMain.cs @@ -17,7 +17,7 @@ public class SandboxMain : MonoBehaviour CancellationTokenSource cts; - UniTaskCompletionSource2 ucs; + UniTaskCompletionSource ucs; void Start() { @@ -38,7 +38,7 @@ public class SandboxMain : MonoBehaviour Application.logMessageReceived += Application_logMessageReceived; - ucs = new UniTaskCompletionSource2(); + ucs = new UniTaskCompletionSource(); okButton.onClick.AddListener(async () => { @@ -60,7 +60,7 @@ public class SandboxMain : MonoBehaviour text.text += "\n" + condition; } - async UniTask2 OuterAsync(bool b) + async UniTask OuterAsync(bool b) { UnityEngine.Debug.Log("START OUTER"); @@ -72,14 +72,14 @@ public class SandboxMain : MonoBehaviour // throw new InvalidOperationException("NAZO ERROR!?"); // error!? } - async UniTask2 InnerAsync(bool b) + async UniTask InnerAsync(bool b) { if (b) { UnityEngine.Debug.Log("Start delay:" + Time.frameCount); - await UniTask2.DelayFrame(60); + await UniTask.DelayFrame(60); UnityEngine.Debug.Log("End delay:" + Time.frameCount); - await UniTask2.DelayFrame(60); + await UniTask.DelayFrame(60); UnityEngine.Debug.Log("Onemore end delay:" + Time.frameCount); } else diff --git a/Assets/UniRx.Async/CompilerServices/AsyncUniTaskMethodBuilder.cs b/Assets/UniRx.Async/CompilerServices/AsyncUniTaskMethodBuilder.cs index 31f9d34..e53f0f2 100644 --- a/Assets/UniRx.Async/CompilerServices/AsyncUniTaskMethodBuilder.cs +++ b/Assets/UniRx.Async/CompilerServices/AsyncUniTaskMethodBuilder.cs @@ -10,274 +10,8 @@ using System.Security; 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(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(); - moveNext = runner.Run; - runner.StateMachine = stateMachine; // set after create delegate. - } - - awaiter.OnCompleted(moveNext); - } - - // 6. AwaitUnsafeOnCompleted - [DebuggerHidden] - [SecuritySafeCritical] - public void AwaitUnsafeOnCompleted(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(); - moveNext = runner.Run; - runner.StateMachine = stateMachine; // set after create delegate. - } - - awaiter.UnsafeOnCompleted(moveNext); - } - - // 7. Start - [DebuggerHidden] - public void Start(ref TStateMachine stateMachine) - where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - // 8. SetStateMachine - [DebuggerHidden] - public void SetStateMachine(IAsyncStateMachine stateMachine) - { - } - } - - // TODO:Remove - public struct AsyncUniTaskMethodBuilder - { - T result; - 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 new UniTask(promise); - } - - if (moveNext == null) - { - return new UniTask(result); - } - else - { - promise = new UniTaskCompletionSource(); - return new UniTask(promise); - } - } - } - - // 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(T result) - { - if (moveNext == null) - { - this.result = result; - } - else - { - if (promise == null) - { - promise = new UniTaskCompletionSource(); - } - promise.TrySetResult(result); - } - } - - // 5. AwaitOnCompleted - [DebuggerHidden] - public void AwaitOnCompleted(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(); - moveNext = runner.Run; - runner.StateMachine = stateMachine; // set after create delegate. - } - - awaiter.OnCompleted(moveNext); - } - - // 6. AwaitUnsafeOnCompleted - [DebuggerHidden] - [SecuritySafeCritical] - public void AwaitUnsafeOnCompleted(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(); - moveNext = runner.Run; - runner.StateMachine = stateMachine; // set after create delegate. - } - - awaiter.UnsafeOnCompleted(moveNext); - } - - // 7. Start - [DebuggerHidden] - public void Start(ref TStateMachine stateMachine) - where TStateMachine : IAsyncStateMachine - { - stateMachine.MoveNext(); - } - - // 8. SetStateMachine - [DebuggerHidden] - public void SetStateMachine(IAsyncStateMachine stateMachine) - { - } - } - - - - - [StructLayout(LayoutKind.Auto)] - public struct AsyncUniTask2MethodBuilder + public struct AsyncUniTaskMethodBuilder { // cache items. AutoResetUniTaskCompletionSource promise; @@ -286,13 +20,13 @@ namespace UniRx.Async.CompilerServices // 1. Static Create method. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncUniTask2MethodBuilder Create() + public static AsyncUniTaskMethodBuilder Create() { return default; } // 2. TaskLike Task property. - public UniTask2 Task + public UniTask Task { [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -305,7 +39,7 @@ namespace UniRx.Async.CompilerServices if (runner == null) { - return UniTask2.CompletedTask; + return UniTask.CompletedTask; } promise = AutoResetUniTaskCompletionSource.Create(); @@ -363,7 +97,7 @@ namespace UniRx.Async.CompilerServices } if (runner == null) { - runner = MoveNextRunner2.Create(ref stateMachine); + runner = MoveNextRunner.Create(ref stateMachine); } awaiter.OnCompleted(runner.CallMoveNext); @@ -382,7 +116,7 @@ namespace UniRx.Async.CompilerServices } if (runner == null) { - runner = MoveNextRunner2.Create(ref stateMachine); + runner = MoveNextRunner.Create(ref stateMachine); } awaiter.OnCompleted(runner.CallMoveNext); @@ -405,7 +139,7 @@ namespace UniRx.Async.CompilerServices } [StructLayout(LayoutKind.Auto)] - public struct AsyncUniTask2MethodBuilder + public struct AsyncUniTaskMethodBuilder { // cache items. AutoResetUniTaskCompletionSource promise; @@ -415,14 +149,14 @@ namespace UniRx.Async.CompilerServices // 1. Static Create method. [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static AsyncUniTask2MethodBuilder Create() + public static AsyncUniTaskMethodBuilder Create() { return default; } // 2. TaskLike Task property. [DebuggerHidden] - public UniTask2 Task + public UniTask Task { get { @@ -433,7 +167,7 @@ namespace UniRx.Async.CompilerServices if (runner == null) { - return UniTask2.FromResult(result); + return UniTask.FromResult(result); } promise = AutoResetUniTaskCompletionSource.Create(); @@ -494,7 +228,7 @@ namespace UniRx.Async.CompilerServices } if (runner == null) { - runner = MoveNextRunner2.Create(ref stateMachine); + runner = MoveNextRunner.Create(ref stateMachine); } awaiter.OnCompleted(runner.CallMoveNext); @@ -513,7 +247,7 @@ namespace UniRx.Async.CompilerServices } if (runner == null) { - runner = MoveNextRunner2.Create(ref stateMachine); + runner = MoveNextRunner.Create(ref stateMachine); } awaiter.OnCompleted(runner.CallMoveNext); diff --git a/Assets/UniRx.Async/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs b/Assets/UniRx.Async/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs index 9fad249..2a3b43f 100644 --- a/Assets/UniRx.Async/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs +++ b/Assets/UniRx.Async/CompilerServices/AsyncUniTaskVoidMethodBuilder.cs @@ -66,7 +66,7 @@ namespace UniRx.Async.CompilerServices { if (runner == null) { - runner = MoveNextRunner2.Create(ref stateMachine); + runner = MoveNextRunner.Create(ref stateMachine); } awaiter.OnCompleted(runner.CallMoveNext); @@ -81,7 +81,7 @@ namespace UniRx.Async.CompilerServices { if (runner == null) { - runner = MoveNextRunner2.Create(ref stateMachine); + runner = MoveNextRunner.Create(ref stateMachine); } awaiter.OnCompleted(runner.CallMoveNext); diff --git a/Assets/UniRx.Async/CompilerServices/MoveNextRunner.cs b/Assets/UniRx.Async/CompilerServices/MoveNextRunner.cs index 7c7155f..365ca79 100644 --- a/Assets/UniRx.Async/CompilerServices/MoveNextRunner.cs +++ b/Assets/UniRx.Async/CompilerServices/MoveNextRunner.cs @@ -9,43 +9,30 @@ using UniRx.Async.Internal; namespace UniRx.Async.CompilerServices { - // TODO: Remove it. - internal class MoveNextRunner - where TStateMachine : IAsyncStateMachine - { - public TStateMachine StateMachine; - - [DebuggerHidden] - public void Run() - { - StateMachine.MoveNext(); - } - } - internal interface IMoveNextRunner { Action CallMoveNext { get; } void Return(); } - internal class MoveNextRunner2 : IMoveNextRunner, IPromisePoolItem + internal class MoveNextRunner : IMoveNextRunner, IPromisePoolItem where TStateMachine : IAsyncStateMachine { - static PromisePool> pool = new PromisePool>(); + static PromisePool> pool = new PromisePool>(); TStateMachine stateMachine; internal readonly Action callMoveNext; public Action CallMoveNext => callMoveNext; - MoveNextRunner2() + MoveNextRunner() { callMoveNext = MoveNext; } - public static MoveNextRunner2 Create(ref TStateMachine stateMachine) + public static MoveNextRunner Create(ref TStateMachine stateMachine) { - var result = pool.TryRent() ?? new MoveNextRunner2(); + var result = pool.TryRent() ?? new MoveNextRunner(); result.stateMachine = stateMachine; return result; } diff --git a/Assets/UniRx.Async/UniTask.Bridge.cs b/Assets/UniRx.Async/UniTask.Bridge.cs index a9ecbf6..814bd02 100644 --- a/Assets/UniRx.Async/UniTask.Bridge.cs +++ b/Assets/UniRx.Async/UniTask.Bridge.cs @@ -8,14 +8,6 @@ namespace UniRx.Async { // UnityEngine Bridges. - public partial struct UniTask2 - { - public static IEnumerator ToCoroutine(Func taskFactory) - { - return taskFactory().ToCoroutine(); - } - } - public partial struct UniTask { public static IEnumerator ToCoroutine(Func taskFactory) diff --git a/Assets/UniRx.Async/UniTask.Delay.cs b/Assets/UniRx.Async/UniTask.Delay.cs index 25e8b5f..0ab0fb2 100644 --- a/Assets/UniRx.Async/UniTask.Delay.cs +++ b/Assets/UniRx.Async/UniTask.Delay.cs @@ -9,31 +9,30 @@ using UnityEngine; namespace UniRx.Async { - // TODO:rename - public partial struct UniTask2 + public partial struct UniTask { - public static YieldAwaitable2 Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update) + public static YieldAwaitable Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update) { // 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) { 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); if (delayTimeSpan < TimeSpan.Zero) @@ -42,11 +41,11 @@ namespace UniRx.Async } return (ignoreTimeScale) - ? new UniTask2(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token) - : new UniTask2(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token); + ? new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var 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) { @@ -54,8 +53,8 @@ namespace UniRx.Async } return (ignoreTimeScale) - ? new UniTask2(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token) - : new UniTask2(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token); + ? new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token) + : new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token); } 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 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 - { - 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 { readonly PlayerLoopTiming timing; diff --git a/Assets/UniRx.Async/UniTask.Factory.cs b/Assets/UniRx.Async/UniTask.Factory.cs index 9893ad2..e97d36e 100644 --- a/Assets/UniRx.Async/UniTask.Factory.cs +++ b/Assets/UniRx.Async/UniTask.Factory.cs @@ -7,11 +7,11 @@ using UnityEngine.Events; namespace UniRx.Async { - public partial struct UniTask2 + public partial struct UniTask { - static readonly UniTask2 CanceledUniTask = new Func(() => + static readonly UniTask CanceledUniTask = new Func(() => { - var promise = new UniTaskCompletionSource2(); + var promise = new UniTaskCompletionSource(); promise.SetCanceled(CancellationToken.None); promise.MarkHandled(); return promise.Task; @@ -19,41 +19,41 @@ namespace UniRx.Async static class CanceledUniTaskCache { - public static readonly UniTask2 Task; + public static readonly UniTask Task; static CanceledUniTaskCache() { - var promise = new UniTaskCompletionSource2(); + var promise = new UniTaskCompletionSource(); promise.SetCanceled(CancellationToken.None); promise.MarkHandled(); 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.MarkHandled(); return promise.Task; } - public static UniTask2 FromException(Exception ex) + public static UniTask FromException(Exception ex) { - var promise = new UniTaskCompletionSource2(); + var promise = new UniTaskCompletionSource(); promise.SetException(ex); promise.MarkHandled(); return promise.Task; } - public static UniTask2 FromResult(T value) + public static UniTask FromResult(T value) { - return new UniTask2(value); + return new UniTask(value); } - public static UniTask2 FromCanceled(CancellationToken cancellationToken = default) + public static UniTask FromCanceled(CancellationToken cancellationToken = default) { if (cancellationToken == CancellationToken.None) { @@ -61,14 +61,14 @@ namespace UniRx.Async } else { - var promise = new UniTaskCompletionSource2(); + var promise = new UniTaskCompletionSource(); promise.SetCanceled(cancellationToken); promise.MarkHandled(); return promise.Task; } } - public static UniTask2 FromCanceled(CancellationToken cancellationToken = default) + public static UniTask FromCanceled(CancellationToken cancellationToken = default) { if (cancellationToken == CancellationToken.None) { @@ -76,7 +76,7 @@ namespace UniRx.Async } else { - var promise = new UniTaskCompletionSource2(); + var promise = new UniTaskCompletionSource(); promise.SetCanceled(cancellationToken); promise.MarkHandled(); return promise.Task; @@ -120,143 +120,15 @@ namespace UniRx.Async } } - - // TODO:remove - public partial struct UniTask - { - static readonly UniTask CanceledUniTask = new Func(() => - { - var promise = new UniTaskCompletionSource(); - 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(); - promise.TrySetException(ex); - promise.MarkHandled(); - return new UniTask(promise); - } - - public static UniTask FromException(Exception ex) - { - var promise = new UniTaskCompletionSource(); - promise.TrySetException(ex); - promise.MarkHandled(); - return new UniTask(promise); - } - - public static UniTask FromResult(T value) - { - return new UniTask(value); - } - - public static UniTask FromCanceled() - { - return CanceledUniTask; - } - - public static UniTask FromCanceled() - { - return CanceledUniTaskCache.Task; - } - - public static UniTask FromCanceled(CancellationToken token) - { - var promise = new UniTaskCompletionSource(); - promise.TrySetException(new OperationCanceledException(token)); - promise.MarkHandled(); - return new UniTask(promise); - } - - public static UniTask FromCanceled(CancellationToken token) - { - var promise = new UniTaskCompletionSource(); - promise.TrySetException(new OperationCanceledException(token)); - promise.MarkHandled(); - return new UniTask(promise); - } - - /// shorthand of new UniTask[T](Func[UniTask[T]] factory) - public static UniTask Lazy(Func> factory) - { - return new UniTask(factory); - } - - /// - /// helper of create add UniTaskVoid to delegate. - /// For example: FooEvent += () => UniTask.Void(async () => { /* */ }) - /// - public static void Void(Func asyncAction) - { - asyncAction().Forget(); - } - - public static Action VoidAction(Func asyncAction) - { - return () => Void(asyncAction); - } - - public static UnityAction VoidUnityAction(Func asyncAction) - { - return () => Void(asyncAction); - } - - /// - /// helper of create add UniTaskVoid to delegate. - /// For example: FooEvent += (sender, e) => UniTask.Void(async arg => { /* */ }, (sender, e)) - /// - public static void Void(Func asyncAction, T state) - { - asyncAction(state).Forget(); - } - - static class CanceledUniTaskCache - { - public static readonly UniTask Task; - - static CanceledUniTaskCache() - { - var promise = new UniTaskCompletionSource(); - promise.TrySetCanceled(); - promise.MarkHandled(); - Task = new UniTask(promise); - } - } - } - - - // TODO:remove internal static class CompletedTasks { + public static readonly UniTask Completed = new UniTask(); + public static readonly UniTask AsyncUnit = UniTask.FromResult(UniRx.Async.AsyncUnit.Default); public static readonly UniTask True = UniTask.FromResult(true); public static readonly UniTask False = UniTask.FromResult(false); public static readonly UniTask Zero = UniTask.FromResult(0); public static readonly UniTask MinusOne = UniTask.FromResult(-1); public static readonly UniTask One = UniTask.FromResult(1); } - - - // TODO:rename - internal static class CompletedTasks2 - { - public static readonly UniTask2 Completed = new UniTask2(); - public static readonly UniTask2 AsyncUnit = UniTask2.FromResult(UniRx.Async.AsyncUnit.Default); - public static readonly UniTask2 True = UniTask2.FromResult(true); - public static readonly UniTask2 False = UniTask2.FromResult(false); - public static readonly UniTask2 Zero = UniTask2.FromResult(0); - public static readonly UniTask2 MinusOne = UniTask2.FromResult(-1); - public static readonly UniTask2 One = UniTask2.FromResult(1); - } } #endif \ No newline at end of file diff --git a/Assets/UniRx.Async/UniTask.cs b/Assets/UniRx.Async/UniTask.cs index bf71764..1b97d18 100644 --- a/Assets/UniRx.Async/UniTask.cs +++ b/Assets/UniRx.Async/UniTask.cs @@ -25,15 +25,15 @@ namespace UniRx.Async /// /// Lightweight unity specified task-like object. /// - [AsyncMethodBuilder(typeof(AsyncUniTask2MethodBuilder))] - public readonly partial struct UniTask2 + [AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder))] + public readonly partial struct UniTask { readonly IUniTaskSource source; readonly short token; [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public UniTask2(IUniTaskSource source, short token) + public UniTask(IUniTaskSource source, short token) { this.source = source; this.token = token; @@ -60,12 +60,12 @@ namespace UniRx.Async /// /// returns (bool IsCanceled) instead of throws OperationCanceledException. /// - public UniTask2 SuppressCancellationThrow() + public UniTask SuppressCancellationThrow() { var status = Status; - if (status == AwaiterStatus.Succeeded) return CompletedTasks2.False; - if (status == AwaiterStatus.Canceled) return CompletedTasks2.True; - return new UniTask2(new IsCanceledSource(source), token); + if (status == AwaiterStatus.Succeeded) return CompletedTasks.False; + if (status == AwaiterStatus.Canceled) return CompletedTasks.True; + return new UniTask(new IsCanceledSource(source), token); } public override string ToString() @@ -77,7 +77,7 @@ namespace UniRx.Async /// /// Memoizing inner IValueTaskSource. The result UniTask can await multiple. /// - public UniTask2 Preserve() + public UniTask Preserve() { if (source == null) { @@ -85,21 +85,21 @@ namespace UniRx.Async } else { - return new UniTask2(new MemoizeSource(source), token); + return new UniTask(new MemoizeSource(source), token); } } - public static implicit operator UniTask2(UniTask2 task) + public static implicit operator UniTask(UniTask task) { - if (task.source == null) return CompletedTasks2.AsyncUnit; + if (task.source == null) return CompletedTasks.AsyncUnit; var status = task.source.GetStatus(task.token); if (status.IsCompletedSuccessfully()) { - return CompletedTasks2.AsyncUnit; + return CompletedTasks.AsyncUnit; } - return new UniTask2(new AsyncUnitSource(task.source), task.token); + return new UniTask(new AsyncUnitSource(task.source), task.token); } class AsyncUnitSource : IUniTaskSource @@ -261,11 +261,11 @@ namespace UniRx.Async public readonly struct Awaiter : ICriticalNotifyCompletion { - readonly UniTask2 task; + readonly UniTask task; [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Awaiter(in UniTask2 task) + public Awaiter(in UniTask task) { this.task = task; } @@ -336,8 +336,8 @@ namespace UniRx.Async /// /// Lightweight unity specified task-like object. /// - [AsyncMethodBuilder(typeof(AsyncUniTask2MethodBuilder<>))] - public readonly struct UniTask2 + [AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder<>))] + public readonly struct UniTask { readonly IUniTaskSource source; readonly T result; @@ -345,7 +345,7 @@ namespace UniRx.Async [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public UniTask2(T result) + public UniTask(T result) { this.source = default; this.token = default; @@ -354,7 +354,7 @@ namespace UniRx.Async [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public UniTask2(IUniTaskSource source, short token) + public UniTask(IUniTaskSource source, short token) { this.source = source; this.token = token; @@ -381,7 +381,7 @@ namespace UniRx.Async /// /// Memoizing inner IValueTaskSource. The result UniTask can await multiple. /// - public UniTask2 Preserve() + public UniTask Preserve() { if (source == null) { @@ -389,34 +389,34 @@ namespace UniRx.Async } else { - return new UniTask2(new MemoizeSource(source), token); + return new UniTask(new MemoizeSource(source), token); } } - public static implicit operator UniTask2(UniTask2 task) + public static implicit operator UniTask(UniTask task) { - if (task.source == null) return UniTask2.CompletedTask; + if (task.source == null) return UniTask.CompletedTask; var status = task.source.GetStatus(task.token); if (status.IsCompletedSuccessfully()) { - return UniTask2.CompletedTask; + return UniTask.CompletedTask; } - return new UniTask2(task.source, task.token); + return new UniTask(task.source, task.token); } /// /// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException. /// - public UniTask2<(bool IsCanceled, T Result)> SuppressCancellationThrow() + public UniTask<(bool IsCanceled, T Result)> SuppressCancellationThrow() { 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() @@ -568,11 +568,11 @@ namespace UniRx.Async public readonly struct Awaiter : ICriticalNotifyCompletion { - readonly UniTask2 task; + readonly UniTask task; [DebuggerHidden] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Awaiter(in UniTask2 task) + public Awaiter(in UniTask task) { this.task = task; } @@ -649,472 +649,6 @@ namespace UniRx.Async } } } - - - /// - /// Lightweight unity specified task-like object. - /// - [AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder))] - public partial struct UniTask : IEquatable - { - static readonly UniTask DefaultAsyncUnitTask = new UniTask(AsyncUnit.Default); - - readonly IAwaiter awaiter; - - [DebuggerHidden] - public UniTask(IAwaiter awaiter) - { - this.awaiter = awaiter; - } - - [DebuggerHidden] - public UniTask(Func 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); - } - - /// - /// returns (bool IsCanceled) instead of throws OperationCanceledException. - /// - public UniTask SuppressCancellationThrow() - { - var status = Status; - if (status == AwaiterStatus.Succeeded) return CompletedTasks.False; - if (status == AwaiterStatus.Canceled) return CompletedTasks.True; - return new UniTask(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(UniTask task) - { - if (task.awaiter != null) - { - if (task.awaiter.IsCompleted) - { - return DefaultAsyncUnitTask; - } - else - { - // UniTask -> UniTask is free but UniTask -> UniTask requires wrapping cost. - return new UniTask(new AsyncUnitAwaiter(task.awaiter)); - } - } - else - { - return DefaultAsyncUnitTask; - } - } - - class AsyncUnitAwaiter : IAwaiter - { - 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 - { - 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(); - } - } - } - } - - /// - /// Lightweight unity specified task-like object. - /// - [AsyncMethodBuilder(typeof(AsyncUniTaskMethodBuilder<>))] - public struct UniTask : IEquatable> - { - readonly T result; - readonly IAwaiter awaiter; - - [DebuggerHidden] - public UniTask(T result) - { - this.result = result; - this.awaiter = null; - } - - [DebuggerHidden] - public UniTask(IAwaiter awaiter) - { - this.result = default(T); - this.awaiter = awaiter; - } - - [DebuggerHidden] - public UniTask(Func> factory) - { - this.result = default(T); - 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 T Result - { - get - { - if (awaiter == null) - { - return result; - } - else - { - return awaiter.GetResult(); - } - } - } - - [DebuggerHidden] - public Awaiter GetAwaiter() - { - return new Awaiter(this); - } - - /// - /// returns (bool IsCanceled, T Result) instead of throws OperationCanceledException. - /// - 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 other) - { - if (this.awaiter == null && other.awaiter == null) - { - return EqualityComparer.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 task) - { - if (task.awaiter != null) - { - return new UniTask(task.awaiter); - } - else - { - return new UniTask(); - } - } - - class IsCanceledAwaiter : IAwaiter<(bool, T)> - { - readonly IAwaiter awaiter; - - public IsCanceledAwaiter(IAwaiter 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 - { - readonly UniTask task; - - [DebuggerHidden] - public Awaiter(in UniTask 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 diff --git a/Assets/UniRx.Async/UniTaskCompletionSource.cs b/Assets/UniRx.Async/UniTaskCompletionSource.cs index 27355a4..73427f8 100644 --- a/Assets/UniRx.Async/UniTaskCompletionSource.cs +++ b/Assets/UniRx.Async/UniTaskCompletionSource.cs @@ -2,7 +2,6 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member using System; -using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; @@ -12,52 +11,24 @@ using UniRx.Async.Internal; 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 { - bool TrySetResult(); + void SetResult(); } public interface IResolvePromise { - bool TrySetResult(T value); + void SetResult(T value); } public interface IRejectPromise { - bool TrySetException(Exception exception); + void SetException(Exception exception); } public interface ICancelPromise { - bool TrySetCanceled(); + void SetCanceled(CancellationToken cancellationToken = default); } public interface IPromise : IResolvePromise, 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(); - list.Add((Action)c); - list.Add(action); - if (Interlocked.CompareExchange(ref continuation, list, c) == c) - { - goto TRYINVOKE; - } - } - - var l = (List)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)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 : IAwaiter, IPromise - { - // 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 Task => new UniTask(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.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(); - list.Add((Action)c); - list.Add(action); - if (Interlocked.CompareExchange(ref continuation, list, c) == c) - { - goto TRYINVOKE; - } - } - - var l = (List)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)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)this).GetResult(); - } - - void INotifyCompletion.OnCompleted(Action continuation) - { - ((ICriticalNotifyCompletion)this).UnsafeOnCompleted(continuation); - } - } - [StructLayout(LayoutKind.Auto)] public struct UniTaskCompletionSourceCore { @@ -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 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 core; bool handled = false; - public UniTaskCompletionSource2() + public UniTaskCompletionSource() { TaskTracker2.TrackActiveTask(this, 2); } @@ -622,11 +259,11 @@ namespace UniRx.Async } } - public UniTask2 Task + public UniTask Task { 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); } - ~UniTaskCompletionSource2() + ~UniTaskCompletionSource() { // clear error information. core.Reset(); } } - public class AutoResetUniTaskCompletionSource : IUniTaskSource, IPromisePoolItem + public class AutoResetUniTaskCompletionSource : IUniTaskSource, IPromisePoolItem, IPromise { static readonly PromisePool pool = new PromisePool(); @@ -722,11 +359,11 @@ namespace UniRx.Async return source; } - public UniTask2 Task + public UniTask Task { 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) { - core.SetCancellation(cancellationToken); + core.SetCanceled(cancellationToken); } public void SetException(Exception exception) @@ -789,12 +426,12 @@ namespace UniRx.Async } } - public class UniTaskCompletionSource2 : IUniTaskSource + public class UniTaskCompletionSource : IUniTaskSource, IPromise { UniTaskCompletionSourceCore core; bool handled = false; - public UniTaskCompletionSource2() + public UniTaskCompletionSource() { TaskTracker2.TrackActiveTask(this, 2); } @@ -809,11 +446,11 @@ namespace UniRx.Async } } - public UniTask2 Task + public UniTask Task { get { - return new UniTask2(this, core.Version); + return new UniTask(this, core.Version); } } @@ -831,7 +468,7 @@ namespace UniRx.Async public void SetCanceled(CancellationToken cancellationToken = default) { - core.SetCancellation(cancellationToken); + core.SetCanceled(cancellationToken); } public void SetException(Exception exception) @@ -865,14 +502,14 @@ namespace UniRx.Async core.OnCompleted(continuation, state, token); } - ~UniTaskCompletionSource2() + ~UniTaskCompletionSource() { // clear error information. core.Reset(); } } - public class AutoResetUniTaskCompletionSource : IUniTaskSource, IPromisePoolItem + public class AutoResetUniTaskCompletionSource : IUniTaskSource, IPromisePoolItem, IPromise { static readonly PromisePool> pool = new PromisePool>(); @@ -892,7 +529,7 @@ namespace UniRx.Async public static AutoResetUniTaskCompletionSource CreateFromCanceled(CancellationToken cancellationToken, out short token) { var source = Create(); - source.SetCancellation(cancellationToken); + source.SetCanceled(cancellationToken); token = source.core.Version; return source; } @@ -913,11 +550,11 @@ namespace UniRx.Async return source; } - public UniTask2 Task + public UniTask Task { get { - return new UniTask2(this, core.Version); + return new UniTask(this, core.Version); } } @@ -928,7 +565,7 @@ namespace UniRx.Async public void SetCanceled(CancellationToken cancellationToken = default) { - core.SetCancellation(cancellationToken); + core.SetCanceled(cancellationToken); } 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 s_sentinel = CompletionSentinel; - - private static void CompletionSentinel(object _) // named method to aid debugging - { - throw new InvalidOperationException("The sentinel delegate should never be invoked."); - } - } } #endif \ No newline at end of file diff --git a/Assets/UniRx.Async/UniTaskExtensions.cs b/Assets/UniRx.Async/UniTaskExtensions.cs index 6cdfaf8..64c0f9b 100644 --- a/Assets/UniRx.Async/UniTaskExtensions.cs +++ b/Assets/UniRx.Async/UniTaskExtensions.cs @@ -10,12 +10,12 @@ using UniRx.Async.Internal; namespace UniRx.Async { - public static partial class UniTaskExtensions2 + public static partial class UniTaskExtensions { /// /// Convert UniTask -> UniTask[AsyncUnit]. /// - public static UniTask2 AsAsyncUnitUniTask(this UniTask2 task) + public static UniTask AsAsyncUnitUniTask(this UniTask task) { // use implicit conversion return task; @@ -24,7 +24,7 @@ namespace UniRx.Async /// /// Convert UniTask[T] -> UniTask. /// - public static UniTask2 AsUniTask(this UniTask2 task) + public static UniTask AsUniTask(this UniTask task) { // use implicit conversion return task; @@ -33,13 +33,13 @@ namespace UniRx.Async /// /// Convert Task[T] -> UniTask[T]. /// - 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) => { - var p = (UniTaskCompletionSource2)state; + var p = (UniTaskCompletionSource)state; switch (x.Status) { @@ -63,13 +63,13 @@ namespace UniRx.Async /// /// Convert Task -> UniTask. /// - 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) => { - var p = (UniTaskCompletionSource2)state; + var p = (UniTaskCompletionSource)state; switch (x.Status) { @@ -90,7 +90,7 @@ namespace UniRx.Async return promise.Task; } - public static Task AsTask(this UniTask2 task) + public static Task AsTask(this UniTask task) { try { @@ -112,7 +112,7 @@ namespace UniRx.Async awaiter.SourceOnCompleted(state => { - var (inTcs, inAwaiter) = ((TaskCompletionSource, UniTask2.Awaiter))state; + var (inTcs, inAwaiter) = ((TaskCompletionSource, UniTask.Awaiter))state; try { 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 { @@ -154,7 +154,7 @@ namespace UniRx.Async awaiter.SourceOnCompleted(state => { - var (inTcs, inAwaiter) = ((TaskCompletionSource, UniTask2.Awaiter))state; + var (inTcs, inAwaiter) = ((TaskCompletionSource, UniTask.Awaiter))state; try { inAwaiter.GetResult(); @@ -174,481 +174,6 @@ namespace UniRx.Async } } - public static IEnumerator ToCoroutine(this UniTask2 task, Action resultHandler = null, Action exceptionHandler = null) - { - return new ToCoroutineEnumerator(task, resultHandler, exceptionHandler); - } - - public static IEnumerator ToCoroutine(this UniTask2 task, Action 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 Timeout(this UniTask2 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; - } - - /// - /// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled). - /// - public static async UniTask2 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; - } - - - /// - /// Timeout with suppress OperationCanceledException. Returns (bool IsTimeout, T Result). - /// - public static async UniTask2<(bool IsTimeout, T Result)> TimeoutWithoutException(this UniTask2 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 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 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(this UniTask2 task) - { - ForgetCore(task).Forget(); - } - - public static void Forget(this UniTask2 task, Action 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 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(this UniTask2 task, Action continuationFunction) - { - continuationFunction(await task); - } - - public static async UniTask2 ContinueWith(this UniTask2 task, Func continuationFunction) - { - await continuationFunction(await task); - } - - public static async UniTask2 ContinueWith(this UniTask2 task, Func continuationFunction) - { - return continuationFunction(await task); - } - - public static async UniTask2 ContinueWith(this UniTask2 task, Func> 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 continuationFunction) - { - await task; - await continuationFunction(); - } - - public static async UniTask2 ContinueWith(this UniTask2 task, Func continuationFunction) - { - await task; - return continuationFunction(); - } - - public static async UniTask2 ContinueWith(this UniTask2 task, Func> 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 ConfigureAwait(this Task 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 ConfigureAwait(this UniTask2 task, PlayerLoopTiming timing) - { - var v = await task; - await UniTask2.Yield(timing); - return v; - } - - public static async UniTask2 Unwrap(this UniTask2> task) - { - return await await task; - } - - public static async UniTask2 Unwrap(this UniTask2 task) - { - await await task; - } - - class ToCoroutineEnumerator : IEnumerator - { - bool completed; - UniTask2 task; - Action exceptionHandler = null; - bool isStarted = false; - ExceptionDispatchInfo exception; - - public ToCoroutineEnumerator(UniTask2 task, Action 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 : IEnumerator - { - bool completed; - Action resultHandler = null; - Action exceptionHandler = null; - bool isStarted = false; - UniTask2 task; - object current = null; - ExceptionDispatchInfo exception; - - public ToCoroutineEnumerator(UniTask2 task, Action resultHandler, Action exceptionHandler) - { - completed = false; - this.task = task; - this.resultHandler = resultHandler; - this.exceptionHandler = exceptionHandler; - } - - async UniTaskVoid RunTask(UniTask2 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 - { - /// - /// Convert UniTask -> UniTask[AsyncUnit]. - /// - public static UniTask AsAsyncUnitUniTask(this UniTask task) - { - // use implicit conversion - return task; - } - - /// - /// Convert Task[T] -> UniTask[T]. - /// - public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true) - { - var promise = new UniTaskCompletionSource(); - - task.ContinueWith((x, state) => - { - var p = (UniTaskCompletionSource)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(promise); - } - - /// - /// Convert Task -> UniTask. - /// - public static UniTask AsUniTask(this Task task, bool useCurrentSynchronizationContext = true) - { - var promise = new UniTaskCompletionSource(); - - task.ContinueWith((x, state) => - { - var p = (UniTaskCompletionSource)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(this UniTask task, Action resultHandler = null, Action exceptionHandler = null) { return new ToCoroutineEnumerator(task, resultHandler, exceptionHandler); @@ -664,6 +189,8 @@ namespace UniRx.Async return Timeout(task.AsAsyncUnitUniTask(), timeout, ignoreTimeScale, timeoutCheckTiming, taskCancellationTokenSource); } + // TODO: require UniTask2.Delay, WhenAny, etc... + public static async UniTask Timeout(this UniTask task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) { // left, right both suppress operation canceled exception. @@ -1001,7 +528,7 @@ namespace UniRx.Async try { var value = await task; - current = value; + current = value; // boxed if T is struct... if (resultHandler != null) { resultHandler(value);