Compare commits

...

8 Commits

Author SHA1 Message Date
neuecc
54ceca6ceb R 2020-06-25 23:03:13 +09:00
neuecc
50bdf7460c 2.0.21 2020-06-25 23:02:40 +09:00
neuecc
c06e45d0bb ToCancellationToken(linkeToken) 2020-06-25 23:02:30 +09:00
neuecc
3ed6e28a00 Removed Timeout(bool ignoreTimeScale), changed to Timeout(DelayType delayType) 2020-06-25 22:35:55 +09:00
neuecc
ab76098895 Removed CancelAfterSlim(bool ignoreTimeScale), changed to CancelAfterSlim(DelayType delayType) 2020-06-25 22:35:35 +09:00
neuecc
0a447e43b0 Add UniTask.ToCancellationToken 2020-06-25 22:34:45 +09:00
neuecc
8df44f2768 Remove UniTask.DelayRealtime, Add UniTask.Delay(DelayType) overload 2020-06-25 22:15:44 +09:00
neuecc
a7ec64d644 more 20 2020-06-24 05:09:00 +09:00
8 changed files with 127 additions and 36 deletions

View File

@@ -800,7 +800,7 @@ After Unity 2019.3.4f1, Unity 2020.1a21, that support path query parameter of gi
or add `"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask"` to `Packages/manifest.json`. or add `"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask"` to `Packages/manifest.json`.
If you want to set a target version, UniTask is using `*.*.*` release tag so you can specify a version like `#2.0.19`. For example `https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.0.19`. If you want to set a target version, UniTask is using `*.*.*` release tag so you can specify a version like `#2.0.21`. For example `https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask#2.0.21`.
### Install via OpenUPM ### Install via OpenUPM

View File

@@ -11,6 +11,55 @@ namespace Cysharp.Threading.Tasks
static readonly Action<object> cancellationTokenCallback = Callback; static readonly Action<object> cancellationTokenCallback = Callback;
static readonly Action<object> disposeCallback = DisposeCallback; static readonly Action<object> disposeCallback = DisposeCallback;
public static CancellationToken ToCancellationToken(this UniTask task)
{
var cts = new CancellationTokenSource();
ToCancellationTokenCore(task, cts).Forget();
return cts.Token;
}
public static CancellationToken ToCancellationToken(this UniTask task, CancellationToken linkToken)
{
if (linkToken.IsCancellationRequested)
{
return linkToken;
}
if (!linkToken.CanBeCanceled)
{
return ToCancellationToken(task);
}
var cts = new CancellationTokenSource();
ToCancellationTokenCore(task, cts).Forget();
return CancellationTokenSource.CreateLinkedTokenSource(linkToken).Token;
}
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task)
{
return ToCancellationToken(task.AsUniTask());
}
public static CancellationToken ToCancellationToken<T>(this UniTask<T> task, CancellationToken linkToken)
{
return ToCancellationToken(task.AsUniTask(), linkToken);
}
static async UniTaskVoid ToCancellationTokenCore(UniTask task, CancellationTokenSource cts)
{
try
{
await task;
}
catch (Exception ex)
{
UniTaskScheduler.PublishUnobservedTaskException(ex);
}
cts.Cancel();
cts.Dispose();
}
public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cancellationToken) public static (UniTask, CancellationTokenRegistration) ToUniTask(this CancellationToken cancellationToken)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)

View File

@@ -9,15 +9,15 @@ namespace Cysharp.Threading.Tasks
{ {
public static class CancellationTokenSourceExtensions public static class CancellationTokenSourceExtensions
{ {
public static void CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update) public static void CancelAfterSlim(this CancellationTokenSource cts, int millisecondsDelay, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{ {
var delay = UniTask.Delay(millisecondsDelay, ignoreTimeScale, delayTiming, cts.Token); var delay = UniTask.Delay(millisecondsDelay, delayType, delayTiming, cts.Token);
CancelAfterCore(cts, delay).Forget(); CancelAfterCore(cts, delay).Forget();
} }
public static void CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, bool ignoreTimeScale = false, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update) public static void CancelAfterSlim(this CancellationTokenSource cts, TimeSpan delayTimeSpan, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update)
{ {
var delay = UniTask.Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cts.Token); var delay = UniTask.Delay(delayTimeSpan, delayType, delayTiming, cts.Token);
CancelAfterCore(cts, delay).Forget(); CancelAfterCore(cts, delay).Forget();
} }

View File

@@ -8,6 +8,16 @@ using UnityEngine;
namespace Cysharp.Threading.Tasks namespace Cysharp.Threading.Tasks
{ {
public enum DelayType
{
/// <summary>use Time.deltaTime.</summary>
DeltaTime,
/// <summary>Ignore timescale, use Time.unscaledDeltaTime.</summary>
UnscaledDeltaTime,
/// <summary>use Stopwatch.GetTimestamp().</summary>
Realtime
}
public partial struct UniTask public partial struct UniTask
{ {
public static YieldAwaitable Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update) public static YieldAwaitable Yield(PlayerLoopTiming timing = PlayerLoopTiming.Update)
@@ -74,36 +84,44 @@ namespace Cysharp.Threading.Tasks
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))
{ {
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay); var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
if (delayTimeSpan < TimeSpan.Zero) return Delay(delayTimeSpan, ignoreTimeScale, delayTiming, cancellationToken);
{
throw new ArgumentOutOfRangeException("Delay does not allow minus millisecondsDelay. millisecondsDelay:" + millisecondsDelay);
}
return (ignoreTimeScale)
? new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token)
: new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token);
} }
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))
{ {
if (delayTimeSpan < TimeSpan.Zero) var delayType = ignoreTimeScale ? DelayType.UnscaledDeltaTime : DelayType.DeltaTime;
{ return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken);
throw new ArgumentOutOfRangeException("Delay does not allow minus delayTimeSpan. delayTimeSpan:" + delayTimeSpan);
}
return (ignoreTimeScale)
? new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token)
: new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out token), token);
} }
public static UniTask DelayRealtime(TimeSpan delayTimeSpan, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken)) public static UniTask Delay(int millisecondsDelay, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
{
var delayTimeSpan = TimeSpan.FromMilliseconds(millisecondsDelay);
return Delay(delayTimeSpan, delayType, delayTiming, cancellationToken);
}
public static UniTask Delay(TimeSpan delayTimeSpan, DelayType delayType, PlayerLoopTiming delayTiming = PlayerLoopTiming.Update, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (delayTimeSpan < TimeSpan.Zero) if (delayTimeSpan < TimeSpan.Zero)
{ {
throw new ArgumentOutOfRangeException("Delay does not allow minus delayTimeSpan. delayTimeSpan:" + delayTimeSpan); throw new ArgumentOutOfRangeException("Delay does not allow minus delayTimeSpan. delayTimeSpan:" + delayTimeSpan);
} }
return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token); switch (delayType)
{
case DelayType.UnscaledDeltaTime:
{
return new UniTask(DelayIgnoreTimeScalePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
}
case DelayType.Realtime:
{
return new UniTask(DelayRealtimePromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
}
case DelayType.DeltaTime:
default:
{
return new UniTask(DelayPromise.Create(delayTimeSpan, delayTiming, cancellationToken, out var token), token);
}
}
} }
sealed class YieldPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<YieldPromise> sealed class YieldPromise : IUniTaskSource, IPlayerLoopItem, ITaskPoolNode<YieldPromise>

View File

@@ -201,10 +201,10 @@ namespace Cysharp.Threading.Tasks
return new ToCoroutineEnumerator(task, exceptionHandler); return new ToCoroutineEnumerator(task, exceptionHandler);
} }
public static async UniTask Timeout(this UniTask task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) public static async UniTask Timeout(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
{ {
var delayCancellationTokenSource = new CancellationTokenSource(); var delayCancellationTokenSource = new CancellationTokenSource();
var timeoutTask = UniTask.Delay(timeout, ignoreTimeScale, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow();
int winArgIndex; int winArgIndex;
bool taskResultIsCanceled; bool taskResultIsCanceled;
@@ -242,10 +242,10 @@ namespace Cysharp.Threading.Tasks
} }
} }
public static async UniTask<T> Timeout<T>(this UniTask<T> task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) public static async UniTask<T> Timeout<T>(this UniTask<T> task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
{ {
var delayCancellationTokenSource = new CancellationTokenSource(); var delayCancellationTokenSource = new CancellationTokenSource();
var timeoutTask = UniTask.Delay(timeout, ignoreTimeScale, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow();
int winArgIndex; int winArgIndex;
(bool IsCanceled, T Result) taskResult; (bool IsCanceled, T Result) taskResult;
@@ -288,10 +288,10 @@ namespace Cysharp.Threading.Tasks
/// <summary> /// <summary>
/// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled). /// Timeout with suppress OperationCanceledException. Returns (bool, IsCacneled).
/// </summary> /// </summary>
public static async UniTask<bool> TimeoutWithoutException(this UniTask task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) public static async UniTask<bool> TimeoutWithoutException(this UniTask task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
{ {
var delayCancellationTokenSource = new CancellationTokenSource(); var delayCancellationTokenSource = new CancellationTokenSource();
var timeoutTask = UniTask.Delay(timeout, ignoreTimeScale, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow();
int winArgIndex; int winArgIndex;
bool taskResultIsCanceled; bool taskResultIsCanceled;
@@ -334,10 +334,10 @@ namespace Cysharp.Threading.Tasks
/// <summary> /// <summary>
/// Timeout with suppress OperationCanceledException. Returns (bool IsTimeout, T Result). /// Timeout with suppress OperationCanceledException. Returns (bool IsTimeout, T Result).
/// </summary> /// </summary>
public static async UniTask<(bool IsTimeout, T Result)> TimeoutWithoutException<T>(this UniTask<T> task, TimeSpan timeout, bool ignoreTimeScale = true, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null) public static async UniTask<(bool IsTimeout, T Result)> TimeoutWithoutException<T>(this UniTask<T> task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
{ {
var delayCancellationTokenSource = new CancellationTokenSource(); var delayCancellationTokenSource = new CancellationTokenSource();
var timeoutTask = UniTask.Delay(timeout, ignoreTimeScale, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow(); var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow();
int winArgIndex; int winArgIndex;
(bool IsCanceled, T Result) taskResult; (bool IsCanceled, T Result) taskResult;

View File

@@ -1,7 +1,7 @@
{ {
"name": "com.cysharp.unitask", "name": "com.cysharp.unitask",
"displayName": "UniTask", "displayName": "UniTask",
"version": "2.0.20", "version": "2.0.21",
"unity": "2018.4", "unity": "2018.4",
"description": "Provides an efficient async/await integration to Unity.", "description": "Provides an efficient async/await integration to Unity.",
"keywords": [ "async/await", "async", "Task", "UniTask" ], "keywords": [ "async/await", "async", "Task", "UniTask" ],

View File

@@ -435,13 +435,33 @@ public class SandboxMain : MonoBehaviour
} }
void Start()
async UniTaskVoid Start()
{ {
_ = Foo(); // unhandled. //_ = Foo(); // unhandled.
Go(); //Go();
var cts = new CancellationTokenSource();
okButton.onClick.AddListener(() =>
{
cts.Cancel();
});
UnityEngine.Debug.Log("Start:" + PlayerLoopInfo.CurrentLoopType); UnityEngine.Debug.Log("Start:" + PlayerLoopInfo.CurrentLoopType);
var token = UniTask.Delay(TimeSpan.FromSeconds(3), DelayType.Realtime).ToCancellationToken(cts.Token);
while (!token.IsCancellationRequested)
{
UnityEngine.Debug.Log("in loop");
await UniTask.Yield();
}
UnityEngine.Debug.Log("end");
// this.GetCancellationTokenOnDestroy()
//PlayerLoopInfo.Inject(); //PlayerLoopInfo.Inject();
//_ = AsyncFixedUpdate(); //_ = AsyncFixedUpdate();
@@ -458,7 +478,11 @@ public class SandboxMain : MonoBehaviour
//var cts = new CancellationTokenSource(); //var cts = new CancellationTokenSource();
// UniTask.Post(
// CancellationToken.
//UniTask.Delay(TimeSpan.FromSeconds(3)).
//okButton.onClick.AddListener(UniTask.UnityAction(async () => //okButton.onClick.AddListener(UniTask.UnityAction(async () =>

View File

@@ -190,7 +190,7 @@ namespace Cysharp.Threading.TasksTests
{ {
var now = DateTimeOffset.UtcNow; var now = DateTimeOffset.UtcNow;
await UniTask.DelayRealtime(TimeSpan.FromSeconds(2)); await UniTask.Delay(TimeSpan.FromSeconds(2), DelayType.Realtime);
var elapsed = DateTimeOffset.UtcNow - now; var elapsed = DateTimeOffset.UtcNow - now;