mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-07 16:45:10 +00:00
更新demo
更新demo
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f72c69c0975210489e927516c4494fc
|
||||
guid: 275b87293edc6634f9d72387851dbbdf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40ef2e46f900131419e869398a8d3c9d
|
||||
guid: e046ba353633f1e4b9552aa50e780fe0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52e2d973a2156674e8c1c9433ed031f7
|
||||
guid: 1973dbb90ca25d94490075246d04549a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bee3e3860e37484aa3b861bf76d129f
|
||||
guid: 456b7e008397a8c4c81fac6abd52110a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 967cc925e74341a408d1e0a0f611bc5e
|
||||
guid: aa765154468d4b34eb34304100d39e64
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07630c1e9fb2da542b4e0f6c6bd012db
|
||||
guid: 64b064347ca7a404494a996b072e2e29
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20067094c8a38b5428955c9e2e4285c7
|
||||
guid: a3e874acee8398745b1dc3eddac09eaa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d93e9817915280849b2b41e93952452f
|
||||
guid: a5b9231662e24c942b544bd85d4b39cb
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -25,7 +25,12 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperationHandle handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
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)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled(cancellationToken);
|
||||
|
||||
@@ -44,7 +49,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask(AsyncOperationHandleConfiguredSource.Create(handle, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct AsyncOperationHandleAwaiter : ICriticalNotifyCompletion
|
||||
@@ -106,6 +111,7 @@ namespace Cysharp.Threading.Tasks
|
||||
readonly Action<AsyncOperationHandle> continuationAction;
|
||||
AsyncOperationHandle handle;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
IProgress<float> progress;
|
||||
bool completed;
|
||||
|
||||
@@ -116,7 +122,7 @@ namespace Cysharp.Threading.Tasks
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(AsyncOperationHandle handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -132,6 +138,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (AsyncOperationHandleConfiguredSource)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -219,6 +234,7 @@ namespace Cysharp.Threading.Tasks
|
||||
handle = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -237,7 +253,12 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(handle, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<T> ToUniTask<T>(this AsyncOperationHandle<T> handle, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
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)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested) return UniTask.FromCanceled<T>(cancellationToken);
|
||||
|
||||
@@ -255,7 +276,7 @@ namespace Cysharp.Threading.Tasks
|
||||
return UniTask.FromResult(handle.Result);
|
||||
}
|
||||
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask<T>(AsyncOperationHandleConfiguredSource<T>.Create(handle, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
sealed class AsyncOperationHandleConfiguredSource<T> : IUniTaskSource<T>, IPlayerLoopItem, ITaskPoolNode<AsyncOperationHandleConfiguredSource<T>>
|
||||
@@ -272,6 +293,7 @@ namespace Cysharp.Threading.Tasks
|
||||
readonly Action<AsyncOperationHandle<T>> continuationAction;
|
||||
AsyncOperationHandle<T> handle;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
IProgress<float> progress;
|
||||
bool completed;
|
||||
|
||||
@@ -282,7 +304,7 @@ namespace Cysharp.Threading.Tasks
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<T> Create(AsyncOperationHandle<T> handle, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -298,6 +320,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
result.progress = progress;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (AsyncOperationHandleConfiguredSource<T>)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -390,6 +421,7 @@ namespace Cysharp.Threading.Tasks
|
||||
handle = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9001e9737c47974ba2a210d33589248
|
||||
guid: d96696960b382384190300495cd26735
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -148,6 +148,7 @@ namespace Cysharp.Threading.Tasks
|
||||
Tween tween;
|
||||
TweenCancelBehaviour cancelBehaviour;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationRegistration;
|
||||
CallbackType callbackType;
|
||||
bool canceled;
|
||||
|
||||
@@ -207,7 +208,7 @@ namespace Cysharp.Threading.Tasks
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (result.originalCompleteAction == result.onCompleteCallbackDelegate)
|
||||
{
|
||||
result.originalCompleteAction = null;
|
||||
@@ -215,7 +216,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
|
||||
result.cancellationRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(x =>
|
||||
{
|
||||
var source = (TweenConfiguredSource)x;
|
||||
switch (source.cancelBehaviour)
|
||||
@@ -250,30 +251,7 @@ namespace Cysharp.Threading.Tasks
|
||||
source.tween.Complete(true);
|
||||
break;
|
||||
case TweenCancelBehaviour.CancelAwait:
|
||||
// restore to original callback
|
||||
switch (callbackType)
|
||||
{
|
||||
case CallbackType.Kill:
|
||||
tween.onKill = source.originalCompleteAction;
|
||||
break;
|
||||
case CallbackType.Complete:
|
||||
tween.onComplete = source.originalCompleteAction;
|
||||
break;
|
||||
case CallbackType.Pause:
|
||||
tween.onPause = source.originalCompleteAction;
|
||||
break;
|
||||
case CallbackType.Play:
|
||||
tween.onPlay = source.originalCompleteAction;
|
||||
break;
|
||||
case CallbackType.Rewind:
|
||||
tween.onRewind = source.originalCompleteAction;
|
||||
break;
|
||||
case CallbackType.StepComplete:
|
||||
tween.onStepComplete = source.originalCompleteAction;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
source.RestoreOriginalCallback();
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
break;
|
||||
}
|
||||
@@ -376,7 +354,18 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationRegistration.Dispose();
|
||||
|
||||
RestoreOriginalCallback();
|
||||
|
||||
tween = default;
|
||||
cancellationToken = default;
|
||||
originalCompleteAction = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void RestoreOriginalCallback()
|
||||
{
|
||||
switch (callbackType)
|
||||
{
|
||||
case CallbackType.Kill:
|
||||
@@ -400,11 +389,6 @@ namespace Cysharp.Threading.Tasks
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
tween = default;
|
||||
cancellationToken = default;
|
||||
originalCompleteAction = default;
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f448d5bc5b232e4f98d89d5d1832e8e
|
||||
guid: c517968e1258cb649984dddf2c0ad8b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 029c1c1b674aaae47a6841a0b89ad80e
|
||||
guid: a40cecb731a38b340b0d3899da286566
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1b167ace675fd04898df969ebbbd5bb
|
||||
guid: 3cc67eb6c366477469fdf07a6922c183
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79f4f2475e0b2c44e97ed1dee760627b
|
||||
guid: 930414e3dd7d9d746a13c3a0f14ba5e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -0,0 +1,66 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var handlers = new (string name, string type)[] {
|
||||
("ValueChanged", "string"),
|
||||
("EndEdit", "string"),
|
||||
("EndTextSelection", "(string, int, int)"),
|
||||
("TextSelection", "(string, int, int)"),
|
||||
("Deselect", "string"),
|
||||
("Select", "string"),
|
||||
("Submit", "string"),
|
||||
};
|
||||
|
||||
Func<string, bool> shouldConvert = x => x.EndsWith("TextSelection");
|
||||
Func<string, string> eventName = x => shouldConvert(x) ? $"new TextSelectionEventConverter(inputField.on{x})" : $"inputField.on{x}";
|
||||
#>
|
||||
#if UNITASK_TEXTMESHPRO_SUPPORT
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using TMPro;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static partial class TextMeshProAsyncExtensions
|
||||
{
|
||||
<# foreach(var (name, type) in handlers) { #>
|
||||
public static IAsync<#= (name) #>EventHandler<<#= type #>> GetAsync<#= (name) #>EventHandler(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, inputField.GetCancellationTokenOnDestroy(), false);
|
||||
}
|
||||
|
||||
public static IAsync<#= (name) #>EventHandler<<#= type #>> GetAsync<#= (name) #>EventHandler(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, cancellationToken, false);
|
||||
}
|
||||
|
||||
public static UniTask<<#= type #>> On<#= (name) #>Async(this TMP_InputField inputField)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, inputField.GetCancellationTokenOnDestroy(), true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static UniTask<<#= type #>> On<#= (name) #>Async(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncUnityEventHandler<<#= type #>>(<#= eventName(name) #>, cancellationToken, true).OnInvokeAsync();
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<<#= type #>> On<#= (name) #>AsAsyncEnumerable(this TMP_InputField inputField)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<<#= type #>>(<#= eventName(name) #>, inputField.GetCancellationTokenOnDestroy());
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<<#= type #>> On<#= (name) #>AsAsyncEnumerable(this TMP_InputField inputField, CancellationToken cancellationToken)
|
||||
{
|
||||
return new UnityEventHandlerAsyncEnumerable<<#= type #>>(<#= eventName(name) #>, cancellationToken);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,6 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b91a2c0e3055f54a8aab905c4163009
|
||||
AssemblyDefinitionImporter:
|
||||
guid: 9a4a4017ce5c23445a882e87e8cb103c
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b6ba480edafb67d4e91bb10feb64fae5
|
||||
guid: a9cba699cacf633438f41c07916c83d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc47925d1a5fa2946bdd37746b2b5d48
|
||||
guid: d82b75b6a37050140bd967e8499035d8
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ba497ad9fe06174ea0e46a2b9b61ff5
|
||||
guid: 8a55ef7d1bba14cc982b478d482c4461
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,79 +0,0 @@
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Internal
|
||||
{
|
||||
internal static class Error
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void ThrowArgumentNullException<T>(T value, string paramName)
|
||||
where T : class
|
||||
{
|
||||
if (value == null) ThrowArgumentNullExceptionCore(paramName);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void ThrowArgumentNullExceptionCore(string paramName)
|
||||
{
|
||||
throw new ArgumentNullException(paramName);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Exception ArgumentOutOfRange(string paramName)
|
||||
{
|
||||
return new ArgumentOutOfRangeException(paramName);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Exception NoElements()
|
||||
{
|
||||
return new InvalidOperationException("Source sequence doesn't contain any elements.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Exception MoreThanOneElement()
|
||||
{
|
||||
return new InvalidOperationException("Source sequence contains more than one element.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void ThrowArgumentException(string message)
|
||||
{
|
||||
throw new ArgumentException(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void ThrowNotYetCompleted()
|
||||
{
|
||||
throw new InvalidOperationException("Not yet completed.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static T ThrowNotYetCompleted<T>()
|
||||
{
|
||||
throw new InvalidOperationException("Not yet completed.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void ThrowWhenContinuationIsAlreadyRegistered<T>(T continuationField)
|
||||
where T : class
|
||||
{
|
||||
if (continuationField != null) ThrowInvalidOperationExceptionCore("continuation is already registered.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
static void ThrowInvalidOperationExceptionCore(string message)
|
||||
{
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void ThrowOperationCanceledException()
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4cd4f29f0b944572a9ddaeb813494a03
|
||||
timeCreated: 1694767045
|
@@ -12,12 +12,12 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class OperationHandleBaseExtensions
|
||||
{
|
||||
public static UniTask.Awaiter GetAwaiter(this OperationHandleBase handle)
|
||||
public static UniTask.Awaiter GetAwaiter(this HandleBase handle)
|
||||
{
|
||||
return ToUniTask(handle).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this OperationHandleBase handle,
|
||||
public static UniTask ToUniTask(this HandleBase handle,
|
||||
IProgress<float> progress = null,
|
||||
PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
||||
{
|
||||
@@ -54,15 +54,15 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskPool.RegisterSizeGetter(typeof(OperationHandleBaserConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
private readonly Action<OperationHandleBase> continuationAction;
|
||||
private OperationHandleBase handle;
|
||||
private readonly Action<HandleBase> continuationAction;
|
||||
private HandleBase handle;
|
||||
private IProgress<float> progress;
|
||||
private bool completed;
|
||||
private UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
OperationHandleBaserConfiguredSource() { continuationAction = Continuation; }
|
||||
|
||||
public static IUniTaskSource Create(OperationHandleBase handle,
|
||||
public static IUniTaskSource Create(HandleBase handle,
|
||||
PlayerLoopTiming timing,
|
||||
IProgress<float> progress,
|
||||
out short token)
|
||||
@@ -83,40 +83,46 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
// BUG 在 Unity 2020.3.36 版本测试中, IL2Cpp 会报 如下错误
|
||||
// BUG ArgumentException: Incompatible Delegate Types. First is System.Action`1[[YooAsset.AssetOperationHandle, YooAsset, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]] second is System.Action`1[[YooAsset.OperationHandleBase, YooAsset, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
|
||||
// BUG ArgumentException: Incompatible Delegate Types. First is System.Action`1[[YooAsset.AssetHandle, YooAsset, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]] second is System.Action`1[[YooAsset.OperationHandleBase, YooAsset, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]
|
||||
// BUG 也可能报的是 Action '1' Action '1' 的 InvalidCastException
|
||||
// BUG 此处不得不这么修改, 如果后续 Unity 修复了这个问题, 可以恢复之前的写法
|
||||
#if UNITY_2020_BUG
|
||||
switch(handle)
|
||||
{
|
||||
case AssetOperationHandle asset_handle:
|
||||
case AssetHandle asset_handle:
|
||||
asset_handle.Completed += result.AssetContinuation;
|
||||
break;
|
||||
case SceneOperationHandle scene_handle:
|
||||
case SceneHandle scene_handle:
|
||||
scene_handle.Completed += result.SceneContinuation;
|
||||
break;
|
||||
case SubAssetsOperationHandle sub_asset_handle:
|
||||
case SubAssetsHandle sub_asset_handle:
|
||||
sub_asset_handle.Completed += result.SubContinuation;
|
||||
break;
|
||||
case RawFileOperationHandle raw_file_handle:
|
||||
case RawFileHandle raw_file_handle:
|
||||
raw_file_handle.Completed += result.RawFileContinuation;
|
||||
break;
|
||||
case AllAssetsHandle all_assets_handle:
|
||||
all_assets_handle.Completed += result.AllAssetsContinuation;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (handle)
|
||||
{
|
||||
case AssetOperationHandle asset_handle:
|
||||
case AssetHandle asset_handle:
|
||||
asset_handle.Completed += result.continuationAction;
|
||||
break;
|
||||
case SceneOperationHandle scene_handle:
|
||||
case SceneHandle scene_handle:
|
||||
scene_handle.Completed += result.continuationAction;
|
||||
break;
|
||||
case SubAssetsOperationHandle sub_asset_handle:
|
||||
case SubAssetsHandle sub_asset_handle:
|
||||
sub_asset_handle.Completed += result.continuationAction;
|
||||
break;
|
||||
case RawFileOperationHandle raw_file_handle:
|
||||
case RawFileHandle raw_file_handle:
|
||||
raw_file_handle.Completed += result.continuationAction;
|
||||
break;
|
||||
case AllAssetsHandle all_assets_handle:
|
||||
all_assets_handle.Completed += result.continuationAction;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
token = result.core.Version;
|
||||
@@ -124,29 +130,35 @@ namespace Cysharp.Threading.Tasks
|
||||
return result;
|
||||
}
|
||||
#if UNITY_2020_BUG
|
||||
private void AssetContinuation(AssetOperationHandle handle)
|
||||
private void AssetContinuation(AssetHandle handle)
|
||||
{
|
||||
handle.Completed -= AssetContinuation;
|
||||
BaseContinuation();
|
||||
}
|
||||
|
||||
private void SceneContinuation(SceneOperationHandle handle)
|
||||
private void SceneContinuation(SceneHandle handle)
|
||||
{
|
||||
handle.Completed -= SceneContinuation;
|
||||
BaseContinuation();
|
||||
}
|
||||
|
||||
private void SubContinuation(SubAssetsOperationHandle handle)
|
||||
private void SubContinuation(SubAssetsHandle handle)
|
||||
{
|
||||
handle.Completed -= SubContinuation;
|
||||
BaseContinuation();
|
||||
}
|
||||
|
||||
private void RawFileContinuation(RawFileOperationHandle handle)
|
||||
private void RawFileContinuation(RawFileHandle handle)
|
||||
{
|
||||
handle.Completed -= RawFileContinuation;
|
||||
BaseContinuation();
|
||||
}
|
||||
|
||||
private void AllAssetsContinuation(AllAssetsHandle handle)
|
||||
{
|
||||
handle.Completed -= AllAssetsContinuation;
|
||||
BaseContinuation();
|
||||
}
|
||||
#endif
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void BaseContinuation()
|
||||
@@ -169,22 +181,25 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
}
|
||||
|
||||
private void Continuation(OperationHandleBase _)
|
||||
private void Continuation(HandleBase _)
|
||||
{
|
||||
switch(handle)
|
||||
{
|
||||
case AssetOperationHandle asset_handle:
|
||||
case AssetHandle asset_handle:
|
||||
asset_handle.Completed -= continuationAction;
|
||||
break;
|
||||
case SceneOperationHandle scene_handle:
|
||||
case SceneHandle scene_handle:
|
||||
scene_handle.Completed -= continuationAction;
|
||||
break;
|
||||
case SubAssetsOperationHandle sub_asset_handle:
|
||||
case SubAssetsHandle sub_asset_handle:
|
||||
sub_asset_handle.Completed -= continuationAction;
|
||||
break;
|
||||
case RawFileOperationHandle raw_file_handle:
|
||||
case RawFileHandle raw_file_handle:
|
||||
raw_file_handle.Completed -= continuationAction;
|
||||
break;
|
||||
case AllAssetsHandle all_assets_handle:
|
||||
all_assets_handle.Completed -= continuationAction;
|
||||
break;
|
||||
}
|
||||
|
||||
BaseContinuation();
|
||||
|
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "UniTask.YooAsset",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e72e370b27cbfd41af43a5e7ecce552
|
||||
guid: 633f49a8aafb6fa43894cd4646c71743
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87f9c2230fa75e241ad00d0082d4bdf2
|
||||
guid: 4cc94a232b1c1154b8084bdda29c3484
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
237
UnityProject/Packages/UniTask/Runtime/Linq/Average.tt
Normal file
237
UnityProject/Packages/UniTask/Runtime/Linq/Average.tt
Normal file
@@ -0,0 +1,237 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var types = new[]
|
||||
{
|
||||
(typeof(int), "double"),
|
||||
(typeof(long), "double"),
|
||||
(typeof(float),"float"),
|
||||
(typeof(double),"double"),
|
||||
(typeof(decimal),"decimal"),
|
||||
|
||||
(typeof(int?),"double?"),
|
||||
(typeof(long?),"double?"),
|
||||
(typeof(float?),"float?"),
|
||||
(typeof(double?),"double?"),
|
||||
(typeof(decimal?),"decimal?"),
|
||||
};
|
||||
|
||||
Func<Type, bool> IsNullable = x => x.IsGenericType;
|
||||
Func<Type, Type> ElementType = x => IsNullable(x) ? x.GetGenericArguments()[0] : x;
|
||||
Func<Type, string> TypeName = x => IsNullable(x) ? x.GetGenericArguments()[0].Name + "?" : x.Name;
|
||||
Func<Type, string> WithSuffix = x => IsNullable(x) ? ".GetValueOrDefault()" : "";
|
||||
Func<Type, string> CalcResult = x => { var e = ElementType(x); return (e == typeof(int) || e == typeof(long)) ? "(double)sum / count" : (e == typeof(float)) ? "(float)(sum / count)" : "sum / count"; };
|
||||
#>
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
<# foreach(var (t, ret) in types) { #>
|
||||
public static UniTask<<#= ret #>> AverageAsync(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Average.AverageAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= ret #>> AverageAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.AverageAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= ret #>> AverageAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.AverageAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= ret #>> AverageAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Average.AverageAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
|
||||
internal static class Average
|
||||
{
|
||||
<# foreach(var (t, ret) in types) { #>
|
||||
public static async UniTask<<#= ret #>> AverageAsync(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
<# if (IsNullable(t)) { #>
|
||||
var v = e.Current;
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
<# } else { #>
|
||||
checked
|
||||
{
|
||||
sum += e.Current;
|
||||
count++;
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= ret #>> AverageAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
<# if (IsNullable(t)) { #>
|
||||
var v = selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
<# } else { #>
|
||||
checked
|
||||
{
|
||||
sum += selector(e.Current);
|
||||
count++;
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= ret #>> AverageAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
<# if (IsNullable(t)) { #>
|
||||
var v = await selector(e.Current);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
<# } else { #>
|
||||
checked
|
||||
{
|
||||
sum += await selector(e.Current);
|
||||
count++;
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= ret #>> AverageAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
long count = 0;
|
||||
<#= TypeName(t) #> sum = 0;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
<# if (IsNullable(t)) { #>
|
||||
var v = await selector(e.Current, cancellationToken);
|
||||
if (v.HasValue)
|
||||
{
|
||||
checked
|
||||
{
|
||||
sum += v.Value;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
<# } else { #>
|
||||
checked
|
||||
{
|
||||
sum += await selector(e.Current, cancellationToken);
|
||||
count++;
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return <#= CalcResult(t) #>;
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84bce45768c171d4490153eb08630a98
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
221
UnityProject/Packages/UniTask/Runtime/Linq/CombineLatest.tt
Normal file
221
UnityProject/Packages/UniTask/Runtime/Linq/CombineLatest.tt
Normal file
@@ -0,0 +1,221 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var tMax = 15;
|
||||
Func<int, string> typeArgs = x => string.Join(", ", Enumerable.Range(1, x).Select(x => $"T{x}")) + ", TResult";
|
||||
Func<int, string> paramArgs = x => string.Join(", ", Enumerable.Range(1, x).Select(x => $"IUniTaskAsyncEnumerable<T{x}> source{x}"));
|
||||
Func<int, string> parameters = x => string.Join(", ", Enumerable.Range(1, x).Select(x => $"source{x}"));
|
||||
|
||||
|
||||
#>
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
<# for(var i = 2; i <= tMax; i++) { #>
|
||||
public static IUniTaskAsyncEnumerable<TResult> CombineLatest<<#= typeArgs(i) #>>(this <#= paramArgs(i) #>, Func<<#= typeArgs(i) #>> resultSelector)
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
Error.ThrowArgumentNullException(source<#= j #>, nameof(source<#= j #>));
|
||||
<# } #>
|
||||
Error.ThrowArgumentNullException(resultSelector, nameof(resultSelector));
|
||||
|
||||
return new CombineLatest<<#= typeArgs(i) #>>(<#= parameters(i) #>, resultSelector);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<# for(var i = 2; i <= tMax; i++) { #>
|
||||
internal class CombineLatest<<#= typeArgs(i) #>> : IUniTaskAsyncEnumerable<TResult>
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
readonly IUniTaskAsyncEnumerable<T<#= j #>> source<#= j #>;
|
||||
<# } #>
|
||||
readonly Func<<#= typeArgs(i) #>> resultSelector;
|
||||
|
||||
public CombineLatest(<#= paramArgs(i) #>, Func<<#= typeArgs(i) #>> resultSelector)
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
this.source<#= j #> = source<#= j #>;
|
||||
<# } #>
|
||||
this.resultSelector = resultSelector;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _CombineLatest(<#= parameters(i) #>, resultSelector, cancellationToken);
|
||||
}
|
||||
|
||||
class _CombineLatest : MoveNextSource, IUniTaskAsyncEnumerator<TResult>
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
static readonly Action<object> Completed<#= j #>Delegate = Completed<#= j #>;
|
||||
<# } #>
|
||||
const int CompleteCount = <#= i #>;
|
||||
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
readonly IUniTaskAsyncEnumerable<T<#= j #>> source<#= j #>;
|
||||
<# } #>
|
||||
readonly Func<<#= typeArgs(i) #>> resultSelector;
|
||||
CancellationToken cancellationToken;
|
||||
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
IUniTaskAsyncEnumerator<T<#= j #>> enumerator<#= j #>;
|
||||
UniTask<bool>.Awaiter awaiter<#= j #>;
|
||||
bool hasCurrent<#= j #>;
|
||||
bool running<#= j #>;
|
||||
T<#= j #> current<#= j #>;
|
||||
|
||||
<# } #>
|
||||
int completedCount;
|
||||
bool syncRunning;
|
||||
TResult result;
|
||||
|
||||
public _CombineLatest(<#= paramArgs(i) #>, Func<<#= typeArgs(i) #>> resultSelector, CancellationToken cancellationToken)
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
this.source<#= j #> = source<#= j #>;
|
||||
<# } #>
|
||||
this.resultSelector = resultSelector;
|
||||
this.cancellationToken = cancellationToken;
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
}
|
||||
|
||||
public TResult Current => result;
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
if (completedCount == CompleteCount) return CompletedTasks.False;
|
||||
|
||||
if (enumerator1 == null)
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
enumerator<#= j #> = source<#= j #>.GetAsyncEnumerator(cancellationToken);
|
||||
<# } #>
|
||||
}
|
||||
|
||||
completionSource.Reset();
|
||||
|
||||
AGAIN:
|
||||
syncRunning = true;
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
if (!running<#= j #>)
|
||||
{
|
||||
running<#= j #> = true;
|
||||
awaiter<#= j #> = enumerator<#= j #>.MoveNextAsync().GetAwaiter();
|
||||
if (awaiter<#= j #>.IsCompleted)
|
||||
{
|
||||
Completed<#= j #>(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
awaiter<#= j #>.SourceOnCompleted(Completed<#= j #>Delegate, this);
|
||||
}
|
||||
}
|
||||
<# } #>
|
||||
|
||||
if (<#= string.Join(" || ", Enumerable.Range(1, i).Select(x => $"!running{x}")) #>)
|
||||
{
|
||||
goto AGAIN;
|
||||
}
|
||||
syncRunning = false;
|
||||
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
static void Completed<#= j #>(object state)
|
||||
{
|
||||
var self = (_CombineLatest)state;
|
||||
self.running<#= j #> = false;
|
||||
|
||||
try
|
||||
{
|
||||
if (self.awaiter<#= j #>.GetResult())
|
||||
{
|
||||
self.hasCurrent<#= j #> = true;
|
||||
self.current<#= j #> = self.enumerator<#= j #>.Current;
|
||||
goto SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.running<#= j #> = true; // as complete, no more call MoveNextAsync.
|
||||
if (Interlocked.Increment(ref self.completedCount) == CompleteCount)
|
||||
{
|
||||
goto COMPLETE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.running<#= j #> = true; // as complete, no more call MoveNextAsync.
|
||||
self.completedCount = CompleteCount;
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
SUCCESS:
|
||||
if (!self.TrySetResult())
|
||||
{
|
||||
if (self.syncRunning) return;
|
||||
self.running<#= j #> = true; // as complete, no more call MoveNextAsync.
|
||||
try
|
||||
{
|
||||
self.awaiter<#= j #> = self.enumerator<#= j #>.MoveNextAsync().GetAwaiter();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.completedCount = CompleteCount;
|
||||
self.completionSource.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
self.awaiter<#= j #>.SourceOnCompleted(Completed<#= j #>Delegate, self);
|
||||
}
|
||||
return;
|
||||
COMPLETE:
|
||||
self.completionSource.TrySetResult(false);
|
||||
return;
|
||||
}
|
||||
|
||||
<# } #>
|
||||
bool TrySetResult()
|
||||
{
|
||||
if (<#= string.Join(" && ", Enumerable.Range(1, i).Select(x => $"hasCurrent{x}")) #>)
|
||||
{
|
||||
result = resultSelector(<#= string.Join(", ", Enumerable.Range(1, i).Select(x => $"current{x}")) #>);
|
||||
completionSource.TrySetResult(true);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async UniTask DisposeAsync()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
if (enumerator<#= j #> != null)
|
||||
{
|
||||
await enumerator<#= j #>.DisposeAsync();
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1b8cfa9d17af814a971ee2224aaaaa2
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
262
UnityProject/Packages/UniTask/Runtime/Linq/MinMax.tt
Normal file
262
UnityProject/Packages/UniTask/Runtime/Linq/MinMax.tt
Normal file
@@ -0,0 +1,262 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var types = new[]
|
||||
{
|
||||
typeof(int),
|
||||
typeof(long),
|
||||
typeof(float),
|
||||
typeof(double),
|
||||
typeof(decimal),
|
||||
|
||||
typeof(int?),
|
||||
typeof(long?),
|
||||
typeof(float?),
|
||||
typeof(double?),
|
||||
typeof(decimal?),
|
||||
};
|
||||
|
||||
Func<Type, bool> IsNullable = x => x.IsGenericType;
|
||||
Func<Type, string> TypeName = x => IsNullable(x) ? x.GetGenericArguments()[0].Name + "?" : x.Name;
|
||||
Func<Type, string> WithSuffix = x => IsNullable(x) ? ".GetValueOrDefault()" : "";
|
||||
#>
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
<# foreach(var (minMax, op) in new[]{("Min",">"), ("Max", "<")}) { #>
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
<# foreach(var t in types) { #>
|
||||
public static UniTask<<#= TypeName(t) #>> <#= minMax #>Async(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return <#= minMax #>.<#= minMax #>Async(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= TypeName(t) #>> <#= minMax #>Async<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return <#= minMax #>.<#= minMax #>Async(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return <#= minMax #>.<#= minMax #>AwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return <#= minMax #>.<#= minMax #>AwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
|
||||
internal static partial class <#= minMax #>
|
||||
{
|
||||
<# foreach(var t in types) { #>
|
||||
public static async UniTask<<#= TypeName(t) #>> <#= minMax #>Async(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> value = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
value = e.Current;
|
||||
<# if (IsNullable(t)) { #>
|
||||
if(value == null) continue;
|
||||
<# } #>
|
||||
goto NEXT_LOOP;
|
||||
}
|
||||
|
||||
<# if (IsNullable(t)) { #>
|
||||
return default;
|
||||
<# } else { #>
|
||||
throw Error.NoElements();
|
||||
<# } #>
|
||||
NEXT_LOOP:
|
||||
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
var x = e.Current;
|
||||
<# if (IsNullable(t)) { #>
|
||||
if( x == null) continue;
|
||||
<# } #>
|
||||
if (value <#= op #> x)
|
||||
{
|
||||
value = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= TypeName(t) #>> <#= minMax #>Async<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> value = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
value = selector(e.Current);
|
||||
<# if (IsNullable(t)) { #>
|
||||
if(value == null) continue;
|
||||
<# } #>
|
||||
goto NEXT_LOOP;
|
||||
}
|
||||
|
||||
<# if (IsNullable(t)) { #>
|
||||
return default;
|
||||
<# } else { #>
|
||||
throw Error.NoElements();
|
||||
<# } #>
|
||||
NEXT_LOOP:
|
||||
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
var x = selector(e.Current);
|
||||
<# if (IsNullable(t)) { #>
|
||||
if( x == null) continue;
|
||||
<# } #>
|
||||
if (value <#= op #> x)
|
||||
{
|
||||
value = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> value = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
value = await selector(e.Current);
|
||||
<# if (IsNullable(t)) { #>
|
||||
if(value == null) continue;
|
||||
<# } #>
|
||||
goto NEXT_LOOP;
|
||||
}
|
||||
|
||||
<# if (IsNullable(t)) { #>
|
||||
return default;
|
||||
<# } else { #>
|
||||
throw Error.NoElements();
|
||||
<# } #>
|
||||
NEXT_LOOP:
|
||||
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
var x = await selector(e.Current);
|
||||
<# if (IsNullable(t)) { #>
|
||||
if( x == null) continue;
|
||||
<# } #>
|
||||
if (value <#= op #> x)
|
||||
{
|
||||
value = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> value = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
value = await selector(e.Current, cancellationToken);
|
||||
<# if (IsNullable(t)) { #>
|
||||
if(value == null) continue;
|
||||
<# } #>
|
||||
goto NEXT_LOOP;
|
||||
}
|
||||
|
||||
<# if (IsNullable(t)) { #>
|
||||
return default;
|
||||
<# } else { #>
|
||||
throw Error.NoElements();
|
||||
<# } #>
|
||||
NEXT_LOOP:
|
||||
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
var x = await selector(e.Current, cancellationToken);
|
||||
<# if (IsNullable(t)) { #>
|
||||
if( x == null) continue;
|
||||
<# } #>
|
||||
if (value <#= op #> x)
|
||||
{
|
||||
value = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18108e9feb2ec40498df573cfef2ea15
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
167
UnityProject/Packages/UniTask/Runtime/Linq/Sum.tt
Normal file
167
UnityProject/Packages/UniTask/Runtime/Linq/Sum.tt
Normal file
@@ -0,0 +1,167 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var types = new[]
|
||||
{
|
||||
typeof(int),
|
||||
typeof(long),
|
||||
typeof(float),
|
||||
typeof(double),
|
||||
typeof(decimal),
|
||||
|
||||
typeof(int?),
|
||||
typeof(long?),
|
||||
typeof(float?),
|
||||
typeof(double?),
|
||||
typeof(decimal?),
|
||||
};
|
||||
|
||||
Func<Type, bool> IsNullable = x => x.IsGenericType;
|
||||
Func<Type, string> TypeName = x => IsNullable(x) ? x.GetGenericArguments()[0].Name + "?" : x.Name;
|
||||
Func<Type, string> WithSuffix = x => IsNullable(x) ? ".GetValueOrDefault()" : "";
|
||||
#>
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
<# foreach(var t in types) { #>
|
||||
public static UniTask<<#= TypeName(t) #>> SumAsync(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
|
||||
return Sum.SumAsync(source, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= TypeName(t) #>> SumAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Sum.SumAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= TypeName(t) #>> SumAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Sum.SumAwaitAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<<#= TypeName(t) #>> SumAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
|
||||
{
|
||||
Error.ThrowArgumentNullException(source, nameof(source));
|
||||
Error.ThrowArgumentNullException(source, nameof(selector));
|
||||
|
||||
return Sum.SumAwaitWithCancellationAsync(source, selector, cancellationToken);
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
|
||||
internal static class Sum
|
||||
{
|
||||
<# foreach(var t in types) { #>
|
||||
public static async UniTask<<#= TypeName(t) #>> SumAsync(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> sum = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
sum += e.Current<#= WithSuffix(t) #>;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= TypeName(t) #>> SumAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> sum = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
sum += selector(e.Current)<#= WithSuffix(t) #>;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= TypeName(t) #>> SumAwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> sum = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
sum += (await selector(e.Current))<#= WithSuffix(t) #>;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static async UniTask<<#= TypeName(t) #>> SumAwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
|
||||
{
|
||||
<#= TypeName(t) #> sum = default;
|
||||
|
||||
var e = source.GetAsyncEnumerator(cancellationToken);
|
||||
try
|
||||
{
|
||||
while (await e.MoveNextAsync())
|
||||
{
|
||||
sum += (await selector(e.Current, cancellationToken))<#= WithSuffix(t) #>;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (e != null)
|
||||
{
|
||||
await e.DisposeAsync();
|
||||
}
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
}
|
7
UnityProject/Packages/UniTask/Runtime/Linq/Sum.tt.meta
Normal file
7
UnityProject/Packages/UniTask/Runtime/Linq/Sum.tt.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b61271ca8e712494ab1ce2d10b180b6f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c463ff8cd00c4e449ca9bfe6a6c6b4d
|
||||
guid: 669f5459819f7284ca1b35f4d55fe226
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -4,38 +4,50 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
|
||||
{
|
||||
return new EveryUpdate(updateTiming);
|
||||
return new EveryUpdate(updateTiming, cancelImmediately);
|
||||
}
|
||||
}
|
||||
|
||||
internal class EveryUpdate : IUniTaskAsyncEnumerable<AsyncUnit>
|
||||
{
|
||||
readonly PlayerLoopTiming updateTiming;
|
||||
readonly bool cancelImmediately;
|
||||
|
||||
public EveryUpdate(PlayerLoopTiming updateTiming)
|
||||
public EveryUpdate(PlayerLoopTiming updateTiming, bool cancelImmediately)
|
||||
{
|
||||
this.updateTiming = updateTiming;
|
||||
this.cancelImmediately = cancelImmediately;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _EveryUpdate(updateTiming, cancellationToken);
|
||||
return new _EveryUpdate(updateTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
class _EveryUpdate : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
|
||||
{
|
||||
readonly PlayerLoopTiming updateTiming;
|
||||
CancellationToken cancellationToken;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
bool disposed;
|
||||
|
||||
public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken)
|
||||
public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
this.updateTiming = updateTiming;
|
||||
this.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (_EveryUpdate)state;
|
||||
source.completionSource.TrySetCanceled(source.cancellationToken);
|
||||
}, this);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 2);
|
||||
PlayerLoopHelper.AddAction(updateTiming, this);
|
||||
}
|
||||
@@ -44,10 +56,14 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// return false instead of throw
|
||||
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
|
||||
|
||||
if (disposed) return CompletedTasks.False;
|
||||
|
||||
completionSource.Reset();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
@@ -55,6 +71,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
cancellationTokenRegistration.Dispose();
|
||||
disposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
@@ -63,7 +80,13 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (disposed || cancellationToken.IsCancellationRequested)
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (disposed)
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
return false;
|
||||
|
@@ -7,7 +7,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
public static IUniTaskAsyncEnumerable<TProperty> EveryValueChanged<TTarget, TProperty>(TTarget target, Func<TTarget, TProperty> propertySelector, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<TProperty> equalityComparer = null)
|
||||
public static IUniTaskAsyncEnumerable<TProperty> EveryValueChanged<TTarget, TProperty>(TTarget target, Func<TTarget, TProperty> propertySelector, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<TProperty> equalityComparer = null, bool cancelImmediately = false)
|
||||
where TTarget : class
|
||||
{
|
||||
var unityObject = target as UnityEngine.Object;
|
||||
@@ -15,11 +15,11 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
if (isUnityObject)
|
||||
{
|
||||
return new EveryValueChangedUnityObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming);
|
||||
return new EveryValueChangedUnityObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming, cancelImmediately);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new EveryValueChangedStandardObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming);
|
||||
return new EveryValueChangedStandardObject<TTarget, TProperty>(target, propertySelector, equalityComparer ?? UnityEqualityComparer.GetDefault<TProperty>(), monitorTiming, cancelImmediately);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,18 +30,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly Func<TTarget, TProperty> propertySelector;
|
||||
readonly IEqualityComparer<TProperty> equalityComparer;
|
||||
readonly PlayerLoopTiming monitorTiming;
|
||||
readonly bool cancelImmediately;
|
||||
|
||||
public EveryValueChangedUnityObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming)
|
||||
public EveryValueChangedUnityObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, bool cancelImmediately)
|
||||
{
|
||||
this.target = target;
|
||||
this.propertySelector = propertySelector;
|
||||
this.equalityComparer = equalityComparer;
|
||||
this.monitorTiming = monitorTiming;
|
||||
this.cancelImmediately = cancelImmediately;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<TProperty> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken);
|
||||
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
sealed class _EveryValueChanged : MoveNextSource, IUniTaskAsyncEnumerator<TProperty>, IPlayerLoopItem
|
||||
@@ -50,13 +52,14 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly UnityEngine.Object targetAsUnityObject;
|
||||
readonly IEqualityComparer<TProperty> equalityComparer;
|
||||
readonly Func<TTarget, TProperty> propertySelector;
|
||||
CancellationToken cancellationToken;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
bool first;
|
||||
TProperty currentValue;
|
||||
bool disposed;
|
||||
|
||||
public _EveryValueChanged(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken)
|
||||
public _EveryValueChanged(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
this.target = target;
|
||||
this.targetAsUnityObject = target as UnityEngine.Object;
|
||||
@@ -64,6 +67,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
this.equalityComparer = equalityComparer;
|
||||
this.cancellationToken = cancellationToken;
|
||||
this.first = true;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (_EveryValueChanged)state;
|
||||
source.completionSource.TrySetCanceled(source.cancellationToken);
|
||||
}, this);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 2);
|
||||
PlayerLoopHelper.AddAction(monitorTiming, this);
|
||||
}
|
||||
@@ -72,8 +85,15 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// return false instead of throw
|
||||
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
|
||||
if (disposed) return CompletedTasks.False;
|
||||
|
||||
completionSource.Reset();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
@@ -86,7 +106,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return CompletedTasks.True;
|
||||
}
|
||||
|
||||
completionSource.Reset();
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
@@ -94,6 +113,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
cancellationTokenRegistration.Dispose();
|
||||
disposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
@@ -102,13 +122,18 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (disposed || cancellationToken.IsCancellationRequested || targetAsUnityObject == null) // destroyed = cancel.
|
||||
if (disposed || targetAsUnityObject == null)
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
TProperty nextValue = default(TProperty);
|
||||
try
|
||||
{
|
||||
@@ -139,18 +164,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly Func<TTarget, TProperty> propertySelector;
|
||||
readonly IEqualityComparer<TProperty> equalityComparer;
|
||||
readonly PlayerLoopTiming monitorTiming;
|
||||
readonly bool cancelImmediately;
|
||||
|
||||
public EveryValueChangedStandardObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming)
|
||||
public EveryValueChangedStandardObject(TTarget target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, bool cancelImmediately)
|
||||
{
|
||||
this.target = new WeakReference<TTarget>(target, false);
|
||||
this.propertySelector = propertySelector;
|
||||
this.equalityComparer = equalityComparer;
|
||||
this.monitorTiming = monitorTiming;
|
||||
this.cancelImmediately = cancelImmediately;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<TProperty> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken);
|
||||
return new _EveryValueChanged(target, propertySelector, equalityComparer, monitorTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
sealed class _EveryValueChanged : MoveNextSource, IUniTaskAsyncEnumerator<TProperty>, IPlayerLoopItem
|
||||
@@ -158,19 +185,30 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly WeakReference<TTarget> target;
|
||||
readonly IEqualityComparer<TProperty> equalityComparer;
|
||||
readonly Func<TTarget, TProperty> propertySelector;
|
||||
CancellationToken cancellationToken;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
bool first;
|
||||
TProperty currentValue;
|
||||
bool disposed;
|
||||
|
||||
public _EveryValueChanged(WeakReference<TTarget> target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken)
|
||||
public _EveryValueChanged(WeakReference<TTarget> target, Func<TTarget, TProperty> propertySelector, IEqualityComparer<TProperty> equalityComparer, PlayerLoopTiming monitorTiming, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
this.target = target;
|
||||
this.propertySelector = propertySelector;
|
||||
this.equalityComparer = equalityComparer;
|
||||
this.cancellationToken = cancellationToken;
|
||||
this.first = true;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (_EveryValueChanged)state;
|
||||
source.completionSource.TrySetCanceled(source.cancellationToken);
|
||||
}, this);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 2);
|
||||
PlayerLoopHelper.AddAction(monitorTiming, this);
|
||||
}
|
||||
@@ -179,8 +217,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
if (disposed || cancellationToken.IsCancellationRequested) return CompletedTasks.False;
|
||||
if (disposed) return CompletedTasks.False;
|
||||
|
||||
completionSource.Reset();
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
@@ -192,7 +238,6 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
return CompletedTasks.True;
|
||||
}
|
||||
|
||||
completionSource.Reset();
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
@@ -200,6 +245,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
cancellationTokenRegistration.Dispose();
|
||||
disposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
@@ -208,13 +254,19 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (disposed || cancellationToken.IsCancellationRequested || !target.TryGetTarget(out var t))
|
||||
if (disposed || !target.TryGetTarget(out var t))
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
DisposeAsync().Forget();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
TProperty nextValue = default(TProperty);
|
||||
try
|
||||
{
|
||||
|
@@ -6,32 +6,32 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
public static partial class UniTaskAsyncEnumerable
|
||||
{
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false, bool cancelImmediately = false)
|
||||
{
|
||||
return new Timer(dueTime, null, updateTiming, ignoreTimeScale);
|
||||
return new Timer(dueTime, null, updateTiming, ignoreTimeScale, cancelImmediately);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> Timer(TimeSpan dueTime, TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false, bool cancelImmediately = false)
|
||||
{
|
||||
return new Timer(dueTime, period, updateTiming, ignoreTimeScale);
|
||||
return new Timer(dueTime, period, updateTiming, ignoreTimeScale, cancelImmediately);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> Interval(TimeSpan period, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool ignoreTimeScale = false, bool cancelImmediately = false)
|
||||
{
|
||||
return new Timer(period, period, updateTiming, ignoreTimeScale);
|
||||
return new Timer(period, period, updateTiming, ignoreTimeScale, cancelImmediately);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
|
||||
{
|
||||
if (dueTimeFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. dueTimeFrameCount:" + dueTimeFrameCount);
|
||||
}
|
||||
|
||||
return new TimerFrame(dueTimeFrameCount, null, updateTiming);
|
||||
return new TimerFrame(dueTimeFrameCount, null, updateTiming, cancelImmediately);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> TimerFrame(int dueTimeFrameCount, int periodFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
|
||||
{
|
||||
if (dueTimeFrameCount < 0)
|
||||
{
|
||||
@@ -42,16 +42,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus periodFrameCount. periodFrameCount:" + dueTimeFrameCount);
|
||||
}
|
||||
|
||||
return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming);
|
||||
return new TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancelImmediately);
|
||||
}
|
||||
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update)
|
||||
public static IUniTaskAsyncEnumerable<AsyncUnit> IntervalFrame(int intervalFrameCount, PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
|
||||
{
|
||||
if (intervalFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus intervalFrameCount. intervalFrameCount:" + intervalFrameCount);
|
||||
}
|
||||
return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming);
|
||||
return new TimerFrame(intervalFrameCount, intervalFrameCount, updateTiming, cancelImmediately);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,18 +61,20 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly TimeSpan dueTime;
|
||||
readonly TimeSpan? period;
|
||||
readonly bool ignoreTimeScale;
|
||||
readonly bool cancelImmediately;
|
||||
|
||||
public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale)
|
||||
public Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, bool cancelImmediately)
|
||||
{
|
||||
this.updateTiming = updateTiming;
|
||||
this.dueTime = dueTime;
|
||||
this.period = period;
|
||||
this.ignoreTimeScale = ignoreTimeScale;
|
||||
this.cancelImmediately = cancelImmediately;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _Timer(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken);
|
||||
return new _Timer(dueTime, period, updateTiming, ignoreTimeScale, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
class _Timer : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
|
||||
@@ -81,7 +83,8 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly float? period;
|
||||
readonly PlayerLoopTiming updateTiming;
|
||||
readonly bool ignoreTimeScale;
|
||||
CancellationToken cancellationToken;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
int initialFrame;
|
||||
float elapsed;
|
||||
@@ -89,7 +92,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
bool completed;
|
||||
bool disposed;
|
||||
|
||||
public _Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken)
|
||||
public _Timer(TimeSpan dueTime, TimeSpan? period, PlayerLoopTiming updateTiming, bool ignoreTimeScale, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
this.dueTime = (float)dueTime.TotalSeconds;
|
||||
this.period = (period == null) ? null : (float?)period.Value.TotalSeconds;
|
||||
@@ -105,6 +108,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
this.updateTiming = updateTiming;
|
||||
this.ignoreTimeScale = ignoreTimeScale;
|
||||
this.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (_Timer)state;
|
||||
source.completionSource.TrySetCanceled(source.cancellationToken);
|
||||
}, this);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 2);
|
||||
PlayerLoopHelper.AddAction(updateTiming, this);
|
||||
}
|
||||
@@ -114,12 +127,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// return false instead of throw
|
||||
if (disposed || cancellationToken.IsCancellationRequested || completed) return CompletedTasks.False;
|
||||
if (disposed || completed) return CompletedTasks.False;
|
||||
|
||||
// reset value here.
|
||||
this.elapsed = 0;
|
||||
|
||||
completionSource.Reset();
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
|
||||
@@ -127,6 +144,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
cancellationTokenRegistration.Dispose();
|
||||
disposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
@@ -135,11 +153,16 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (disposed || cancellationToken.IsCancellationRequested)
|
||||
if (disposed)
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
return false;
|
||||
}
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dueTimePhase)
|
||||
{
|
||||
@@ -187,24 +210,27 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
readonly PlayerLoopTiming updateTiming;
|
||||
readonly int dueTimeFrameCount;
|
||||
readonly int? periodFrameCount;
|
||||
readonly bool cancelImmediately;
|
||||
|
||||
public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming)
|
||||
public TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, bool cancelImmediately)
|
||||
{
|
||||
this.updateTiming = updateTiming;
|
||||
this.dueTimeFrameCount = dueTimeFrameCount;
|
||||
this.periodFrameCount = periodFrameCount;
|
||||
this.cancelImmediately = cancelImmediately;
|
||||
}
|
||||
|
||||
public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return new _TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken);
|
||||
return new _TimerFrame(dueTimeFrameCount, periodFrameCount, updateTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
class _TimerFrame : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
|
||||
{
|
||||
readonly int dueTimeFrameCount;
|
||||
readonly int? periodFrameCount;
|
||||
CancellationToken cancellationToken;
|
||||
readonly CancellationToken cancellationToken;
|
||||
readonly CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
int initialFrame;
|
||||
int currentFrame;
|
||||
@@ -212,7 +238,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
bool completed;
|
||||
bool disposed;
|
||||
|
||||
public _TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken)
|
||||
public _TimerFrame(int dueTimeFrameCount, int? periodFrameCount, PlayerLoopTiming updateTiming, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
if (dueTimeFrameCount <= 0) dueTimeFrameCount = 0;
|
||||
if (periodFrameCount != null)
|
||||
@@ -225,6 +251,15 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
this.dueTimeFrameCount = dueTimeFrameCount;
|
||||
this.periodFrameCount = periodFrameCount;
|
||||
this.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (_TimerFrame)state;
|
||||
source.completionSource.TrySetCanceled(source.cancellationToken);
|
||||
}, this);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(this, 2);
|
||||
PlayerLoopHelper.AddAction(updateTiming, this);
|
||||
@@ -234,13 +269,15 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public UniTask<bool> MoveNextAsync()
|
||||
{
|
||||
// return false instead of throw
|
||||
if (disposed || cancellationToken.IsCancellationRequested || completed) return CompletedTasks.False;
|
||||
if (disposed || completed) return CompletedTasks.False;
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
|
||||
// reset value here.
|
||||
this.currentFrame = 0;
|
||||
|
||||
completionSource.Reset();
|
||||
return new UniTask<bool>(this, completionSource.Version);
|
||||
}
|
||||
@@ -249,6 +286,7 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
cancellationTokenRegistration.Dispose();
|
||||
disposed = true;
|
||||
TaskTracker.RemoveTracking(this);
|
||||
}
|
||||
@@ -257,7 +295,12 @@ namespace Cysharp.Threading.Tasks.Linq
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (disposed || cancellationToken.IsCancellationRequested)
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
completionSource.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
if (disposed)
|
||||
{
|
||||
completionSource.TrySetResult(false);
|
||||
return false;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1b92f798107ca0d40b1053ca41307c56
|
||||
guid: 85c0c768ced512e42b24021b3258b669
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
@@ -0,0 +1,208 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var empty = new (string, string)[0];
|
||||
|
||||
var triggers = new (string triggerName, string methodName, string returnType, string handlerInterface, (string argType, string argName)[] arguments)[]
|
||||
{
|
||||
("AnimatorIK", "OnAnimatorIK", "int", null, new []{ ("int", "layerIndex") }),
|
||||
("AnimatorMove", "OnAnimatorMove", "AsyncUnit", null, empty),
|
||||
("OnCanvasGroupChanged", "OnCanvasGroupChanged", "AsyncUnit", null, empty ),
|
||||
("CollisionEnter2D", "OnCollisionEnter2D", "Collision2D", null, new []{ ("Collision2D", "coll") }),
|
||||
("CollisionExit2D", "OnCollisionExit2D", "Collision2D", null, new []{ ("Collision2D", "coll") }),
|
||||
("CollisionStay2D", "OnCollisionStay2D", "Collision2D", null, new []{ ("Collision2D", "coll") }),
|
||||
("CollisionEnter", "OnCollisionEnter", "Collision", null, new []{ ("Collision", "coll") }),
|
||||
("CollisionExit", "OnCollisionExit", "Collision", null, new []{ ("Collision", "coll") }),
|
||||
("CollisionStay", "OnCollisionStay", "Collision", null, new []{ ("Collision", "coll") }),
|
||||
("Enable", "OnEnable", "AsyncUnit", null, empty),
|
||||
("Disable", "OnDisable", "AsyncUnit", null, empty),
|
||||
("JointBreak", "OnJointBreak", "float", null, new []{ ("float", "breakForce") }),
|
||||
("JointBreak2D", "OnJointBreak2D", "Joint2D", null, new []{ ("Joint2D", "brokenJoint") }),
|
||||
("Update", "Update", "AsyncUnit", null, empty),
|
||||
("FixedUpdate", "FixedUpdate", "AsyncUnit", null, empty),
|
||||
("LateUpdate", "LateUpdate", "AsyncUnit", null, empty),
|
||||
|
||||
("ParticleCollision", "OnParticleCollision", "GameObject", null, new []{ ("GameObject", "other") }),
|
||||
("RectTransformDimensionsChange", "OnRectTransformDimensionsChange", "AsyncUnit", null, empty),
|
||||
("RectTransformRemoved", "OnRectTransformRemoved", "AsyncUnit", null, empty),
|
||||
("BeforeTransformParentChanged", "OnBeforeTransformParentChanged", "AsyncUnit", null, empty),
|
||||
("TransformParentChanged", "OnTransformParentChanged", "AsyncUnit", null, empty),
|
||||
("TransformChildrenChanged", "OnTransformChildrenChanged", "AsyncUnit", null, empty),
|
||||
("TriggerEnter2D", "OnTriggerEnter2D", "Collider2D", null, new []{ ("Collider2D", "other") }),
|
||||
("TriggerExit2D", "OnTriggerExit2D", "Collider2D", null, new []{ ("Collider2D", "other") }),
|
||||
("TriggerStay2D", "OnTriggerStay2D", "Collider2D", null, new []{ ("Collider2D", "other") }),
|
||||
("TriggerEnter", "OnTriggerEnter", "Collider", null, new []{ ("Collider", "other") }),
|
||||
("TriggerExit", "OnTriggerExit", "Collider", null, new []{ ("Collider", "other") }),
|
||||
("TriggerStay", "OnTriggerStay", "Collider", null, new []{ ("Collider", "other") }),
|
||||
("BecameInvisible", "OnBecameInvisible", "AsyncUnit", null, empty),
|
||||
("BecameVisible", "OnBecameVisible", "AsyncUnit", null, empty),
|
||||
|
||||
// Mouse... #if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO)
|
||||
("MouseDown", "OnMouseDown", "AsyncUnit", null, empty),
|
||||
("MouseDrag", "OnMouseDrag", "AsyncUnit", null, empty),
|
||||
("MouseEnter", "OnMouseEnter", "AsyncUnit", null, empty),
|
||||
("MouseExit", "OnMouseExit", "AsyncUnit", null, empty),
|
||||
("MouseOver", "OnMouseOver", "AsyncUnit", null, empty),
|
||||
("MouseUp", "OnMouseUp", "AsyncUnit", null, empty),
|
||||
("MouseUpAsButton", "OnMouseUpAsButton", "AsyncUnit", null, empty),
|
||||
|
||||
// new in v2
|
||||
("ApplicationFocus", "OnApplicationFocus", "bool", null, new []{("bool", "hasFocus") }),
|
||||
("ApplicationPause", "OnApplicationPause", "bool", null, new []{("bool", "pauseStatus") }),
|
||||
("ApplicationQuit", "OnApplicationQuit", "AsyncUnit", null, empty),
|
||||
("AudioFilterRead", "OnAudioFilterRead", "(float[] data, int channels)", null, new[]{("float[]", "data"), ("int", "channels")}),
|
||||
("ControllerColliderHit", "OnControllerColliderHit", "ControllerColliderHit", null, new[]{("ControllerColliderHit", "hit")}),
|
||||
("DrawGizmos", "OnDrawGizmos", "AsyncUnit", null, empty),
|
||||
("DrawGizmosSelected", "OnDrawGizmosSelected", "AsyncUnit", null, empty),
|
||||
("GUI", "OnGUI", "AsyncUnit", null, empty),
|
||||
("ParticleSystemStopped", "OnParticleSystemStopped", "AsyncUnit", null, empty),
|
||||
("ParticleTrigger", "OnParticleTrigger", "AsyncUnit", null, empty),
|
||||
("PostRender", "OnPostRender", "AsyncUnit", null, empty),
|
||||
("PreCull", "OnPreCull", "AsyncUnit", null, empty),
|
||||
("PreRender", "OnPreRender", "AsyncUnit", null, empty),
|
||||
("RenderImage", "OnRenderImage", "(RenderTexture source, RenderTexture destination)", null, new[]{("RenderTexture", "source"), ("RenderTexture", "destination")}),
|
||||
("RenderObject", "OnRenderObject", "AsyncUnit", null, empty),
|
||||
("ServerInitialized", "OnServerInitialized", "AsyncUnit", null, empty),
|
||||
("Validate", "OnValidate", "AsyncUnit", null, empty),
|
||||
("WillRenderObject", "OnWillRenderObject", "AsyncUnit", null, empty),
|
||||
("Reset", "Reset", "AsyncUnit", null, empty),
|
||||
|
||||
// uGUI
|
||||
("BeginDrag", "OnBeginDrag", "PointerEventData", "IBeginDragHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("Cancel", "OnCancel", "BaseEventData", "ICancelHandler", new []{ ("BaseEventData", "eventData") }),
|
||||
("Deselect", "OnDeselect", "BaseEventData", "IDeselectHandler", new []{ ("BaseEventData", "eventData") }),
|
||||
("Drag", "OnDrag", "PointerEventData", "IDragHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("Drop", "OnDrop", "PointerEventData", "IDropHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("EndDrag", "OnEndDrag", "PointerEventData", "IEndDragHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("InitializePotentialDrag", "OnInitializePotentialDrag", "PointerEventData", "IInitializePotentialDragHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("Move", "OnMove", "AxisEventData", "IMoveHandler", new []{ ("AxisEventData", "eventData") }),
|
||||
("PointerClick", "OnPointerClick", "PointerEventData", "IPointerClickHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("PointerDown", "OnPointerDown", "PointerEventData", "IPointerDownHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("PointerEnter", "OnPointerEnter", "PointerEventData", "IPointerEnterHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("PointerExit", "OnPointerExit", "PointerEventData", "IPointerExitHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("PointerUp", "OnPointerUp", "PointerEventData", "IPointerUpHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("Scroll", "OnScroll", "PointerEventData", "IScrollHandler", new []{ ("PointerEventData", "eventData") }),
|
||||
("Select", "OnSelect", "BaseEventData", "ISelectHandler", new []{ ("BaseEventData", "eventData") }),
|
||||
("Submit", "OnSubmit", "BaseEventData", "ISubmitHandler", new []{ ("BaseEventData", "eventData") }),
|
||||
("UpdateSelected", "OnUpdateSelected", "BaseEventData", "IUpdateSelectedHandler", new []{ ("BaseEventData", "eventData") }),
|
||||
|
||||
// 2019.3
|
||||
("ParticleUpdateJobScheduled", "OnParticleUpdateJobScheduled", "UnityEngine.ParticleSystemJobs.ParticleSystemJobData", null, new[]{("UnityEngine.ParticleSystemJobs.ParticleSystemJobData", "particles")}),
|
||||
|
||||
// Oneshot
|
||||
// Awake, Start, Destroy
|
||||
};
|
||||
|
||||
triggers = triggers.OrderBy(x => x.handlerInterface != null).ThenBy(x => x.handlerInterface != null ? x.handlerInterface : x.methodName).ToArray();
|
||||
|
||||
Func<string, string> ToInterfaceName = x => $"IAsync{x}Handler";
|
||||
Func<string, string> ToUniTaskName = x => x == "AsyncUnit" ? "UniTask" : $"UniTask<{x}>";
|
||||
Func<string, string> ToCastUniTasSourceType = x => x == "AsyncUnit" ? "IUniTaskSource" : $"IUniTaskSource<{x}>";
|
||||
Func<string, string> OnInvokeSuffix = x => x == "AsyncUnit" ? ".AsUniTask()" : $"";
|
||||
Func<(string argType, string argName)[], string> BuildMethodArgument = x => string.Join(", ", x.Select(y => y.argType + " " + y.argName));
|
||||
Func<(string argType, string argName)[], string> BuildResultParameter = x => x.Length == 0 ? "AsyncUnit.Default" : "(" + string.Join(", ", x.Select(y => y.argName)) + ")";
|
||||
|
||||
Func<string, bool> IsParticleSystem = x => x == "ParticleUpdateJobScheduled";
|
||||
Func<string, bool> IsMouseTrigger = x => x.StartsWith("Mouse");
|
||||
Func<string, string> RequirePhysicsModule = x => (x.StartsWith("Collision") || x.StartsWith("Collider") || x.StartsWith("ControllerCollider") || x.StartsWith("Joint") || x.StartsWith("Trigger"))
|
||||
? (x.Contains("2D") ? "UNITASK_PHYSICS2D_SUPPORT" : "UNITASK_PHYSICS_SUPPORT")
|
||||
: null;
|
||||
Func<string, bool> IsUguiSystem = x => x != null;
|
||||
#>
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT
|
||||
using UnityEngine.EventSystems;
|
||||
#endif
|
||||
|
||||
namespace Cysharp.Threading.Tasks.Triggers
|
||||
{
|
||||
<# foreach(var t in triggers) { #>
|
||||
#region <#= t.triggerName #>
|
||||
<# if(IsUguiSystem(t.handlerInterface)) { #>
|
||||
#if !UNITY_2019_1_OR_NEWER || UNITASK_UGUI_SUPPORT
|
||||
<# } #>
|
||||
<# if(IsParticleSystem(t.triggerName)) { #>
|
||||
#if UNITY_2019_3_OR_NEWER && (!UNITY_2019_1_OR_NEWER || UNITASK_PARTICLESYSTEM_SUPPORT)
|
||||
<# } #>
|
||||
<# if(IsMouseTrigger(t.triggerName)) { #>
|
||||
#if !(UNITY_IPHONE || UNITY_ANDROID || UNITY_METRO)
|
||||
<# } #>
|
||||
<# if(RequirePhysicsModule(t.triggerName) != null) { #>
|
||||
#if !UNITY_2019_1_OR_NEWER || <#= RequirePhysicsModule(t.triggerName) #>
|
||||
<# } #>
|
||||
|
||||
public interface <#= ToInterfaceName(t.methodName) #>
|
||||
{
|
||||
<#= ToUniTaskName(t.returnType) #> <#= t.methodName #>Async();
|
||||
}
|
||||
|
||||
public partial class AsyncTriggerHandler<T> : <#= ToInterfaceName(t.methodName) #>
|
||||
{
|
||||
<#= ToUniTaskName(t.returnType) #> <#= ToInterfaceName(t.methodName) #>.<#= t.methodName #>Async()
|
||||
{
|
||||
core.Reset();
|
||||
return new <#= ToUniTaskName(t.returnType) #>((<#= ToCastUniTasSourceType(t.returnType) #>)(object)this, core.Version);
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class AsyncTriggerExtensions
|
||||
{
|
||||
public static Async<#= t.triggerName #>Trigger GetAsync<#= t.triggerName #>Trigger(this GameObject gameObject)
|
||||
{
|
||||
return GetOrAddComponent<Async<#= t.triggerName #>Trigger>(gameObject);
|
||||
}
|
||||
|
||||
public static Async<#= t.triggerName #>Trigger GetAsync<#= t.triggerName #>Trigger(this Component component)
|
||||
{
|
||||
return component.gameObject.GetAsync<#= t.triggerName #>Trigger();
|
||||
}
|
||||
}
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class Async<#= t.triggerName #>Trigger : AsyncTriggerBase<<#= t.returnType #>><#= (t.handlerInterface == null) ? "" : $", {t.handlerInterface}" #>
|
||||
{
|
||||
void <#= (t.handlerInterface == null) ? "" : $"{t.handlerInterface}." #><#= t.methodName #>(<#= BuildMethodArgument(t.arguments) #>)
|
||||
{
|
||||
RaiseEvent(<#= BuildResultParameter(t.arguments) #>);
|
||||
}
|
||||
|
||||
public <#= ToInterfaceName(t.methodName) #> Get<#= t.methodName #>AsyncHandler()
|
||||
{
|
||||
return new AsyncTriggerHandler<<#= t.returnType #>>(this, false);
|
||||
}
|
||||
|
||||
public <#= ToInterfaceName(t.methodName) #> Get<#= t.methodName #>AsyncHandler(CancellationToken cancellationToken)
|
||||
{
|
||||
return new AsyncTriggerHandler<<#= t.returnType #>>(this, cancellationToken, false);
|
||||
}
|
||||
|
||||
public <#= ToUniTaskName(t.returnType) #> <#= t.methodName #>Async()
|
||||
{
|
||||
return ((<#= ToInterfaceName(t.methodName) #>)new AsyncTriggerHandler<<#= t.returnType #>>(this, true)).<#= t.methodName #>Async();
|
||||
}
|
||||
|
||||
public <#= ToUniTaskName(t.returnType) #> <#= t.methodName #>Async(CancellationToken cancellationToken)
|
||||
{
|
||||
return ((<#= ToInterfaceName(t.methodName) #>)new AsyncTriggerHandler<<#= t.returnType #>>(this, cancellationToken, true)).<#= t.methodName #>Async();
|
||||
}
|
||||
}
|
||||
<# if(IsUguiSystem(t.handlerInterface)) { #>
|
||||
#endif
|
||||
<# } #>
|
||||
<# if(RequirePhysicsModule(t.triggerName) != null) { #>
|
||||
#endif
|
||||
<# } #>
|
||||
<# if(IsParticleSystem(t.triggerName) || IsMouseTrigger(t.triggerName)) { #>
|
||||
#endif
|
||||
<# } #>
|
||||
#endregion
|
||||
|
||||
<# } #>
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ca26d0cd9373354c8cd147490f32c8e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -33,14 +33,14 @@ namespace Cysharp.Threading.Tasks
|
||||
return new YieldAwaitable(timing);
|
||||
}
|
||||
|
||||
public static UniTask Yield(CancellationToken cancellationToken)
|
||||
public static UniTask Yield(CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(YieldPromise.Create(PlayerLoopTiming.Update, cancellationToken, out var token), token);
|
||||
return new UniTask(YieldPromise.Create(PlayerLoopTiming.Update, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken)
|
||||
public static UniTask Yield(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(YieldPromise.Create(timing, cancellationToken, out var token), token);
|
||||
return new UniTask(YieldPromise.Create(timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -48,7 +48,7 @@ namespace Cysharp.Threading.Tasks
|
||||
/// </summary>
|
||||
public static UniTask NextFrame()
|
||||
{
|
||||
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, CancellationToken.None, out var token), token);
|
||||
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, CancellationToken.None, false, out var token), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,23 +56,23 @@ namespace Cysharp.Threading.Tasks
|
||||
/// </summary>
|
||||
public static UniTask NextFrame(PlayerLoopTiming timing)
|
||||
{
|
||||
return new UniTask(NextFramePromise.Create(timing, CancellationToken.None, out var token), token);
|
||||
return new UniTask(NextFramePromise.Create(timing, CancellationToken.None, false, out var token), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similar as UniTask.Yield but guaranteed run on next frame.
|
||||
/// </summary>
|
||||
public static UniTask NextFrame(CancellationToken cancellationToken)
|
||||
public static UniTask NextFrame(CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, cancellationToken, out var token), token);
|
||||
return new UniTask(NextFramePromise.Create(PlayerLoopTiming.Update, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Similar as UniTask.Yield but guaranteed run on next frame.
|
||||
/// </summary>
|
||||
public static UniTask NextFrame(PlayerLoopTiming timing, CancellationToken cancellationToken)
|
||||
public static UniTask NextFrame(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(NextFramePromise.Create(timing, cancellationToken, out var token), token);
|
||||
return new UniTask(NextFramePromise.Create(timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
@@ -88,15 +88,21 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
[Obsolete("Use WaitForEndOfFrame(MonoBehaviour) instead or UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate). Equivalent for coroutine's WaitForEndOfFrame requires MonoBehaviour(runner of Coroutine).")]
|
||||
public static UniTask WaitForEndOfFrame(CancellationToken cancellationToken)
|
||||
public static UniTask WaitForEndOfFrame(CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken);
|
||||
return UniTask.Yield(PlayerLoopTiming.LastPostLateUpdate, cancellationToken, cancelImmediately);
|
||||
}
|
||||
#endif
|
||||
|
||||
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken = default)
|
||||
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner)
|
||||
{
|
||||
var source = WaitForEndOfFramePromise.Create(coroutineRunner, cancellationToken, out var token);
|
||||
var source = WaitForEndOfFramePromise.Create(coroutineRunner, CancellationToken.None, false, out var token);
|
||||
return new UniTask(source, token);
|
||||
}
|
||||
|
||||
public static UniTask WaitForEndOfFrame(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
var source = WaitForEndOfFramePromise.Create(coroutineRunner, cancellationToken, cancelImmediately, out var token);
|
||||
return new UniTask(source, token);
|
||||
}
|
||||
|
||||
@@ -113,50 +119,50 @@ namespace Cysharp.Threading.Tasks
|
||||
/// <summary>
|
||||
/// Same as UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken).
|
||||
/// </summary>
|
||||
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken)
|
||||
public static UniTask WaitForFixedUpdate(CancellationToken cancellationToken, bool cancelImmediately = false)
|
||||
{
|
||||
return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken);
|
||||
return UniTask.Yield(PlayerLoopTiming.LastFixedUpdate, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask WaitForSeconds(float duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask WaitForSeconds(float duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
return Delay(Mathf.RoundToInt(1000 * duration), ignoreTimeScale, delayTiming, cancellationToken);
|
||||
return Delay(Mathf.RoundToInt(1000 * duration), ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask WaitForSeconds(int duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask WaitForSeconds(int duration, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
return Delay(1000 * duration, ignoreTimeScale, delayTiming, cancellationToken);
|
||||
return Delay(1000 * duration, ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask DelayFrame(int delayFrameCount, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
if (delayFrameCount < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Delay does not allow minus delayFrameCount. delayFrameCount:" + delayFrameCount);
|
||||
}
|
||||
|
||||
return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, out var token), token);
|
||||
return new UniTask(DelayFramePromise.Create(delayFrameCount, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask Delay(int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
|
||||
return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken);
|
||||
return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask Delay(TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
var delayType = ignoreTimeScale ? DelayType.UnscaledDeltaTime : DelayType.DeltaTime;
|
||||
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken);
|
||||
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
|
||||
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken);
|
||||
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken, cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask Delay(TimeSpan delayTimeSpan, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask Delay(TimeSpan delayTimeSpan, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
if (delayTimeSpan < TimeSpan.Zero)
|
||||
{
|
||||
@@ -175,16 +181,16 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
case DelayType.UnscaledDeltaTime:
|
||||
{
|
||||
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
|
||||
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
case DelayType.Realtime:
|
||||
{
|
||||
return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
|
||||
return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
case DelayType.DeltaTime:
|
||||
default:
|
||||
{
|
||||
return new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
|
||||
return new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,13 +207,14 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
YieldPromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -219,8 +226,16 @@ namespace Cysharp.Threading.Tasks
|
||||
result = new YieldPromise();
|
||||
}
|
||||
|
||||
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (YieldPromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -274,6 +289,7 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -290,14 +306,15 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
int frameCount;
|
||||
CancellationToken cancellationToken;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
NextFramePromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -312,6 +329,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.frameCount = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (NextFramePromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -369,6 +395,7 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -384,14 +411,15 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskPool.RegisterSizeGetter(typeof(WaitForEndOfFramePromise), () => pool.Size);
|
||||
}
|
||||
|
||||
CancellationToken cancellationToken;
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
WaitForEndOfFramePromise()
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(MonoBehaviour coroutineRunner, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -405,6 +433,15 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitForEndOfFramePromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
coroutineRunner.StartCoroutine(result);
|
||||
@@ -446,6 +483,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
Reset(); // Reset Enumerator
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
@@ -494,6 +532,7 @@ namespace Cysharp.Threading.Tasks
|
||||
int initialFrame;
|
||||
int delayFrameCount;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
int currentFrameCount;
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
@@ -502,7 +541,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(int delayFrameCount, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -518,6 +557,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (DelayFramePromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -604,6 +652,7 @@ namespace Cysharp.Threading.Tasks
|
||||
currentFrameCount = default;
|
||||
delayFrameCount = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -623,6 +672,7 @@ namespace Cysharp.Threading.Tasks
|
||||
float delayTimeSpan;
|
||||
float elapsed;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -630,7 +680,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -647,6 +697,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (DelayPromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -715,6 +774,7 @@ namespace Cysharp.Threading.Tasks
|
||||
delayTimeSpan = default;
|
||||
elapsed = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -734,6 +794,7 @@ namespace Cysharp.Threading.Tasks
|
||||
float elapsed;
|
||||
int initialFrame;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -741,7 +802,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(TimeSpan delayFrameTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -758,6 +819,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.initialFrame = PlayerLoopHelper.IsMainThread ? Time.frameCount : -1;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (DelayIgnoreTimeScalePromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -826,6 +896,7 @@ namespace Cysharp.Threading.Tasks
|
||||
delayFrameTimeSpan = default;
|
||||
elapsed = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -844,6 +915,7 @@ namespace Cysharp.Threading.Tasks
|
||||
long delayTimeSpanTicks;
|
||||
ValueStopwatch stopwatch;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
@@ -851,7 +923,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(TimeSpan delayTimeSpan, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -867,6 +939,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.delayTimeSpanTicks = delayTimeSpan.Ticks;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (DelayRealtimePromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -931,6 +1012,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
stopwatch = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
@@ -9,30 +9,30 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public partial struct UniTask
|
||||
{
|
||||
public static UniTask WaitUntil(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask WaitUntil(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, out var token), token);
|
||||
return new UniTask(WaitUntilPromise.Create(predicate, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask WaitWhile(Func<bool> predicate, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
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, out var token), token);
|
||||
return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
||||
public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update, bool completeImmediately = false)
|
||||
{
|
||||
return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, out var token), token);
|
||||
return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, completeImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public static UniTask<U> WaitUntilValueChanged<T, U>(T target, Func<T, U> monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<U> equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<U> WaitUntilValueChanged<T, U>(T target, Func<T, U> monitorFunction, PlayerLoopTiming monitorTiming = PlayerLoopTiming.Update, IEqualityComparer<U> equalityComparer = null, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
where T : class
|
||||
{
|
||||
var unityObject = target as UnityEngine.Object;
|
||||
var isUnityObject = target is UnityEngine.Object; // don't use (unityObject == null)
|
||||
|
||||
return new UniTask<U>(isUnityObject
|
||||
? WaitUntilValueChangedUnityObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out var token)
|
||||
: WaitUntilValueChangedStandardObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, out token), token);
|
||||
? WaitUntilValueChangedUnityObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, cancelImmediately, out var token)
|
||||
: WaitUntilValueChangedStandardObjectPromise<T, U>.Create(target, monitorFunction, equalityComparer, monitorTiming, cancellationToken, cancelImmediately, out token), token);
|
||||
}
|
||||
|
||||
sealed class WaitUntilPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<WaitUntilPromise>
|
||||
@@ -48,6 +48,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
Func<bool> predicate;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -55,7 +56,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -70,6 +71,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.predicate = predicate;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitUntilPromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -136,6 +146,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
predicate = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -153,6 +164,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
Func<bool> predicate;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -160,7 +172,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(Func<bool> predicate, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -174,6 +186,15 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.predicate = predicate;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitWhilePromise)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -241,6 +262,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
predicate = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -257,6 +279,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<object> core;
|
||||
|
||||
@@ -264,7 +287,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, out short token)
|
||||
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, bool completeImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -278,6 +301,15 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (completeImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitUntilCanceledPromise)state;
|
||||
promise.core.TrySetResult(null);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
@@ -329,6 +361,7 @@ namespace Cysharp.Threading.Tasks
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -351,6 +384,7 @@ namespace Cysharp.Threading.Tasks
|
||||
Func<T, U> monitorFunction;
|
||||
IEqualityComparer<U> equalityComparer;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<U> core;
|
||||
|
||||
@@ -358,7 +392,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -376,6 +410,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.currentValue = monitorFunction(target);
|
||||
result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault<U>();
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitUntilValueChangedUnityObjectPromise<T, U>)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -453,6 +496,7 @@ namespace Cysharp.Threading.Tasks
|
||||
monitorFunction = default;
|
||||
equalityComparer = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
@@ -474,6 +518,7 @@ namespace Cysharp.Threading.Tasks
|
||||
Func<T, U> monitorFunction;
|
||||
IEqualityComparer<U> equalityComparer;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<U> core;
|
||||
|
||||
@@ -481,7 +526,7 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
}
|
||||
|
||||
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<U> Create(T target, Func<T, U> monitorFunction, IEqualityComparer<U> equalityComparer, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -498,6 +543,15 @@ namespace Cysharp.Threading.Tasks
|
||||
result.currentValue = monitorFunction(target);
|
||||
result.equalityComparer = equalityComparer ?? UnityEqualityComparer.GetDefault<U>();
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (WaitUntilValueChangedStandardObjectPromise<T, U>)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -575,6 +629,7 @@ namespace Cysharp.Threading.Tasks
|
||||
monitorFunction = default;
|
||||
equalityComparer = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,122 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public partial struct UniTask
|
||||
{
|
||||
<# for(var i = 2; i <= 15; i++ ) {
|
||||
var range = Enumerable.Range(1, i);
|
||||
var t = string.Join(", ", range.Select(x => "T" + x));
|
||||
var args = string.Join(", ", range.Select(x => $"UniTask<T{x}> task{x}"));
|
||||
var targs = string.Join(", ", range.Select(x => $"task{x}"));
|
||||
var tresult = string.Join(", ", range.Select(x => $"task{x}.GetAwaiter().GetResult()"));
|
||||
var completedSuccessfullyAnd = string.Join(" && ", range.Select(x => $"task{x}.Status.IsCompletedSuccessfully()"));
|
||||
var tfield = string.Join(", ", range.Select(x => $"self.t{x}"));
|
||||
#>
|
||||
|
||||
public static UniTask<(<#= t #>)> WhenAll<<#= t #>>(<#= args #>)
|
||||
{
|
||||
if (<#= completedSuccessfullyAnd #>)
|
||||
{
|
||||
return new UniTask<(<#= t #>)>((<#= tresult #>));
|
||||
}
|
||||
|
||||
return new UniTask<(<#= t #>)>(new WhenAllPromise<<#= t #>>(<#= targs #>), 0);
|
||||
}
|
||||
|
||||
sealed class WhenAllPromise<<#= t #>> : IUniTaskSource<(<#= t #>)>
|
||||
{
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
T<#= j #> t<#= j #> = default;
|
||||
<# } #>
|
||||
int completedCount;
|
||||
UniTaskCompletionSourceCore<(<#= t #>)> core;
|
||||
|
||||
public WhenAllPromise(<#= args #>)
|
||||
{
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
|
||||
this.completedCount = 0;
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
{
|
||||
var awaiter = task<#= j #>.GetAwaiter();
|
||||
if (awaiter.IsCompleted)
|
||||
{
|
||||
TryInvokeContinuationT<#= j #>(this, awaiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
awaiter.SourceOnCompleted(state =>
|
||||
{
|
||||
using (var t = (StateTuple<WhenAllPromise<<#= t #>>, UniTask<T<#= j #>>.Awaiter>)state)
|
||||
{
|
||||
TryInvokeContinuationT<#= j #>(t.Item1, t.Item2);
|
||||
}
|
||||
}, StateTuple.Create(this, awaiter));
|
||||
}
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
static void TryInvokeContinuationT<#= j #>(WhenAllPromise<<#= t #>> self, in UniTask<T<#= j #>>.Awaiter awaiter)
|
||||
{
|
||||
try
|
||||
{
|
||||
self.t<#= j #> = awaiter.GetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.core.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Interlocked.Increment(ref self.completedCount) == <#= i #>)
|
||||
{
|
||||
self.core.TrySetResult((<#= tfield #>));
|
||||
}
|
||||
}
|
||||
|
||||
<# } #>
|
||||
|
||||
public (<#= t #>) GetResult(short token)
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
GC.SuppressFinalize(this);
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c2ecfd98ee1b9a4c9fae1b398c32d75
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,117 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.ExceptionServices;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public partial struct UniTask
|
||||
{
|
||||
<# for(var i = 2; i <= 15; i++ ) {
|
||||
var range = Enumerable.Range(1, i);
|
||||
var t = string.Join(", ", range.Select(x => "T" + x));
|
||||
var args = string.Join(", ", range.Select(x => $"UniTask<T{x}> task{x}"));
|
||||
var targs = string.Join(", ", range.Select(x => $"task{x}"));
|
||||
var tresult = string.Join(", ", range.Select(x => $"task{x}.GetAwaiter().GetResult()"));
|
||||
var tBool = string.Join(", ", range.Select(x => $"T{x} result{x}"));
|
||||
var tfield = string.Join(", ", range.Select(x => $"self.t{x}"));
|
||||
Func<int, string> getResult = j => string.Join(", ", range.Select(x => (x == j) ? "result" : "default"));
|
||||
#>
|
||||
public static UniTask<(int winArgumentIndex, <#= tBool #>)> WhenAny<<#= t #>>(<#= args #>)
|
||||
{
|
||||
return new UniTask<(int winArgumentIndex, <#= tBool #>)>(new WhenAnyPromise<<#= t #>>(<#= targs #>), 0);
|
||||
}
|
||||
|
||||
sealed class WhenAnyPromise<<#= t #>> : IUniTaskSource<(int, <#= tBool #>)>
|
||||
{
|
||||
int completedCount;
|
||||
UniTaskCompletionSourceCore<(int, <#= tBool #>)> core;
|
||||
|
||||
public WhenAnyPromise(<#= args #>)
|
||||
{
|
||||
TaskTracker.TrackActiveTask(this, 3);
|
||||
|
||||
this.completedCount = 0;
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
{
|
||||
var awaiter = task<#= j #>.GetAwaiter();
|
||||
|
||||
if (awaiter.IsCompleted)
|
||||
{
|
||||
TryInvokeContinuationT<#= j #>(this, awaiter);
|
||||
}
|
||||
else
|
||||
{
|
||||
awaiter.SourceOnCompleted(state =>
|
||||
{
|
||||
using (var t = (StateTuple<WhenAnyPromise<<#= t #>>, UniTask<T<#= j #>>.Awaiter>)state)
|
||||
{
|
||||
TryInvokeContinuationT<#= j #>(t.Item1, t.Item2);
|
||||
}
|
||||
}, StateTuple.Create(this, awaiter));
|
||||
}
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
|
||||
<# for(var j = 1; j <= i; j++) { #>
|
||||
static void TryInvokeContinuationT<#= j #>(WhenAnyPromise<<#= t #>> self, in UniTask<T<#= j #>>.Awaiter awaiter)
|
||||
{
|
||||
T<#= j #> result;
|
||||
try
|
||||
{
|
||||
result = awaiter.GetResult();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
self.core.TrySetException(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Interlocked.Increment(ref self.completedCount) == 1)
|
||||
{
|
||||
self.core.TrySetResult((<#= j - 1 #>, <#= getResult(j) #>));
|
||||
}
|
||||
}
|
||||
|
||||
<# } #>
|
||||
|
||||
public (int, <#= tBool #>) GetResult(short token)
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
GC.SuppressFinalize(this);
|
||||
return core.GetResult(token);
|
||||
}
|
||||
|
||||
public UniTaskStatus GetStatus(short token)
|
||||
{
|
||||
return core.GetStatus(token);
|
||||
}
|
||||
|
||||
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||
{
|
||||
core.OnCompleted(continuation, state, token);
|
||||
}
|
||||
|
||||
public UniTaskStatus UnsafeGetStatus()
|
||||
{
|
||||
return core.UnsafeGetStatus();
|
||||
}
|
||||
|
||||
void IUniTaskSource.GetResult(short token)
|
||||
{
|
||||
GetResult(token);
|
||||
}
|
||||
}
|
||||
|
||||
<# } #>
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71c2c0bce7543454c8ef545083e18170
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,7 +1,9 @@
|
||||
{
|
||||
"name": "UniTask",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"references": [
|
||||
"GUID:e34a5702dd353724aa315fb8011f08c3"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
|
@@ -0,0 +1,63 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static partial class UniTaskExtensions
|
||||
{
|
||||
// shorthand of WhenAll
|
||||
|
||||
public static UniTask.Awaiter GetAwaiter(this UniTask[] tasks)
|
||||
{
|
||||
return UniTask.WhenAll(tasks).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask.Awaiter GetAwaiter(this IEnumerable<UniTask> tasks)
|
||||
{
|
||||
return UniTask.WhenAll(tasks).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask<T[]>.Awaiter GetAwaiter<T>(this UniTask<T>[] tasks)
|
||||
{
|
||||
return UniTask.WhenAll(tasks).GetAwaiter();
|
||||
}
|
||||
|
||||
public static UniTask<T[]>.Awaiter GetAwaiter<T>(this IEnumerable<UniTask<T>> tasks)
|
||||
{
|
||||
return UniTask.WhenAll(tasks).GetAwaiter();
|
||||
}
|
||||
|
||||
<# for(var i = 2; i <= 15; i++ ) {
|
||||
var range = Enumerable.Range(1, i);
|
||||
var t = string.Join(", ", range.Select(x => "T" + x));
|
||||
var args = string.Join(", ", range.Select(x => $"UniTask<T{x}> task{x}"));
|
||||
var titems = string.Join(", ", range.Select(x => $"tasks.Item{x}"));
|
||||
#>
|
||||
public static UniTask<(<#= t #>)>.Awaiter GetAwaiter<<#= t #>>(this (<#= args #>) tasks)
|
||||
{
|
||||
return UniTask.WhenAll(<#= titems #>).GetAwaiter();
|
||||
}
|
||||
|
||||
<# } #>
|
||||
|
||||
<# for(var i = 2; i <= 15; i++ ) {
|
||||
var range = Enumerable.Range(1, i);
|
||||
var args = string.Join(", ", range.Select(x => $"UniTask task{x}"));
|
||||
var titems = string.Join(", ", range.Select(x => $"tasks.Item{x}"));
|
||||
#>
|
||||
|
||||
public static UniTask.Awaiter GetAwaiter(this (<#= args #>) tasks)
|
||||
{
|
||||
return UniTask.WhenAll(<#= titems #>).GetAwaiter();
|
||||
}
|
||||
|
||||
<# } #>
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a75b5d7e55a5a34fb6476586df37c72
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -24,12 +24,17 @@ namespace Cysharp.Threading.Tasks
|
||||
return AwaitForAllAssets(asyncOperation, null, PlayerLoopTiming.Update, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return AwaitForAllAssets(asyncOperation, progress: null, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object[]> AwaitForAllAssets(this AssetBundleRequest 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.allAssets);
|
||||
return new UniTask<UnityEngine.Object[]>(AssetBundleRequestAllAssetsConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityEngine.Object[]>(AssetBundleRequestAllAssetsConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct AssetBundleRequestAllAssetsAwaiter : ICriticalNotifyCompletion
|
||||
@@ -95,15 +100,19 @@ namespace Cysharp.Threading.Tasks
|
||||
AssetBundleRequest asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object[]> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
AssetBundleRequestAllAssetsConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityEngine.Object[]> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<UnityEngine.Object[]> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -118,6 +127,18 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (AssetBundleRequestAllAssetsConfiguredSource)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -161,6 +182,12 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
@@ -188,8 +215,29 @@ namespace Cysharp.Threading.Tasks
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.allAssets);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,12 +20,17 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<AsyncGPUReadbackRequest> ToUniTask(this AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<AsyncGPUReadbackRequest> WithCancellation(this AsyncGPUReadbackRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
if (asyncOperation.done) return UniTask.FromResult(asyncOperation);
|
||||
return new UniTask<AsyncGPUReadbackRequest>(AsyncGPUReadbackRequestAwaiterConfiguredSource.Create(asyncOperation, timing, cancellationToken, out var token), token);
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<AsyncGPUReadbackRequest> ToUniTask(this AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken), bool cancelImmediately = false)
|
||||
{
|
||||
if (asyncOperation.done) return UniTask.FromResult(asyncOperation);
|
||||
return new UniTask<AsyncGPUReadbackRequest>(AsyncGPUReadbackRequestAwaiterConfiguredSource.Create(asyncOperation, timing, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
sealed class AsyncGPUReadbackRequestAwaiterConfiguredSource : IUniTaskSource<AsyncGPUReadbackRequest>, IPlayerLoopItem, ITaskPoolNode<AsyncGPUReadbackRequestAwaiterConfiguredSource>
|
||||
{
|
||||
static TaskPool<AsyncGPUReadbackRequestAwaiterConfiguredSource> pool;
|
||||
@@ -39,15 +44,15 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
AsyncGPUReadbackRequest asyncOperation;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncGPUReadbackRequest> core;
|
||||
|
||||
AsyncGPUReadbackRequestAwaiterConfiguredSource()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static IUniTaskSource<AsyncGPUReadbackRequest> Create(AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<AsyncGPUReadbackRequest> Create(AsyncGPUReadbackRequest asyncOperation, PlayerLoopTiming timing, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -61,6 +66,15 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.cancellationToken = cancellationToken;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var promise = (AsyncGPUReadbackRequestAwaiterConfiguredSource)state;
|
||||
promise.core.TrySetCanceled(promise.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -131,6 +145,7 @@ namespace Cysharp.Threading.Tasks
|
||||
core.Reset();
|
||||
asyncOperation = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
#if !UNITY_2023_1_OR_NEWER
|
||||
// from Unity2023.1.0a15, AsyncOperationAwaitableExtensions.GetAwaiter is defined in UnityEngine.
|
||||
|
||||
public static AsyncOperationAwaiter GetAwaiter(this AsyncOperation asyncOperation)
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
@@ -30,12 +29,17 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask WithCancellation(this AsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask ToUniTask(this AsyncOperation 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(cancellationToken);
|
||||
if (asyncOperation.isDone) return UniTask.CompletedTask;
|
||||
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask(AsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct AsyncOperationAwaiter : ICriticalNotifyCompletion
|
||||
@@ -92,15 +96,19 @@ namespace Cysharp.Threading.Tasks
|
||||
AsyncOperation asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AsyncUnit> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
AsyncOperationConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource Create(AsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -115,6 +123,18 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (AsyncOperationConfiguredSource)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -154,6 +174,12 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
@@ -178,11 +204,33 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(AsyncUnit.Default);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -200,12 +248,17 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<UnityEngine.Object> WithCancellation(this ResourceRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object> ToUniTask(this ResourceRequest 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.asset);
|
||||
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityEngine.Object>(ResourceRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct ResourceRequestAwaiter : ICriticalNotifyCompletion
|
||||
@@ -266,15 +319,19 @@ namespace Cysharp.Threading.Tasks
|
||||
ResourceRequest asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
ResourceRequestConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<UnityEngine.Object> Create(ResourceRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -289,6 +346,18 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (ResourceRequestConfiguredSource)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -332,6 +401,12 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
@@ -356,11 +431,33 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -379,12 +476,17 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<UnityEngine.Object> WithCancellation(this AssetBundleRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<UnityEngine.Object> ToUniTask(this AssetBundleRequest 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.asset);
|
||||
return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityEngine.Object>(AssetBundleRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct AssetBundleRequestAwaiter : ICriticalNotifyCompletion
|
||||
@@ -445,15 +547,19 @@ namespace Cysharp.Threading.Tasks
|
||||
AssetBundleRequest asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityEngine.Object> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
AssetBundleRequestConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<UnityEngine.Object> Create(AssetBundleRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -468,6 +574,18 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (AssetBundleRequestConfiguredSource)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -511,6 +629,12 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
@@ -535,11 +659,33 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -559,12 +705,17 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<AssetBundle> WithCancellation(this AssetBundleCreateRequest asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<AssetBundle> ToUniTask(this AssetBundleCreateRequest 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<AssetBundle>(cancellationToken);
|
||||
if (asyncOperation.isDone) return UniTask.FromResult(asyncOperation.assetBundle);
|
||||
return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask<AssetBundle>(AssetBundleCreateRequestConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct AssetBundleCreateRequestAwaiter : ICriticalNotifyCompletion
|
||||
@@ -625,15 +776,19 @@ namespace Cysharp.Threading.Tasks
|
||||
AssetBundleCreateRequest asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<AssetBundle> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
AssetBundleCreateRequestConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<AssetBundle> Create(AssetBundleCreateRequest asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -648,6 +803,18 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (AssetBundleCreateRequestConfiguredSource)state;
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -691,6 +858,12 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
@@ -715,11 +888,33 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
else
|
||||
{
|
||||
completed = true;
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.assetBundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -739,7 +934,12 @@ namespace Cysharp.Threading.Tasks
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation asyncOperation, IProgress<float> progress = null, PlayerLoopTiming timing = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public static UniTask<UnityWebRequest> WithCancellation(this UnityWebRequestAsyncOperation asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static UniTask<UnityWebRequest> ToUniTask(this UnityWebRequestAsyncOperation 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<UnityWebRequest>(cancellationToken);
|
||||
@@ -751,7 +951,7 @@ namespace Cysharp.Threading.Tasks
|
||||
}
|
||||
return UniTask.FromResult(asyncOperation.webRequest);
|
||||
}
|
||||
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, out var token), token);
|
||||
return new UniTask<UnityWebRequest>(UnityWebRequestAsyncOperationConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct UnityWebRequestAsyncOperationAwaiter : ICriticalNotifyCompletion
|
||||
@@ -820,15 +1020,19 @@ namespace Cysharp.Threading.Tasks
|
||||
UnityWebRequestAsyncOperation asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<UnityWebRequest> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
UnityWebRequestAsyncOperationConfiguredSource()
|
||||
{
|
||||
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, out short token)
|
||||
public static IUniTaskSource<UnityWebRequest> Create(UnityWebRequestAsyncOperation asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
@@ -843,6 +1047,19 @@ namespace Cysharp.Threading.Tasks
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (UnityWebRequestAsyncOperationConfiguredSource)state;
|
||||
source.asyncOperation.webRequest.Abort();
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
@@ -886,6 +1103,12 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// Already completed
|
||||
if (completed || asyncOperation == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
asyncOperation.webRequest.Abort();
|
||||
@@ -900,11 +1123,7 @@ namespace Cysharp.Threading.Tasks
|
||||
|
||||
if (asyncOperation.isDone)
|
||||
{
|
||||
if (asyncOperation.webRequest == null)
|
||||
{
|
||||
core.TrySetException(new ObjectDisposedException("The webRequest has been destroyed."));
|
||||
}
|
||||
else if (asyncOperation.webRequest.IsError())
|
||||
if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
@@ -922,11 +1141,37 @@ namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
349
UnityProject/Packages/UniTask/Runtime/UnityAsyncExtensions.tt
Normal file
349
UnityProject/Packages/UniTask/Runtime/UnityAsyncExtensions.tt
Normal file
@@ -0,0 +1,349 @@
|
||||
<#@ template debug="false" hostspecific="false" language="C#" #>
|
||||
<#@ assembly name="System.Core" #>
|
||||
<#@ import namespace="System.Linq" #>
|
||||
<#@ import namespace="System.Text" #>
|
||||
<#@ import namespace="System.Collections.Generic" #>
|
||||
<#@ output extension=".cs" #>
|
||||
<#
|
||||
var types = new (string typeName, string returnType, string returnField)[]
|
||||
{
|
||||
("AsyncOperation", "void", null),
|
||||
("ResourceRequest", "UnityEngine.Object", "asset"),
|
||||
("AssetBundleRequest", "UnityEngine.Object", "asset"), // allAssets?
|
||||
("AssetBundleCreateRequest", "AssetBundle", "assetBundle"),
|
||||
("UnityWebRequestAsyncOperation", "UnityWebRequest", "webRequest") // -> #if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
|
||||
};
|
||||
|
||||
Func<string, string> ToUniTaskReturnType = x => (x == "void") ? "UniTask" : $"UniTask<{x}>";
|
||||
Func<string, string> ToIUniTaskSourceReturnType = x => (x == "void") ? "IUniTaskSource" : $"IUniTaskSource<{x}>";
|
||||
Func<(string typeName, string returnType, string returnField), bool> IsAsyncOperationBase = x => x.typeName == "AsyncOperation";
|
||||
Func<(string typeName, string returnType, string returnField), bool> IsUnityWebRequest = x => x.returnType == "UnityWebRequest";
|
||||
Func<(string typeName, string returnType, string returnField), bool> IsAssetBundleModule = x => x.typeName == "AssetBundleRequest" || x.typeName == "AssetBundleCreateRequest";
|
||||
Func<(string typeName, string returnType, string returnField), bool> IsVoid = x => x.returnType == "void";
|
||||
#>
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using Cysharp.Threading.Tasks.Internal;
|
||||
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
|
||||
using UnityEngine.Networking;
|
||||
#endif
|
||||
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static partial class UnityAsyncExtensions
|
||||
{
|
||||
<# foreach(var t in types) { #>
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
#if ENABLE_UNITYWEBREQUEST && (!UNITY_2019_1_OR_NEWER || UNITASK_WEBREQUEST_SUPPORT)
|
||||
<# } else if(IsAssetBundleModule(t)) { #>
|
||||
#if UNITASK_ASSETBUNDLE_SUPPORT
|
||||
<# } #>
|
||||
#region <#= t.typeName #>
|
||||
|
||||
<# if (IsAsyncOperationBase(t)) { #>
|
||||
#if !UNITY_2023_1_OR_NEWER
|
||||
// from Unity2023.1.0a15, AsyncOperationAwaitableExtensions.GetAwaiter is defined in UnityEngine.
|
||||
<# } #>
|
||||
public static <#= t.typeName #>Awaiter GetAwaiter(this <#= t.typeName #> asyncOperation)
|
||||
{
|
||||
Error.ThrowArgumentNullException(asyncOperation, nameof(asyncOperation));
|
||||
return new <#= t.typeName #>Awaiter(asyncOperation);
|
||||
}
|
||||
<# if (IsAsyncOperationBase(t)) { #>
|
||||
#endif
|
||||
<# } #>
|
||||
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken);
|
||||
}
|
||||
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> WithCancellation(this <#= t.typeName #> asyncOperation, CancellationToken cancellationToken, bool cancelImmediately)
|
||||
{
|
||||
return ToUniTask(asyncOperation, cancellationToken: cancellationToken, cancelImmediately: cancelImmediately);
|
||||
}
|
||||
|
||||
public static <#= ToUniTaskReturnType(t.returnType) #> ToUniTask(this <#= t.typeName #> 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<#= IsVoid(t) ? "" : "<" + t.returnType + ">" #>(cancellationToken);
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
if (asyncOperation.isDone)
|
||||
{
|
||||
if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
return UniTask.FromException<UnityWebRequest>(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
return UniTask.FromResult(asyncOperation.webRequest);
|
||||
}
|
||||
<# } else { #>
|
||||
if (asyncOperation.isDone) return <#= IsVoid(t) ? "UniTask.CompletedTask" : $"UniTask.FromResult(asyncOperation.{t.returnField})" #>;
|
||||
<# } #>
|
||||
return new <#= ToUniTaskReturnType(t.returnType) #>(<#= t.typeName #>ConfiguredSource.Create(asyncOperation, timing, progress, cancellationToken, cancelImmediately, out var token), token);
|
||||
}
|
||||
|
||||
public struct <#= t.typeName #>Awaiter : ICriticalNotifyCompletion
|
||||
{
|
||||
<#= t.typeName #> asyncOperation;
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
public <#= t.typeName #>Awaiter(<#= t.typeName #> asyncOperation)
|
||||
{
|
||||
this.asyncOperation = asyncOperation;
|
||||
this.continuationAction = null;
|
||||
}
|
||||
|
||||
public bool IsCompleted => asyncOperation.isDone;
|
||||
|
||||
public <#= t.returnType #> GetResult()
|
||||
{
|
||||
if (continuationAction != null)
|
||||
{
|
||||
asyncOperation.completed -= continuationAction;
|
||||
continuationAction = null;
|
||||
<# if (!IsVoid(t)) { #>
|
||||
var result = <#= $"asyncOperation.{t.returnField}" #>;
|
||||
asyncOperation = null;
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
if (result.IsError())
|
||||
{
|
||||
throw new UnityWebRequestException(result);
|
||||
}
|
||||
<# } #>
|
||||
return result;
|
||||
<# } else { #>
|
||||
asyncOperation = null;
|
||||
<# } #>
|
||||
}
|
||||
else
|
||||
{
|
||||
<# if (!IsVoid(t)) { #>
|
||||
var result = <#= $"asyncOperation.{t.returnField}" #>;
|
||||
asyncOperation = null;
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
if (result.IsError())
|
||||
{
|
||||
throw new UnityWebRequestException(result);
|
||||
}
|
||||
<# } #>
|
||||
return result;
|
||||
<# } else { #>
|
||||
asyncOperation = null;
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
UnsafeOnCompleted(continuation);
|
||||
}
|
||||
|
||||
public void UnsafeOnCompleted(Action continuation)
|
||||
{
|
||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||
asyncOperation.completed += continuationAction;
|
||||
}
|
||||
}
|
||||
|
||||
sealed class <#= t.typeName #>ConfiguredSource : <#= ToIUniTaskSourceReturnType(t.returnType) #>, IPlayerLoopItem, ITaskPoolNode<<#= t.typeName #>ConfiguredSource>
|
||||
{
|
||||
static TaskPool<<#= t.typeName #>ConfiguredSource> pool;
|
||||
<#= t.typeName #>ConfiguredSource nextNode;
|
||||
public ref <#= t.typeName #>ConfiguredSource NextNode => ref nextNode;
|
||||
|
||||
static <#= t.typeName #>ConfiguredSource()
|
||||
{
|
||||
TaskPool.RegisterSizeGetter(typeof(<#= t.typeName #>ConfiguredSource), () => pool.Size);
|
||||
}
|
||||
|
||||
<#= t.typeName #> asyncOperation;
|
||||
IProgress<float> progress;
|
||||
CancellationToken cancellationToken;
|
||||
CancellationTokenRegistration cancellationTokenRegistration;
|
||||
bool completed;
|
||||
|
||||
UniTaskCompletionSourceCore<<#= IsVoid(t) ? "AsyncUnit" : t.returnType #>> core;
|
||||
|
||||
Action<AsyncOperation> continuationAction;
|
||||
|
||||
<#= t.typeName #>ConfiguredSource()
|
||||
{
|
||||
continuationAction = Continuation;
|
||||
}
|
||||
|
||||
public static <#= ToIUniTaskSourceReturnType(t.returnType) #> Create(<#= t.typeName #> asyncOperation, PlayerLoopTiming timing, IProgress<float> progress, CancellationToken cancellationToken, bool cancelImmediately, out short token)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
return AutoResetUniTaskCompletionSource<#= IsVoid(t) ? "" : $"<{t.returnType}>" #>.CreateFromCanceled(cancellationToken, out token);
|
||||
}
|
||||
|
||||
if (!pool.TryPop(out var result))
|
||||
{
|
||||
result = new <#= t.typeName #>ConfiguredSource();
|
||||
}
|
||||
|
||||
result.asyncOperation = asyncOperation;
|
||||
result.progress = progress;
|
||||
result.cancellationToken = cancellationToken;
|
||||
result.completed = false;
|
||||
|
||||
asyncOperation.completed += result.continuationAction;
|
||||
|
||||
if (cancelImmediately && cancellationToken.CanBeCanceled)
|
||||
{
|
||||
result.cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
|
||||
{
|
||||
var source = (<#= t.typeName #>ConfiguredSource)state;
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
source.asyncOperation.webRequest.Abort();
|
||||
<# } #>
|
||||
source.core.TrySetCanceled(source.cancellationToken);
|
||||
}, result);
|
||||
}
|
||||
|
||||
TaskTracker.TrackActiveTask(result, 3);
|
||||
|
||||
PlayerLoopHelper.AddAction(timing, result);
|
||||
|
||||
token = result.core.Version;
|
||||
return result;
|
||||
}
|
||||
|
||||
public <#= t.returnType #> GetResult(short token)
|
||||
{
|
||||
try
|
||||
{
|
||||
<# if (!IsVoid(t)) { #>
|
||||
return core.GetResult(token);
|
||||
<# } else { #>
|
||||
core.GetResult(token);
|
||||
<# } #>
|
||||
}
|
||||
finally
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
}
|
||||
|
||||
<# if (!IsVoid(t)) { #>
|
||||
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)
|
||||
{
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
asyncOperation.webRequest.Abort();
|
||||
<# } #>
|
||||
core.TrySetCanceled(cancellationToken);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (progress != null)
|
||||
{
|
||||
progress.Report(asyncOperation.progress);
|
||||
}
|
||||
|
||||
if (asyncOperation.isDone)
|
||||
{
|
||||
<# if(IsUnityWebRequest(t)) { #>
|
||||
if (asyncOperation.webRequest.IsError())
|
||||
{
|
||||
core.TrySetException(new UnityWebRequestException(asyncOperation.webRequest));
|
||||
}
|
||||
else
|
||||
{
|
||||
core.TrySetResult(asyncOperation.webRequest);
|
||||
}
|
||||
<# } else { #>
|
||||
core.TrySetResult(<#= IsVoid(t) ? "AsyncUnit.Default" : $"asyncOperation.{t.returnField}" #>);
|
||||
<# } #>
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryReturn()
|
||||
{
|
||||
TaskTracker.RemoveTracking(this);
|
||||
core.Reset();
|
||||
asyncOperation.completed -= continuationAction;
|
||||
asyncOperation = default;
|
||||
progress = default;
|
||||
cancellationToken = default;
|
||||
cancellationTokenRegistration.Dispose();
|
||||
return pool.TryPush(this);
|
||||
}
|
||||
|
||||
void Continuation(AsyncOperation _)
|
||||
{
|
||||
if (completed)
|
||||
{
|
||||
TryReturn();
|
||||
}
|
||||
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}" #>);
|
||||
}
|
||||
<# } #>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
<# if(IsUnityWebRequest(t) || IsAssetBundleModule(t)) { #>
|
||||
#endif
|
||||
<# } #>
|
||||
|
||||
<# } #>
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1053c85b3f0794488b10e6de53e9c02
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,17 @@
|
||||
#if UNITY_2023_1_OR_NEWER
|
||||
namespace Cysharp.Threading.Tasks
|
||||
{
|
||||
public static class UnityAwaitableExtensions
|
||||
{
|
||||
public static async UniTask AsUniTask(this UnityEngine.Awaitable awaitable)
|
||||
{
|
||||
await awaitable;
|
||||
}
|
||||
|
||||
public static async UniTask<T> AsUniTask<T>(this UnityEngine.Awaitable<T> awaitable)
|
||||
{
|
||||
return await awaitable;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c29533c9e4284dee914b71a6579ea274
|
||||
timeCreated: 1698895807
|
@@ -3,4 +3,5 @@
|
||||
[assembly: InternalsVisibleTo("UniTask.Linq")]
|
||||
[assembly: InternalsVisibleTo("UniTask.Addressables")]
|
||||
[assembly: InternalsVisibleTo("UniTask.DOTween")]
|
||||
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
||||
[assembly: InternalsVisibleTo("UniTask.TextMeshPro")]
|
||||
[assembly: InternalsVisibleTo("UniTask.YooAsset")]
|
@@ -2,7 +2,7 @@
|
||||
"name": "com.cysharp.unitask",
|
||||
"displayName": "UniTask",
|
||||
"author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" },
|
||||
"version": "2.4.0",
|
||||
"version": "2.5.0",
|
||||
"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