mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-07 16:45:10 +00:00
TE6 打飞机Demo
TE6 打飞机Demo
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e046ba353633f1e4b9552aa50e780fe0
|
||||
guid: 40ef2e46f900131419e869398a8d3c9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1973dbb90ca25d94490075246d04549a
|
||||
guid: 52e2d973a2156674e8c1c9433ed031f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 456b7e008397a8c4c81fac6abd52110a
|
||||
guid: 5bee3e3860e37484aa3b861bf76d129f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -7,6 +7,7 @@ using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
@@ -20,17 +21,12 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(handle).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken)
|
||||
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
|
||||
{
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken);
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
|
||||
}
|
||||
|
||||
public static UniTask WithCancellation(this AsyncOperationHandle handle, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
|
||||
|
||||
@@ -49,7 +45,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
|
||||
}
|
||||
|
||||
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
|
||||
@@ -108,21 +104,23 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperationHandle> continuationAction;
|
||||
readonly Action<AsyncOperationHandle> completedCallback;
|
||||
AsyncOperationHandle handle;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
IProgress<float> progress;
|
||||
bool autoReleaseWhenCanceled;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
completedCallback = HandleCompleted;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -137,6 +135,8 @@ namespace Cysharp.Threading.Tasks
|
||||
result.handle = handle;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
|
||||
result.completed = false;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
@@ -144,6 +144,10 @@ namespace Cysharp.Threading.Tasks
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (AsyncOperationHandleConfiguredSource)state;
|
||||
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
|
||||
{
|
||||
Addressables.Release(promise.handle);
|
||||
}
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
@@ -152,41 +156,60 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
handle.Completed += result.continuationAction;
|
||||
handle.Completed += result.completedCallback;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperationHandle _)
|
||||
void HandleCompleted(AsyncOperationHandle _)
|
||||
{
|
||||
handle.Completed -= continuationAction;
|
||||
if (handle.IsValid())
|
||||
{
|
||||
handle.Completed -= completedCallback;
|
||||
}
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (autoReleaseWhenCanceled && handle.IsValid())
|
||||
{
|
||||
Addressables.Release(handle);
|
||||
}
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (handle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(handle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
core.GetResult(token);
|
||||
try
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
@@ -208,20 +231,23 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
if (autoReleaseWhenCanceled && handle.IsValid())
|
||||
{
|
||||
Addressables.Release(handle);
|
||||
}
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null && handle.IsValid())
|
||||
{
|
||||
progress.Report(handle.PercentComplete);
|
||||
progress.Report(handle.GetDownloadStatus().Percent);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -248,17 +274,12 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(handle).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken)
|
||||
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken, bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
|
||||
{
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken);
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately, autoReleaseWhenCanceled: autoReleaseWhenCanceled);
|
||||
}
|
||||
|
||||
public static UniTask<T> WithCancellation<T>(this AsyncOperationHandle<T> handle, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false, bool autoReleaseWhenCanceled = false)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T>(cancellationToken);
|
||||
|
||||
@@ -276,7 +297,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return UniTask.FromResult(handle.Result);
|
||||
}
|
||||
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, cancelImmediately, autoReleaseWhenCanceled, out var token), token);
|
||||
}
|
||||
|
||||
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
|
||||
@@ -290,21 +311,23 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncOperationHandleConfiguredSource<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
readonly Action<AsyncOperationHandle<T>> continuationAction;
|
||||
readonly Action<AsyncOperationHandle<T>> completedCallback;
|
||||
AsyncOperationHandle<T> handle;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
IProgress<float> progress;
|
||||
bool autoReleaseWhenCanceled;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<T> core;
|
||||
|
||||
AsyncOperationHandleConfiguredSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
completedCallback = HandleCompleted;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, bool autoReleaseWhenCanceled, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -320,12 +343,18 @@ namespace Cysharp.Threading.Tasks
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
result.progress = progress;
|
||||
result.autoReleaseWhenCanceled = autoReleaseWhenCanceled;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (AsyncOperationHandleConfiguredSource<T>)state;
|
||||
if (promise.autoReleaseWhenCanceled && promise.handle.IsValid())
|
||||
{
|
||||
Addressables.Release(promise.handle);
|
||||
}
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
@@ -334,41 +363,59 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
handle.Completed += result.continuationAction;
|
||||
handle.Completed += result.completedCallback;
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperationHandle<T> argHandle)
|
||||
void HandleCompleted(AsyncOperationHandle<T> argHandle)
|
||||
{
|
||||
handle.Completed -= continuationAction;
|
||||
if (handle.IsValid())
|
||||
{
|
||||
handle.Completed -= completedCallback;
|
||||
}
|
||||
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
if (autoReleaseWhenCanceled && handle.IsValid())
|
||||
{
|
||||
Addressables.Release(handle);
|
||||
}
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (argHandle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(argHandle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (argHandle.Status == AsyncOperationStatus.Failed)
|
||||
{
|
||||
core.TrySetException(argHandle.OperationException);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(argHandle.Result);
|
||||
}
|
||||
core.TrySetResult(argHandle.Result);
|
||||
}
|
||||
}
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
return core.GetResult(token);
|
||||
try
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
@@ -395,20 +442,23 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completed = true;
|
||||
if (autoReleaseWhenCanceled && handle.IsValid())
|
||||
{
|
||||
Addressables.Release(handle);
|
||||
}
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null && handle.IsValid())
|
||||
{
|
||||
progress.Report(handle.PercentComplete);
|
||||
progress.Report(handle.GetDownloadStatus().Percent);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@@ -2,7 +2,8 @@
|
||||
"name": "UniTask.Addressables",
|
||||
"references": [
|
||||
"UniTask",
|
||||
"Unity.ResourceManager"
|
||||
"Unity.ResourceManager",
|
||||
"Unity.Addressables"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d96696960b382384190300495cd26735
|
||||
guid: 25cb2f742bfeb1d48a4e65d3140b955d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c517968e1258cb649984dddf2c0ad8b0
|
||||
guid: 1f448d5bc5b232e4f98d89d5d1832e8e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a40cecb731a38b340b0d3899da286566
|
||||
guid: 029c1c1b674aaae47a6841a0b89ad80e
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cc67eb6c366477469fdf07a6922c183
|
||||
guid: f89da606bde9a4e4e94ae1189a029887
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 930414e3dd7d9d746a13c3a0f14ba5e7
|
||||
guid: 79f4f2475e0b2c44e97ed1dee760627b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a4a4017ce5c23445a882e87e8cb103c
|
||||
guid: e9bb9fc551a975d44a7180e022a2debe
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9cba699cacf633438f41c07916c83d0
|
||||
guid: b6ba480edafb67d4e91bb10feb64fae5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -16,7 +16,12 @@
|
||||
"name": "com.unity.textmeshpro",
|
||||
"expression": "",
|
||||
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.ugui",
|
||||
"expression": "2.0.0",
|
||||
"define": "UNITASK_TEXTMESHPRO_SUPPORT"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d82b75b6a37050140bd967e8499035d8
|
||||
guid: dc47925d1a5fa2946bdd37746b2b5d48
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
@@ -1,4 +1,9 @@
|
||||
#pragma warning disable CS1591
|
||||
#pragma warning disable CS0108
|
||||
|
||||
#if (UNITASK_NETCORE && !NETSTANDARD2_0) || UNITY_2022_3_OR_NEWER
|
||||
#define SUPPORT_VALUETASK
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
@@ -19,9 +24,8 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
// similar as IValueTaskSource
|
||||
public interface IUniTaskSource
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
#if SUPPORT_VALUETASK
|
||||
: System.Threading.Tasks.Sources.IValueTaskSource
|
||||
#pragma warning disable CS0108
|
||||
#endif
|
||||
{
|
||||
UniTaskStatus GetStatus(short token);
|
||||
@@ -30,8 +34,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
UniTaskStatus UnsafeGetStatus(); // only for debug use.
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
#pragma warning restore CS0108
|
||||
#if SUPPORT_VALUETASK
|
||||
|
||||
System.Threading.Tasks.Sources.ValueTaskSourceStatus System.Threading.Tasks.Sources.IValueTaskSource.GetStatus(short token)
|
||||
{
|
||||
@@ -53,13 +56,13 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
public interface IUniTaskSource<out T> : IUniTaskSource
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
#if SUPPORT_VALUETASK
|
||||
, System.Threading.Tasks.Sources.IValueTaskSource<T>
|
||||
#endif
|
||||
{
|
||||
new T GetResult(short token);
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER && !NETSTANDARD2_0
|
||||
#if SUPPORT_VALUETASK
|
||||
|
||||
new public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
|
@@ -27,7 +27,9 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public static IUniTaskAsyncEnumerable<T> Merge<T>(this IEnumerable<IUniTaskAsyncEnumerable<T>> sources)
|
||||
{
|
||||
return new Merge<T>(sources.ToArray());
|
||||
return sources is IUniTaskAsyncEnumerable<T>[] array
|
||||
? new Merge<T>(array)
|
||||
: new Merge<T>(sources.ToArray());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<T> Merge<T>(params IUniTaskAsyncEnumerable<T>[] sources)
|
||||
|
104
UnityProject/Packages/UniTask/Runtime/UniTask.AsValueTask.cs
Normal file
104
UnityProject/Packages/UniTask/Runtime/UniTask.AsValueTask.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
#pragma warning disable 0649
|
||||
|
||||
#if UNITASK_NETCORE || UNITY_2022_3_OR_NEWER
|
||||
#define SUPPORT_VALUETASK
|
||||
#endif
|
||||
|
||||
#if SUPPORT_VALUETASK
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks.Sources;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class UniTaskValueTaskExtensions
|
||||
{
|
||||
public static ValueTask AsValueTask(this in UniTask task)
|
||||
{
|
||||
#if (UNITASK_NETCORE && NETSTANDARD2_0)
|
||||
return new ValueTask(new UniTaskValueTaskSource(task), 0);
|
||||
#else
|
||||
return task;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static ValueTask<T> AsValueTask<T>(this in UniTask<T> task)
|
||||
{
|
||||
#if (UNITASK_NETCORE && NETSTANDARD2_0)
|
||||
return new ValueTask<T>(new UniTaskValueTaskSource<T>(task), 0);
|
||||
#else
|
||||
return task;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static async UniTask<T> AsUniTask<T>(this ValueTask<T> task)
|
||||
{
|
||||
return await task;
|
||||
}
|
||||
|
||||
public static async UniTask AsUniTask(this ValueTask task)
|
||||
{
|
||||
await task;
|
||||
}
|
||||
|
||||
#if (UNITASK_NETCORE && NETSTANDARD2_0)
|
||||
|
||||
class UniTaskValueTaskSource : IValueTaskSource
|
||||
{
|
||||
readonly UniTask task;
|
||||
readonly UniTask.Awaiter awaiter;
|
||||
|
||||
public UniTaskValueTaskSource(UniTask task)
|
||||
{
|
||||
this.task = task;
|
||||
this.awaiter = task.GetAwaiter();
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
awaiter.GetResult();
|
||||
}
|
||||
|
||||
public ValueTaskSourceStatus GetStatus(short token)
|
||||
{
|
||||
return (ValueTaskSourceStatus)task.Status;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
|
||||
{
|
||||
awaiter.SourceOnCompleted(continuation, state);
|
||||
}
|
||||
}
|
||||
|
||||
class UniTaskValueTaskSource<T> : IValueTaskSource<T>
|
||||
{
|
||||
readonly UniTask<T> task;
|
||||
readonly UniTask<T>.Awaiter awaiter;
|
||||
|
||||
public UniTaskValueTaskSource(UniTask<T> task)
|
||||
{
|
||||
this.task = task;
|
||||
this.awaiter = task.GetAwaiter();
|
||||
}
|
||||
|
||||
public T GetResult(short token)
|
||||
{
|
||||
return awaiter.GetResult();
|
||||
}
|
||||
|
||||
public ValueTaskSourceStatus GetStatus(short token)
|
||||
{
|
||||
return (ValueTaskSourceStatus)task.Status;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
|
||||
{
|
||||
awaiter.SourceOnCompleted(continuation, state);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d38f0478933be42d895c37b862540a1c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -208,6 +208,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
YieldPromise()
|
||||
@@ -227,6 +228,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -253,7 +255,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,6 +299,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -309,6 +319,7 @@ namespace Cysharp.Threading.Tasks
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
NextFramePromise()
|
||||
{
|
||||
@@ -328,6 +339,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.frameCount = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -354,7 +366,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,6 +433,7 @@ namespace Cysharp.Threading.Tasks
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
WaitForEndOfFramePromise()
|
||||
{
|
||||
@@ -432,6 +452,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -458,7 +479,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,6 +561,7 @@ namespace Cysharp.Threading.Tasks
|
||||
int delayFrameCount;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
int currentFrameCount;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
@@ -556,6 +585,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.delayFrameCount = delayFrameCount;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -582,7 +612,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,6 +690,7 @@ namespace Cysharp.Threading.Tasks
|
||||
delayFrameCount = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -673,6 +711,7 @@ namespace Cysharp.Threading.Tasks
|
||||
float elapsed;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -696,6 +735,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.delayTimeSpan = (float)delayTimeSpan.TotalSeconds;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -722,7 +762,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,6 +822,7 @@ namespace Cysharp.Threading.Tasks
|
||||
elapsed = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -795,6 +843,7 @@ namespace Cysharp.Threading.Tasks
|
||||
int initialFrame;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -818,6 +867,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.delayFrameTimeSpan = (float)delayFrameTimeSpan.TotalSeconds;
|
||||
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -844,7 +894,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,6 +954,7 @@ namespace Cysharp.Threading.Tasks
|
||||
elapsed = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -916,6 +974,7 @@ namespace Cysharp.Threading.Tasks
|
||||
ValueStopwatch stopwatch;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
@@ -938,6 +997,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.stopwatch = ValueStopwatch.StartNew();
|
||||
result.delayTimeSpanTicks = delayTimeSpan.Ticks;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -964,7 +1024,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1013,6 +1080,7 @@ namespace Cysharp.Threading.Tasks
|
||||
stopwatch = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
@@ -81,6 +81,16 @@ namespace Cysharp.Threading.Tasks
|
||||
return factory();
|
||||
}
|
||||
|
||||
public static UniTask Create(Func<CancellationToken, UniTask> factory, CancellationToken cancellationToken)
|
||||
{
|
||||
return factory(cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask Create<T>(T state, Func<T, UniTask> factory)
|
||||
{
|
||||
return factory(state);
|
||||
}
|
||||
|
||||
public static UniTask<T> Create<T>(Func<UniTask<T>> factory)
|
||||
{
|
||||
return factory();
|
||||
@@ -137,11 +147,19 @@ namespace Cysharp.Threading.Tasks
|
||||
return () => asyncAction(cancellationToken).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// helper of create add UniTaskVoid to delegate.
|
||||
/// </summary>
|
||||
public static Action Action<T>(T state, Func<T, UniTaskVoid> asyncAction)
|
||||
{
|
||||
return () => asyncAction(state).Forget();
|
||||
}
|
||||
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For exampe: onClick.AddListener(UniTask.UnityAction(async () => { /* */ } ))
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async () => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction UnityAction(Func<UniTaskVoid> asyncAction)
|
||||
{
|
||||
@@ -150,13 +168,94 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For exampe: onClick.AddListener(UniTask.UnityAction(FooAsync, this.GetCancellationTokenOnDestroy()))
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(FooAsync, this.GetCancellationTokenOnDestroy()))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction UnityAction(Func<CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
|
||||
{
|
||||
return () => asyncAction(cancellationToken).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(FooAsync, Argument))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction UnityAction<T>(T state, Func<T, UniTaskVoid> asyncAction)
|
||||
{
|
||||
return () => asyncAction(state).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T arg) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T> UnityAction<T>(Func<T, UniTaskVoid> asyncAction)
|
||||
{
|
||||
return (arg) => asyncAction(arg).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T0, T1> UnityAction<T0, T1>(Func<T0, T1, UniTaskVoid> asyncAction)
|
||||
{
|
||||
return (arg0, arg1) => asyncAction(arg0, arg1).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T0, T1, T2> UnityAction<T0, T1, T2>(Func<T0, T1, T2, UniTaskVoid> asyncAction)
|
||||
{
|
||||
return (arg0, arg1, arg2) => asyncAction(arg0, arg1, arg2).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2, T3 arg3) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T0, T1, T2, T3> UnityAction<T0, T1, T2, T3>(Func<T0, T1, T2, T3, UniTaskVoid> asyncAction)
|
||||
{
|
||||
return (arg0, arg1, arg2, arg3) => asyncAction(arg0, arg1, arg2, arg3).Forget();
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T arg, CancellationToken cancellationToken) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T> UnityAction<T>(Func<T, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
|
||||
{
|
||||
return (arg) => asyncAction(arg, cancellationToken).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, CancellationToken cancellationToken) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T0, T1> UnityAction<T0, T1>(Func<T0, T1, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
|
||||
{
|
||||
return (arg0, arg1) => asyncAction(arg0, arg1, cancellationToken).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2, CancellationToken cancellationToken) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T0, T1, T2> UnityAction<T0, T1, T2>(Func<T0, T1, T2, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
|
||||
{
|
||||
return (arg0, arg1, arg2) => asyncAction(arg0, arg1, arg2, cancellationToken).Forget();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create async void(UniTaskVoid) UnityAction.
|
||||
/// For example: onClick.AddListener(UniTask.UnityAction(async (T0 arg0, T1 arg1, T2 arg2, T3 arg3, CancellationToken cancellationToken) => { /* */ } ))
|
||||
/// </summary>
|
||||
public static UnityEngine.Events.UnityAction<T0, T1, T2, T3> UnityAction<T0, T1, T2, T3>(Func<T0, T1, T2, T3, CancellationToken, UniTaskVoid> asyncAction, CancellationToken cancellationToken)
|
||||
{
|
||||
return (arg0, arg1, arg2, arg3) => asyncAction(arg0, arg1, arg2, arg3, cancellationToken).Forget();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
@@ -175,6 +274,22 @@ namespace Cysharp.Threading.Tasks
|
||||
return new UniTask<T>(new DeferPromise<T>(factory), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defer the task creation just before call await.
|
||||
/// </summary>
|
||||
public static UniTask Defer<TState>(TState state, Func<TState, UniTask> factory)
|
||||
{
|
||||
return new UniTask(new DeferPromiseWithState<TState>(state, factory), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defer the task creation just before call await.
|
||||
/// </summary>
|
||||
public static UniTask<TResult> Defer<TState, TResult>(TState state, Func<TState, UniTask<TResult>> factory)
|
||||
{
|
||||
return new UniTask<TResult>(new DeferPromiseWithState<TState, TResult>(state, factory), 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Never complete.
|
||||
/// </summary>
|
||||
@@ -438,6 +553,93 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DeferPromiseWithState<TState> : IUniTaskSource
|
||||
{
|
||||
Func<TState, UniTask> factory;
|
||||
TState argument;
|
||||
UniTask task;
|
||||
UniTask.Awaiter awaiter;
|
||||
|
||||
public DeferPromiseWithState(TState argument, Func<TState, UniTask> factory)
|
||||
{
|
||||
this.argument = argument;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
awaiter.GetResult();
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
var f = Interlocked.Exchange(ref factory, null);
|
||||
if (f != null)
|
||||
{
|
||||
task = f(argument);
|
||||
awaiter = task.GetAwaiter();
|
||||
}
|
||||
|
||||
return task.Status;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
awaiter.SourceOnCompleted(continuation, state);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return task.Status;
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DeferPromiseWithState<TState, TResult> : IUniTaskSource<TResult>
|
||||
{
|
||||
Func<TState, UniTask<TResult>> factory;
|
||||
TState argument;
|
||||
UniTask<TResult> task;
|
||||
UniTask<TResult>.Awaiter awaiter;
|
||||
|
||||
public DeferPromiseWithState(TState argument, Func<TState, UniTask<TResult>> factory)
|
||||
{
|
||||
this.argument = argument;
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public TResult GetResult(short token)
|
||||
{
|
||||
return awaiter.GetResult();
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
awaiter.GetResult();
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
var f = Interlocked.Exchange(ref factory, null);
|
||||
if (f != null)
|
||||
{
|
||||
task = f(argument);
|
||||
awaiter = task.GetAwaiter();
|
||||
}
|
||||
|
||||
return task.Status;
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
awaiter.SourceOnCompleted(continuation, state);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return task.Status;
|
||||
}
|
||||
}
|
||||
|
||||
sealed class NeverPromise<T> : IUniTaskSource<T>
|
||||
{
|
||||
static readonly Action<object> cancellationCallback = CancellationCallback;
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
@@ -14,11 +15,21 @@ namespace Cysharp.Threading.Tasks
|
||||
return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask WaitUntil<T>(T state, Func<T, bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(WaitUntilPromise<T>.Create(state, predicate, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask WaitWhile(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask WaitWhile<T>(T state, Func<T, bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(WaitWhilePromise<T>.Create(state, predicate, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool completeImmediately = false)
|
||||
{
|
||||
return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, completeImmediately, out var token), token);
|
||||
@@ -49,6 +60,7 @@ namespace Cysharp.Threading.Tasks
|
||||
Func<bool> predicate;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -70,6 +82,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.predicate = predicate;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -96,7 +109,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +167,136 @@ namespace Cysharp.Threading.Tasks
|
||||
predicate = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WaitUntilPromise<T> : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitUntilPromise<T>>
|
||||
{
|
||||
static TaskPool<WaitUntilPromise<T>> pool;
|
||||
WaitUntilPromise<T> nextNode;
|
||||
public ref WaitUntilPromise<T> NextNode => ref nextNode;
|
||||
|
||||
static WaitUntilPromise()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(WaitUntilPromise<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
Func<T, bool> predicate;
|
||||
T argument;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
WaitUntilPromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(T argument, Func<T, bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new WaitUntilPromise<T>();
|
||||
}
|
||||
|
||||
result.predicate = predicate;
|
||||
result.argument = argument;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitUntilPromise<T>)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!predicate(argument))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
core.TrySetException(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
core.TrySetResult(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
predicate = default;
|
||||
argument = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -165,6 +315,7 @@ namespace Cysharp.Threading.Tasks
|
||||
Func<bool> predicate;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -186,7 +337,8 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.predicate = predicate;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
@@ -212,7 +364,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +422,136 @@ namespace Cysharp.Threading.Tasks
|
||||
predicate = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WaitWhilePromise<T> : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitWhilePromise<T>>
|
||||
{
|
||||
static TaskPool<WaitWhilePromise<T>> pool;
|
||||
WaitWhilePromise<T> nextNode;
|
||||
public ref WaitWhilePromise<T> NextNode => ref nextNode;
|
||||
|
||||
static WaitWhilePromise()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(WaitWhilePromise<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
Func<T, bool> predicate;
|
||||
T argument;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
WaitWhilePromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(T argument, Func<T, bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new WaitWhilePromise<T>();
|
||||
}
|
||||
|
||||
result.predicate = predicate;
|
||||
result.argument = argument;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitWhilePromise<T>)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
public void GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (predicate(argument))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
core.TrySetException(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
core.TrySetResult(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
predicate = default;
|
||||
argument = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -280,6 +569,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -287,7 +577,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, bool completeImmediately, out short token)
|
||||
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -300,8 +590,9 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (completeImmediately && cancellationToken.CanBeCanceled)
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
@@ -326,7 +617,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,6 +660,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -385,6 +684,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IEqualityComparer<U> equalityComparer;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<U> core;
|
||||
|
||||
@@ -410,7 +710,8 @@ namespace Cysharp.Threading.Tasks
|
||||
result.currentValue = monitorFunction(target);
|
||||
result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault<U>();
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
@@ -436,7 +737,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,6 +805,7 @@ namespace Cysharp.Threading.Tasks
|
||||
equalityComparer = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -519,6 +828,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IEqualityComparer<U> equalityComparer;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
|
||||
UniTaskCompletionSourceCore<U> core;
|
||||
|
||||
@@ -543,7 +853,8 @@ namespace Cysharp.Threading.Tasks
|
||||
result.currentValue = monitorFunction(target);
|
||||
result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault<U>();
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
@@ -569,7 +880,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,6 +948,7 @@ namespace Cysharp.Threading.Tasks
|
||||
equalityComparer = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
183
UnityProject/Packages/UniTask/Runtime/UniTask.WhenEach.cs
Normal file
183
UnityProject/Packages/UniTask/Runtime/UniTask.WhenEach.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public partial struct UniTask
|
||||
{
|
||||
public static IUniTaskAsyncEnumerable<WhenEachResult<T>> WhenEach<T>(IEnumerable<UniTask<T>> tasks)
|
||||
{
|
||||
return new WhenEachEnumerable<T>(tasks);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<WhenEachResult<T>> WhenEach<T>(params UniTask<T>[] tasks)
|
||||
{
|
||||
return new WhenEachEnumerable<T>(tasks);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct WhenEachResult<T>
|
||||
{
|
||||
public T Result { get; }
|
||||
public Exception Exception { get; }
|
||||
|
||||
//[MemberNotNullWhen(false, nameof(Exception))]
|
||||
public bool IsCompletedSuccessfully => Exception == null;
|
||||
|
||||
//[MemberNotNullWhen(true, nameof(Exception))]
|
||||
public bool IsFaulted => Exception != null;
|
||||
|
||||
public WhenEachResult(T result)
|
||||
{
|
||||
this.Result = result;
|
||||
this.Exception = null;
|
||||
}
|
||||
|
||||
public WhenEachResult(Exception exception)
|
||||
{
|
||||
if (exception == null) throw new ArgumentNullException(nameof(exception));
|
||||
this.Result = default;
|
||||
this.Exception = exception;
|
||||
}
|
||||
|
||||
public void TryThrow()
|
||||
{
|
||||
if (IsFaulted)
|
||||
{
|
||||
ExceptionDispatchInfo.Capture(Exception).Throw();
|
||||
}
|
||||
}
|
||||
|
||||
public T GetResult()
|
||||
{
|
||||
if (IsFaulted)
|
||||
{
|
||||
ExceptionDispatchInfo.Capture(Exception).Throw();
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (IsCompletedSuccessfully)
|
||||
{
|
||||
return Result?.ToString() ?? "";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"Exception{{{Exception.Message}}}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum WhenEachState : byte
|
||||
{
|
||||
NotRunning,
|
||||
Running,
|
||||
Completed
|
||||
}
|
||||
|
||||
internal sealed class WhenEachEnumerable<T> : IUniTaskAsyncEnumerable<WhenEachResult<T>>
|
||||
{
|
||||
IEnumerable<UniTask<T>> source;
|
||||
|
||||
public WhenEachEnumerable(IEnumerable<UniTask<T>> source)
|
||||
{
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<WhenEachResult<T>> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new Enumerator(source, cancellationToken);
|
||||
}
|
||||
|
||||
sealed class Enumerator : IUniTaskAsyncEnumerator<WhenEachResult<T>>
|
||||
{
|
||||
readonly IEnumerable<UniTask<T>> source;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
Channel<WhenEachResult<T>> channel;
|
||||
IUniTaskAsyncEnumerator<WhenEachResult<T>> channelEnumerator;
|
||||
int completeCount;
|
||||
WhenEachState state;
|
||||
|
||||
public Enumerator(IEnumerable<UniTask<T>> source, CancellationToken cancellationToken)
|
||||
{
|
||||
this.source = source;
|
||||
this.cancellationToken = cancellationToken;
|
||||
}
|
||||
|
||||
public WhenEachResult<T> Current => channelEnumerator.Current;
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
if (state == WhenEachState.NotRunning)
|
||||
{
|
||||
state = WhenEachState.Running;
|
||||
channel = Channel.CreateSingleConsumerUnbounded<WhenEachResult<T>>();
|
||||
channelEnumerator = channel.Reader.ReadAllAsync().GetAsyncEnumerator(cancellationToken);
|
||||
|
||||
if (source is UniTask<T>[] array)
|
||||
{
|
||||
ConsumeAll(this, array, array.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var rentArray = ArrayPoolUtil.Materialize(source))
|
||||
{
|
||||
ConsumeAll(this, rentArray.Array, rentArray.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return channelEnumerator.MoveNextAsync();
|
||||
}
|
||||
|
||||
static void ConsumeAll(Enumerator self, UniTask<T>[] array, int length)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
RunWhenEachTask(self, array[i], length).Forget();
|
||||
}
|
||||
}
|
||||
|
||||
static async UniTaskVoid RunWhenEachTask(Enumerator self, UniTask<T> task, int length)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await task;
|
||||
self.channel.Writer.TryWrite(new WhenEachResult<T>(result));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.channel.Writer.TryWrite(new WhenEachResult<T>(ex));
|
||||
}
|
||||
|
||||
if (Interlocked.Increment(ref self.completeCount) == length)
|
||||
{
|
||||
self.state = WhenEachState.Completed;
|
||||
self.channel.Writer.TryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask DisposeAsync()
|
||||
{
|
||||
if (channelEnumerator != null)
|
||||
{
|
||||
await channelEnumerator.DisposeAsync();
|
||||
}
|
||||
|
||||
if (state != WhenEachState.Completed)
|
||||
{
|
||||
state = WhenEachState.Completed;
|
||||
channel.Writer.TryComplete(new OperationCanceledException());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7cac24fdda5112047a1cd3dd66b542c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,6 +1,10 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
#pragma warning disable CS0436
|
||||
|
||||
#if UNITASK_NETCORE || UNITY_2022_3_OR_NEWER
|
||||
#define SUPPORT_VALUETASK
|
||||
#endif
|
||||
|
||||
using Cysharp.Threading.Tasks.CompilerServices;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
@@ -69,7 +73,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return new UniTask<bool>(new IsCanceledSource(source), token);
|
||||
}
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
#if SUPPORT_VALUETASK
|
||||
|
||||
public static implicit operator System.Threading.Tasks.ValueTask(in UniTask self)
|
||||
{
|
||||
@@ -78,7 +82,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return default;
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
#if (UNITASK_NETCORE && NETSTANDARD2_0)
|
||||
return self.AsValueTask();
|
||||
#else
|
||||
return new System.Threading.Tasks.ValueTask(self.source, self.token);
|
||||
@@ -118,7 +122,7 @@ namespace Cysharp.Threading.Tasks
|
||||
this.source.GetResult(this.token);
|
||||
return CompletedTasks.AsyncUnit;
|
||||
}
|
||||
else if(this.source is IUniTaskSource<AsyncUnit> asyncUnitSource)
|
||||
else if (this.source is IUniTaskSource<AsyncUnit> asyncUnitSource)
|
||||
{
|
||||
return new UniTask<AsyncUnit>(asyncUnitSource, this.token);
|
||||
}
|
||||
@@ -440,7 +444,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return self.AsUniTask();
|
||||
}
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
#if SUPPORT_VALUETASK
|
||||
|
||||
public static implicit operator System.Threading.Tasks.ValueTask<T>(in UniTask<T> self)
|
||||
{
|
||||
@@ -449,7 +453,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return new System.Threading.Tasks.ValueTask<T>(self.result);
|
||||
}
|
||||
|
||||
#if NETSTANDARD2_0
|
||||
#if (UNITASK_NETCORE && NETSTANDARD2_0)
|
||||
return self.AsValueTask();
|
||||
#else
|
||||
return new System.Threading.Tasks.ValueTask<T>(self.source, self.token);
|
||||
|
@@ -201,6 +201,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
task.Forget();
|
||||
return UniTask.FromCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
@@ -224,6 +225,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
task.Forget();
|
||||
return UniTask.FromCanceled<T>(cancellationToken);
|
||||
}
|
||||
|
||||
@@ -454,7 +456,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled).
|
||||
/// Timeout with suppress OperationCanceledException. Returns (bool, IsCanceled).
|
||||
/// </summary>
|
||||
public static async UniTask<bool> TimeoutWithoutException(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
|
||||
{
|
||||
|
@@ -101,6 +101,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object[]> core;
|
||||
@@ -127,6 +128,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -156,7 +158,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +225,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -223,19 +233,17 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.allAssets);
|
||||
}
|
||||
core.TrySetResult(asyncOperation.allAssets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ namespace Cysharp.Threading.Tasks
|
||||
AsyncGPUReadbackRequest asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
bool cancelImmediately;
|
||||
UniTaskCompletionSourceCore<AsyncGPUReadbackRequest> core;
|
||||
|
||||
AsyncGPUReadbackRequestAwaiterConfiguredSource()
|
||||
@@ -66,6 +66,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
@@ -92,7 +93,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,6 +154,7 @@ namespace Cysharp.Threading.Tasks
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,386 @@
|
||||
// AsyncInstantiateOperation was added since Unity 2022.3.20 / 2023.3.0b7
|
||||
#if UNITY_2022_3 && !(UNITY_2022_3_0 || UNITY_2022_3_1 || UNITY_2022_3_2 || UNITY_2022_3_3 || UNITY_2022_3_4 || UNITY_2022_3_5 || UNITY_2022_3_6 || UNITY_2022_3_7 || UNITY_2022_3_8 || UNITY_2022_3_9 || UNITY_2022_3_10 || UNITY_2022_3_11 || UNITY_2022_3_12 || UNITY_2022_3_13 || UNITY_2022_3_14 || UNITY_2022_3_15 || UNITY_2022_3_16 || UNITY_2022_3_17 || UNITY_2022_3_18 || UNITY_2022_3_19)
|
||||
#define UNITY_2022_SUPPORT
|
||||
#endif
|
||||
|
||||
#if UNITY_2022_SUPPORT || UNITY_2023_3_OR_NEWER
|
||||
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class AsyncInstantiateOperationExtensions
|
||||
{
|
||||
// AsyncInstantiateOperation<T> has GetAwaiter so no need to impl
|
||||
// public static UniTask<T[]>.Awaiter GetAwaiter<T>(this AsyncInstantiateOperation<T> operation) where T : Object
|
||||
|
||||
public static UniTask<UnityEngine.Object[]> WithCancellation<T>(this AsyncInstantiateOperation asyncOperation, CancellationToken cancellationToken)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object[]> WithCancellation<T>(this AsyncInstantiateOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object[]> ToUniTask(this AsyncInstantiateOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<UnityEngine.Object[]>(cancellationToken);
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.Result);
|
||||
return new UniTask<UnityEngine.Object[]>(AsyncInstantiateOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<T[]> WithCancellation<T>(this AsyncInstantiateOperation<T> asyncOperation, CancellationToken cancellationToken)
|
||||
where T : UnityEngine.Object
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<T[]> WithCancellation<T>(this AsyncInstantiateOperation<T> asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
where T : UnityEngine.Object
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<T[]> ToUniTask<T>(this AsyncInstantiateOperation<T> asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
where T : UnityEngine.Object
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T[]>(cancellationToken);
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.Result);
|
||||
return new UniTask<T[]>(AsyncInstantiateOperationConfiguredSource<T>.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
sealed class AsyncInstantiateOperationConfiguredSource : IUniTaskSource<UnityEngine.Object[]>, IPlayerLoopItem, ITaskPoolNode<AsyncInstantiateOperationConfiguredSource>
|
||||
{
|
||||
static TaskPool<AsyncInstantiateOperationConfiguredSource> pool;
|
||||
AsyncInstantiateOperationConfiguredSource nextNode;
|
||||
public ref AsyncInstantiateOperationConfiguredSource NextNode => ref nextNode;
|
||||
|
||||
static AsyncInstantiateOperationConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncInstantiateOperationConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
AsyncInstantiateOperation asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object[]> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
AsyncInstantiateOperationConfiguredSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityEngine.Object[]> Create(AsyncInstantiateOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<UnityEngine.Object[]>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncInstantiateOperationConfiguredSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (AsyncInstantiateOperationConfiguredSource)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
public UnityEngine.Object[] GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
{
|
||||
progress.Report(asyncOperation.progress);
|
||||
}
|
||||
|
||||
if (asyncOperation.isDone)
|
||||
{
|
||||
core.TrySetResult(asyncOperation.Result);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AsyncInstantiateOperationConfiguredSource<T> : IUniTaskSource<T[]>, IPlayerLoopItem, ITaskPoolNode<AsyncInstantiateOperationConfiguredSource<T>>
|
||||
where T : UnityEngine.Object
|
||||
{
|
||||
static TaskPool<AsyncInstantiateOperationConfiguredSource<T>> pool;
|
||||
AsyncInstantiateOperationConfiguredSource<T> nextNode;
|
||||
public ref AsyncInstantiateOperationConfiguredSource<T> NextNode => ref nextNode;
|
||||
|
||||
static AsyncInstantiateOperationConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(AsyncInstantiateOperationConfiguredSource<T>), () => pool.Size);
|
||||
}
|
||||
|
||||
AsyncInstantiateOperation<T> asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<T[]> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
AsyncInstantiateOperationConfiguredSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T[]> Create(AsyncInstantiateOperation<T> asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<T[]>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new AsyncInstantiateOperationConfiguredSource<T>();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (AsyncInstantiateOperationConfiguredSource<T>)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
public T[] GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
return core.GetResult(token);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
{
|
||||
progress.Report(asyncOperation.progress);
|
||||
}
|
||||
|
||||
if (asyncOperation.isDone)
|
||||
{
|
||||
core.TrySetResult(asyncOperation.Result);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.Result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8321f4244edfdcd4798b4fcc92a736c9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -97,6 +97,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
@@ -123,6 +124,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -152,7 +154,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +218,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -216,19 +226,16 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,6 +327,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object> core;
|
||||
@@ -346,6 +354,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -375,7 +384,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,6 +452,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -443,19 +460,16 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,6 +562,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object> core;
|
||||
@@ -574,6 +589,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -603,7 +619,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -664,6 +687,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -671,19 +695,16 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -777,6 +798,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AssetBundle> core;
|
||||
@@ -803,6 +825,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -832,7 +855,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -893,6 +923,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -900,19 +931,16 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.assetBundle);
|
||||
}
|
||||
core.TrySetResult(asyncOperation.assetBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1021,6 +1049,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityWebRequest> core;
|
||||
@@ -1047,6 +1076,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -1077,7 +1107,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,6 +1183,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -1153,23 +1191,20 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.webRequest);
|
||||
}
|
||||
core.TrySetResult(asyncOperation.webRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -165,6 +165,7 @@ namespace Cysharp.Threading.Tasks
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool cancelImmediately;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<<#= IsVoid(t) ? "AsyncUnit" : t.returnType #>> core;
|
||||
@@ -191,6 +192,7 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.cancelImmediately = cancelImmediately;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
@@ -227,7 +229,10 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
if (!(cancelImmediately && cancellationToken.IsCancellationRequested))
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,6 +309,7 @@ namespace Cysharp.Threading.Tasks
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
cancelImmediately = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -311,31 +317,28 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
return;
|
||||
}
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
else if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
else if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.webRequest);
|
||||
}
|
||||
<# } else { #>
|
||||
else
|
||||
{
|
||||
core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>);
|
||||
}
|
||||
<# } #>
|
||||
core.TrySetResult(asyncOperation.webRequest);
|
||||
}
|
||||
<# } else { #>
|
||||
else
|
||||
{
|
||||
core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>);
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -339,7 +339,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
void InvokeCore(string item1, int item2, int item3)
|
||||
{
|
||||
innerEvent.Invoke(item1, item2, item3);
|
||||
Invoke((item1, item2, item3));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
@@ -855,4 +855,4 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -3,5 +3,4 @@
|
||||
[assembly: InternalsVisibleTo("UniTask.Linq")]
|
||||
[assembly: InternalsVisibleTo("UniTask.Addressables")]
|
||||
[assembly: InternalsVisibleTo("UniTask.DOTween")]
|
||||
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
||||
[assembly: InternalsVisibleTo("UniTask.YooAsset")]
|
||||
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
@@ -2,7 +2,7 @@
|
||||
"name": "com.cysharp.unitask",
|
||||
"displayName": "UniTask",
|
||||
"author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" },
|
||||
"version": "2.5.0",
|
||||
"version": "2.5.10",
|
||||
"unity": "2018.4",
|
||||
"description": "Provides an efficient async/await integration to Unity.",
|
||||
"keywords": [ "async/await", "async", "Task", "UniTask" ],
|
||||
|
Reference in New Issue
Block a user