mirror of https://github.com/Cysharp/UniTask
Add AsyncInstantiate support
parent
809d23edae
commit
4af6851590
|
@ -0,0 +1,173 @@
|
||||||
|
#if UNITASK_ASYNCINSTANTIATE_SUPPORT
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using UnityEngine;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
|
namespace Cysharp.Threading.Tasks
|
||||||
|
{
|
||||||
|
public static class AsyncInstantiateOperationExtensions
|
||||||
|
{
|
||||||
|
public static UniTask<T[]>.Awaiter GetAwaiter<T>(this AsyncInstantiateOperation<T> operation)
|
||||||
|
where T : Object
|
||||||
|
{
|
||||||
|
return ToUniTask(operation).GetAwaiter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UniTask<T[]> WithCancellation<T>(this AsyncInstantiateOperation<T> operation, CancellationToken cancellationToken)
|
||||||
|
where T : Object
|
||||||
|
{
|
||||||
|
return ToUniTask(operation, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UniTask<T[]> ToUniTask<T>(this AsyncInstantiateOperation<T> operation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default)
|
||||||
|
where T : Object
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
operation.Cancel();
|
||||||
|
|
||||||
|
return UniTask.FromCanceled<T[]>(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operation.isDone)
|
||||||
|
{
|
||||||
|
return UniTask.FromResult(operation.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new UniTask<T[]>(AsyncInstantiateOperationConfiguredSource<T>.Create(operation, timing, progress, cancellationToken, out var token), token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class AsyncInstantiateOperationConfiguredSource<T> : IUniTaskSource<T[]>, IPlayerLoopItem, ITaskPoolNode<AsyncInstantiateOperationConfiguredSource<T>>
|
||||||
|
where T : Object
|
||||||
|
{
|
||||||
|
private static TaskPool<AsyncInstantiateOperationConfiguredSource<T>> pool;
|
||||||
|
private AsyncInstantiateOperationConfiguredSource<T> nextNode;
|
||||||
|
|
||||||
|
private AsyncInstantiateOperation<T> operation;
|
||||||
|
private IProgress<float> progress;
|
||||||
|
private CancellationToken cancellationToken;
|
||||||
|
|
||||||
|
private bool completed;
|
||||||
|
private UniTaskCompletionSourceCore<T[]> core;
|
||||||
|
|
||||||
|
static AsyncInstantiateOperationConfiguredSource()
|
||||||
|
{
|
||||||
|
TaskPool.RegisterSizeGetter(typeof(AsyncInstantiateOperationConfiguredSource<T>), () => pool.Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IUniTaskSource<T[]> Create(AsyncInstantiateOperation<T> operation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||||
|
{
|
||||||
|
if (!pool.TryPop(out var source))
|
||||||
|
{
|
||||||
|
source = new AsyncInstantiateOperationConfiguredSource<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
source.operation = operation;
|
||||||
|
source.progress = progress;
|
||||||
|
source.cancellationToken = cancellationToken;
|
||||||
|
source.completed = false;
|
||||||
|
|
||||||
|
TaskTracker.TrackActiveTask(source, 3);
|
||||||
|
PlayerLoopHelper.AddAction(timing, source);
|
||||||
|
|
||||||
|
operation.completed += source.OnCompleted;
|
||||||
|
token = source.core.Version;
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnCompleted(AsyncOperation asyncOperation)
|
||||||
|
{
|
||||||
|
operation.completed -= OnCompleted;
|
||||||
|
|
||||||
|
if (completed)
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
completed = true;
|
||||||
|
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
operation.Cancel();
|
||||||
|
core.TrySetCanceled(cancellationToken);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
core.TrySetResult(operation.Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Destroy()
|
||||||
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
|
|
||||||
|
core.Reset();
|
||||||
|
operation = default;
|
||||||
|
progress = default;
|
||||||
|
cancellationToken = default;
|
||||||
|
|
||||||
|
pool.TryPush(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IUniTaskSource.GetResult(short token)
|
||||||
|
{
|
||||||
|
core.GetResult(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniTaskStatus IUniTaskSource.GetStatus(short token)
|
||||||
|
{
|
||||||
|
return core.GetStatus(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IUniTaskSource.OnCompleted(Action<object> continuation, object state, short token)
|
||||||
|
{
|
||||||
|
core.OnCompleted(continuation, state, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
UniTaskStatus IUniTaskSource.UnsafeGetStatus()
|
||||||
|
{
|
||||||
|
return core.UnsafeGetStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
T[] IUniTaskSource<T[]>.GetResult(short token)
|
||||||
|
{
|
||||||
|
return core.GetResult(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IUniTaskSource<T[]>.OnCompleted(Action<object> continuation, object state, short token)
|
||||||
|
{
|
||||||
|
core.OnCompleted(continuation, state, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPlayerLoopItem.MoveNext()
|
||||||
|
{
|
||||||
|
if (completed)
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
completed = true;
|
||||||
|
operation.Cancel();
|
||||||
|
core.TrySetCanceled(cancellationToken);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress?.Report(operation.progress);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref AsyncInstantiateOperationConfiguredSource<T> ITaskPoolNode<AsyncInstantiateOperationConfiguredSource<T>>.NextNode => ref nextNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2ebf81ddeba24644b2946dcef4f16d16
|
||||||
|
timeCreated: 1708199291
|
Loading…
Reference in New Issue