mirror of
https://github.com/Cysharp/UniTask.git
synced 2026-05-19 13:40:11 +00:00
complete infrastructure
This commit is contained in:
@@ -5,10 +5,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace UniRx.Async.CompilerServices
|
||||
{
|
||||
// TODO:Remove
|
||||
public struct AsyncUniTaskMethodBuilder
|
||||
{
|
||||
UniTaskCompletionSource promise;
|
||||
@@ -138,7 +140,7 @@ namespace UniRx.Async.CompilerServices
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO:Remove
|
||||
public struct AsyncUniTaskMethodBuilder<T>
|
||||
{
|
||||
T result;
|
||||
@@ -269,6 +271,247 @@ namespace UniRx.Async.CompilerServices
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTask2MethodBuilder
|
||||
{
|
||||
// cache items.
|
||||
AutoResetUniTaskCompletionSource promise;
|
||||
IMoveNextRunner runner;
|
||||
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static AsyncUniTask2MethodBuilder Create()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
// 2. TaskLike Task property.
|
||||
public UniTask2 Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
return promise.Task;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
promise.SetException(exception);
|
||||
}
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
public void SetResult()
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
promise.SetResult();
|
||||
}
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
}
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
}
|
||||
|
||||
// 7. Start
|
||||
[DebuggerHidden]
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
// 8. SetStateMachine
|
||||
[DebuggerHidden]
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
// don't use boxed stateMachine.
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public struct AsyncUniTask2MethodBuilder<T>
|
||||
{
|
||||
// cache items.
|
||||
AutoResetUniTaskCompletionSource<T> promise;
|
||||
IMoveNextRunner runner;
|
||||
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static AsyncUniTask2MethodBuilder<T> Create()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
// 2. TaskLike Task property.
|
||||
[DebuggerHidden]
|
||||
public UniTask2<T> Task
|
||||
{
|
||||
get
|
||||
{
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
return promise.Task;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
promise.SetException(exception);
|
||||
}
|
||||
|
||||
// 4. SetResult
|
||||
[DebuggerHidden]
|
||||
public void SetResult(T result)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
promise.SetResult(result);
|
||||
}
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
[DebuggerHidden]
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
}
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
[DebuggerHidden]
|
||||
[SecuritySafeCritical]
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (promise == null)
|
||||
{
|
||||
promise = AutoResetUniTaskCompletionSource<T>.Create();
|
||||
}
|
||||
if (runner == null)
|
||||
{
|
||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
}
|
||||
|
||||
// 7. Start
|
||||
[DebuggerHidden]
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
// 8. SetStateMachine
|
||||
[DebuggerHidden]
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
// don't use boxed stateMachine.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,23 +11,38 @@ namespace UniRx.Async.CompilerServices
|
||||
{
|
||||
public struct AsyncUniTaskVoidMethodBuilder
|
||||
{
|
||||
Action moveNext;
|
||||
IMoveNextRunner runner;
|
||||
|
||||
// 1. Static Create method.
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static AsyncUniTaskVoidMethodBuilder Create()
|
||||
{
|
||||
var builder = new AsyncUniTaskVoidMethodBuilder();
|
||||
return builder;
|
||||
return default;
|
||||
}
|
||||
|
||||
// 2. TaskLike Task property(void)
|
||||
public UniTaskVoid Task => default(UniTaskVoid);
|
||||
public UniTaskVoid Task
|
||||
{
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. SetException
|
||||
[DebuggerHidden]
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
// runner is finished, return first.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
|
||||
UniTaskScheduler.PublishUnobservedTaskException(exception);
|
||||
}
|
||||
|
||||
@@ -35,7 +50,12 @@ namespace UniRx.Async.CompilerServices
|
||||
[DebuggerHidden]
|
||||
public void SetResult()
|
||||
{
|
||||
// do nothing
|
||||
// runner is finished, return.
|
||||
if (runner != null)
|
||||
{
|
||||
runner.Return();
|
||||
runner = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. AwaitOnCompleted
|
||||
@@ -44,14 +64,12 @@ namespace UniRx.Async.CompilerServices
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (moveNext == null)
|
||||
if (runner == null)
|
||||
{
|
||||
var runner = new MoveNextRunner<TStateMachine>();
|
||||
moveNext = runner.Run;
|
||||
runner.StateMachine = stateMachine; // set after create delegate.
|
||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
||||
}
|
||||
|
||||
awaiter.OnCompleted(moveNext);
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
}
|
||||
|
||||
// 6. AwaitUnsafeOnCompleted
|
||||
@@ -61,14 +79,12 @@ namespace UniRx.Async.CompilerServices
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
if (moveNext == null)
|
||||
if (runner == null)
|
||||
{
|
||||
var runner = new MoveNextRunner<TStateMachine>();
|
||||
moveNext = runner.Run;
|
||||
runner.StateMachine = stateMachine; // set after create delegate.
|
||||
runner = MoveNextRunner2<TStateMachine>.Create(ref stateMachine);
|
||||
}
|
||||
|
||||
awaiter.UnsafeOnCompleted(moveNext);
|
||||
awaiter.OnCompleted(runner.CallMoveNext);
|
||||
}
|
||||
|
||||
// 7. Start
|
||||
@@ -83,6 +99,7 @@ namespace UniRx.Async.CompilerServices
|
||||
[DebuggerHidden]
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
// don't use boxed stateMachine.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using UniRx.Async.Internal;
|
||||
|
||||
namespace UniRx.Async.CompilerServices
|
||||
{
|
||||
// TODO: Remove it.
|
||||
internal class MoveNextRunner<TStateMachine>
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
@@ -18,6 +21,52 @@ namespace UniRx.Async.CompilerServices
|
||||
StateMachine.MoveNext();
|
||||
}
|
||||
}
|
||||
|
||||
internal interface IMoveNextRunner
|
||||
{
|
||||
Action CallMoveNext { get; }
|
||||
void Return();
|
||||
}
|
||||
|
||||
internal class MoveNextRunner2<TStateMachine> : IMoveNextRunner, IPromisePoolItem
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
static PromisePool<MoveNextRunner2<TStateMachine>> pool = new PromisePool<MoveNextRunner2<TStateMachine>>();
|
||||
|
||||
TStateMachine stateMachine;
|
||||
internal readonly Action callMoveNext;
|
||||
|
||||
public Action CallMoveNext => callMoveNext;
|
||||
|
||||
MoveNextRunner2()
|
||||
{
|
||||
callMoveNext = MoveNext;
|
||||
}
|
||||
|
||||
public static MoveNextRunner2<TStateMachine> Create(ref TStateMachine stateMachine)
|
||||
{
|
||||
var result = pool.TryRent() ?? new MoveNextRunner2<TStateMachine>();
|
||||
result.stateMachine = stateMachine;
|
||||
return result;
|
||||
}
|
||||
|
||||
[DebuggerHidden]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void MoveNext()
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
public void Return()
|
||||
{
|
||||
pool.TryReturn(this);
|
||||
}
|
||||
|
||||
void IPromisePoolItem.Reset()
|
||||
{
|
||||
stateMachine = default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user