mirror of https://github.com/Cysharp/UniTask
Add UniTask.WaitUntilCanceled
parent
fb1152d8f4
commit
bbd5686816
|
@ -1,7 +1,4 @@
|
||||||
#if NET_4_6 || NET_STANDARD_2_0 || CSHARP_7_OR_LATER
|
using System;
|
||||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Cysharp.Threading.Tasks.Internal;
|
using Cysharp.Threading.Tasks.Internal;
|
||||||
|
|
||||||
|
@ -21,7 +18,11 @@ namespace Cysharp.Threading.Tasks
|
||||||
public static IProgress<T> CreateOnlyValueChanged<T>(Action<T> handler, IEqualityComparer<T> comparer = null)
|
public static IProgress<T> CreateOnlyValueChanged<T>(Action<T> handler, IEqualityComparer<T> comparer = null)
|
||||||
{
|
{
|
||||||
if (handler == null) return NullProgress<T>.Instance;
|
if (handler == null) return NullProgress<T>.Instance;
|
||||||
|
#if UNITY_2018_3_OR_NEWER
|
||||||
return new OnlyValueChangedProgress<T>(handler, comparer ?? UnityEqualityComparer.GetDefault<T>());
|
return new OnlyValueChangedProgress<T>(handler, comparer ?? UnityEqualityComparer.GetDefault<T>());
|
||||||
|
#else
|
||||||
|
return new OnlyValueChangedProgress<T>(handler, comparer ?? EqualityComparer<T>.Default);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class NullProgress<T> : IProgress<T>
|
sealed class NullProgress<T> : IProgress<T>
|
||||||
|
@ -83,6 +84,4 @@ namespace Cysharp.Threading.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
|
@ -19,6 +19,11 @@ namespace Cysharp.Threading.Tasks
|
||||||
return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, out var token), token);
|
return new UniTask(WaitWhilePromise.Create(predicate, timing, cancellationToken, out var token), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static UniTask WaitUntilCanceled(CancellationToken cancellationToken, PlayerLoopTiming timing = PlayerLoopTiming.Update)
|
||||||
|
{
|
||||||
|
return new UniTask(WaitUntilCanceledPromise.Create(cancellationToken, timing, 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))
|
||||||
where T : class
|
where T : class
|
||||||
{
|
{
|
||||||
|
@ -234,6 +239,91 @@ namespace Cysharp.Threading.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class WaitUntilCanceledPromise : IUniTaskSource, IPlayerLoopItem, IPromisePoolItem
|
||||||
|
{
|
||||||
|
static readonly PromisePool<WaitUntilCanceledPromise> pool = new PromisePool<WaitUntilCanceledPromise>();
|
||||||
|
|
||||||
|
CancellationToken cancellationToken;
|
||||||
|
|
||||||
|
UniTaskCompletionSourceCore<object> core;
|
||||||
|
|
||||||
|
WaitUntilCanceledPromise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IUniTaskSource Create(CancellationToken cancellationToken, PlayerLoopTiming timing, out short token)
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
return AutoResetUniTaskCompletionSource.CreateFromCanceled(cancellationToken, out token);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = pool.TryRent() ?? new WaitUntilCanceledPromise();
|
||||||
|
|
||||||
|
result.cancellationToken = cancellationToken;
|
||||||
|
|
||||||
|
TaskTracker.TrackActiveTask(result, 3);
|
||||||
|
|
||||||
|
PlayerLoopHelper.AddAction(timing, result);
|
||||||
|
|
||||||
|
token = result.core.Version;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetResult(short token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TaskTracker.RemoveTracking(this);
|
||||||
|
core.GetResult(token);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
pool.TryReturn(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus GetStatus(short token)
|
||||||
|
{
|
||||||
|
return core.GetStatus(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UniTaskStatus UnsafeGetStatus()
|
||||||
|
{
|
||||||
|
return core.UnsafeGetStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCompleted(Action<object> continuation, object state, short token)
|
||||||
|
{
|
||||||
|
core.OnCompleted(continuation, state, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
if (cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
core.TrySetResult(null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
core.Reset();
|
||||||
|
cancellationToken = default;
|
||||||
|
}
|
||||||
|
|
||||||
|
~WaitUntilCanceledPromise()
|
||||||
|
{
|
||||||
|
if (pool.TryReturn(this))
|
||||||
|
{
|
||||||
|
GC.ReRegisterForFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// where T : UnityEngine.Object, can not add constraint
|
// where T : UnityEngine.Object, can not add constraint
|
||||||
sealed class WaitUntilValueChangedUnityObjectPromise<T, U> : IUniTaskSource<U>, IPlayerLoopItem, IPromisePoolItem
|
sealed class WaitUntilValueChangedUnityObjectPromise<T, U> : IUniTaskSource<U>, IPlayerLoopItem, IPromisePoolItem
|
||||||
{
|
{
|
||||||
|
@ -353,7 +443,6 @@ namespace Cysharp.Threading.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sealed class WaitUntilValueChangedStandardObjectPromise<T, U> : IUniTaskSource<U>, IPlayerLoopItem, IPromisePoolItem
|
sealed class WaitUntilValueChangedStandardObjectPromise<T, U> : IUniTaskSource<U>, IPlayerLoopItem, IPromisePoolItem
|
||||||
where T : class
|
where T : class
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,16 +203,19 @@ public class SandboxMain : MonoBehaviour
|
||||||
//await UniTaskAsyncEnumerable.EveryUpdate().Take(10).ForEachAsync((x, i) => rp.Value = i);
|
//await UniTaskAsyncEnumerable.EveryUpdate().Take(10).ForEachAsync((x, i) => rp.Value = i);
|
||||||
|
|
||||||
//rp.Dispose();
|
//rp.Dispose();
|
||||||
|
var cts = new CancellationTokenSource();
|
||||||
|
Running(cts.Token).Forget();
|
||||||
|
|
||||||
await this.GetAsyncUpdateTrigger().ForEachAsync(x => Debug.Log("yeah"));
|
|
||||||
Debug.Log("DONE");
|
|
||||||
|
cts.CancelAfterSlim(TimeSpan.FromSeconds(3));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async UniTaskVoid Running(IReadOnlyAsyncReactiveProperty<int> rp)
|
async UniTaskVoid Running(CancellationToken ct)
|
||||||
{
|
{
|
||||||
Debug.Log("BEGIN");
|
Debug.Log("BEGIN");
|
||||||
await rp.ForEachAsync(x => Debug.Log("AR:" + x));
|
await UniTask.WaitUntilCanceled(ct);
|
||||||
Debug.Log("DONE");
|
Debug.Log("DONE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue