mirror of https://github.com/Cysharp/UniTask
use PooledDelegate to avoid convert Action to Action<AsyncOperation> allocation
parent
35b933730b
commit
10fb8060fa
|
@ -59,7 +59,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
|
|
||||||
#if NETCOREAPP3_1
|
#if NETCOREAPP3_1
|
||||||
|
|
||||||
public sealed class ThreadPoolWorkItem : IThreadPoolWorkItem
|
sealed class ThreadPoolWorkItem : IThreadPoolWorkItem
|
||||||
{
|
{
|
||||||
static readonly ConcurrentQueue<ThreadPoolWorkItem> pool = new ConcurrentQueue<ThreadPoolWorkItem>();
|
static readonly ConcurrentQueue<ThreadPoolWorkItem> pool = new ConcurrentQueue<ThreadPoolWorkItem>();
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
|
||||||
handle.Completed += continuationAction;
|
handle.Completed += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperationHandle>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperationHandle>.Create(continuation);
|
||||||
handle.CompletedTypeless += continuationAction;
|
handle.CompletedTypeless += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
using Cysharp.Threading.Tasks.Internal;
|
using Cysharp.Threading.Tasks.Internal;
|
||||||
using DG.Tweening;
|
using DG.Tweening;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -77,9 +78,8 @@ namespace Cysharp.Threading.Tasks
|
||||||
|
|
||||||
public void UnsafeOnCompleted(System.Action continuation)
|
public void UnsafeOnCompleted(System.Action continuation)
|
||||||
{
|
{
|
||||||
// convert Action -> TweenCallback allocation.
|
|
||||||
// onKill is called after OnCompleted, both Complete(false/true) and Kill(false/true).
|
// onKill is called after OnCompleted, both Complete(false/true) and Kill(false/true).
|
||||||
tween.onKill = new TweenCallback(continuation);
|
tween.onKill = PooledTweenCallback.Create(continuation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,8 @@ namespace Cysharp.Threading.Tasks
|
||||||
static readonly Action<object> CancellationCallbackDelegate = CancellationCallback;
|
static readonly Action<object> CancellationCallbackDelegate = CancellationCallback;
|
||||||
static readonly TweenCallback EmptyTweenCallback = () => { };
|
static readonly TweenCallback EmptyTweenCallback = () => { };
|
||||||
|
|
||||||
|
readonly TweenCallback onKillDelegate;
|
||||||
|
|
||||||
Tween tween;
|
Tween tween;
|
||||||
TweenCancelBehaviour cancelBehaviour;
|
TweenCancelBehaviour cancelBehaviour;
|
||||||
CancellationToken cancellationToken;
|
CancellationToken cancellationToken;
|
||||||
|
@ -99,7 +101,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
|
|
||||||
TweenConfiguredSource()
|
TweenConfiguredSource()
|
||||||
{
|
{
|
||||||
|
onKillDelegate = OnKill;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, out short token)
|
public static IUniTaskSource Create(Tween tween, TweenCancelBehaviour cancelBehaviour, CancellationToken cancellationToken, out short token)
|
||||||
|
@ -130,8 +132,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this);
|
cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(CancellationCallbackDelegate, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate delegate.
|
tween.OnKill(onKillDelegate);
|
||||||
tween.OnKill(new TweenCallback(OnKill));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnKill()
|
void OnKill()
|
||||||
|
@ -234,6 +235,45 @@ namespace Cysharp.Threading.Tasks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class PooledTweenCallback
|
||||||
|
{
|
||||||
|
static readonly ConcurrentQueue<PooledTweenCallback> pool = new ConcurrentQueue<PooledTweenCallback>();
|
||||||
|
|
||||||
|
readonly TweenCallback runDelegate;
|
||||||
|
|
||||||
|
Action continuation;
|
||||||
|
|
||||||
|
|
||||||
|
PooledTweenCallback()
|
||||||
|
{
|
||||||
|
runDelegate = Run;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static TweenCallback Create(Action continuation)
|
||||||
|
{
|
||||||
|
if (!pool.TryDequeue(out var item))
|
||||||
|
{
|
||||||
|
item = new PooledTweenCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
item.continuation = continuation;
|
||||||
|
return item.runDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
var call = continuation;
|
||||||
|
continuation = null;
|
||||||
|
if (call != null)
|
||||||
|
{
|
||||||
|
pool.Enqueue(this);
|
||||||
|
call.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Cysharp.Threading.Tasks.Internal
|
||||||
|
{
|
||||||
|
internal class PooledDelegate<T>
|
||||||
|
{
|
||||||
|
static readonly ConcurrentQueue<PooledDelegate<T>> pool = new ConcurrentQueue<PooledDelegate<T>>();
|
||||||
|
|
||||||
|
readonly Action<T> runDelegate;
|
||||||
|
|
||||||
|
Action continuation;
|
||||||
|
|
||||||
|
|
||||||
|
PooledDelegate()
|
||||||
|
{
|
||||||
|
runDelegate = Run;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Action<T> Create(Action continuation)
|
||||||
|
{
|
||||||
|
if (!pool.TryDequeue(out var item))
|
||||||
|
{
|
||||||
|
item = new PooledDelegate<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
item.continuation = continuation;
|
||||||
|
return item.runDelegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Run(T _)
|
||||||
|
{
|
||||||
|
var call = continuation;
|
||||||
|
continuation = null;
|
||||||
|
if (call != null)
|
||||||
|
{
|
||||||
|
pool.Enqueue(this);
|
||||||
|
call.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8932579438742fa40b010edd412dbfba
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -14,36 +14,6 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void Forget()
|
public void Forget()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// [DebuggerHidden]
|
|
||||||
// public Awaiter GetAwaiter()
|
|
||||||
// {
|
|
||||||
// return new Awaiter();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public struct Awaiter : ICriticalNotifyCompletion
|
|
||||||
// {
|
|
||||||
// [DebuggerHidden]
|
|
||||||
// public bool IsCompleted => true;
|
|
||||||
|
|
||||||
// [DebuggerHidden]
|
|
||||||
// public void GetResult()
|
|
||||||
// {
|
|
||||||
//#if UNITY_2018_3_OR_NEWER
|
|
||||||
// UnityEngine.Debug.LogWarning("UniTaskVoid can't await, always fire-and-forget. use Forget instead of await.");
|
|
||||||
//#endif
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [DebuggerHidden]
|
|
||||||
// public void OnCompleted(Action continuation)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [DebuggerHidden]
|
|
||||||
// public void UnsafeOnCompleted(Action continuation)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||||
asyncOperation.completed += continuationAction;
|
asyncOperation.completed += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||||
asyncOperation.completed += continuationAction;
|
asyncOperation.completed += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,7 +419,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||||
asyncOperation.completed += continuationAction;
|
asyncOperation.completed += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -596,7 +596,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||||
asyncOperation.completed += continuationAction;
|
asyncOperation.completed += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -774,7 +774,7 @@ namespace Cysharp.Threading.Tasks
|
||||||
public void UnsafeOnCompleted(Action continuation)
|
public void UnsafeOnCompleted(Action continuation)
|
||||||
{
|
{
|
||||||
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
Error.ThrowWhenContinuationIsAlreadyRegistered(continuationAction);
|
||||||
continuationAction = continuation.AsFuncOfT<AsyncOperation>(); // allocate delegate.
|
continuationAction = PooledDelegate<AsyncOperation>.Create(continuation);
|
||||||
asyncOperation.completed += continuationAction;
|
asyncOperation.completed += continuationAction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ using UnityEngine;
|
||||||
using UnityEngine.Networking;
|
using UnityEngine.Networking;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
|
||||||
// using DG.Tweening;
|
// using DG.Tweening;
|
||||||
|
|
||||||
public struct MyJob : IJob
|
public struct MyJob : IJob
|
||||||
|
@ -259,11 +258,15 @@ public class SandboxMain : MonoBehaviour
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var cts = new CancellationTokenSource();
|
//var cts = new CancellationTokenSource();
|
||||||
var r = UniAsync("https://bing.com/", cts.Token);
|
//var r = UniAsync("https://bing.com/", cts.Token);
|
||||||
cts.Cancel();
|
//cts.Cancel();
|
||||||
await r;
|
//await r;
|
||||||
Debug.Log("UNIASYNC");
|
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||||
|
Debug.Log("UNIASYNC1 ");
|
||||||
|
|
||||||
|
_ = await UnityWebRequest.Get("https://bing.com/").SendWebRequest();
|
||||||
|
Debug.Log("UNIASYNC2");
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -291,7 +294,7 @@ public class SandboxMain : MonoBehaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Start()
|
async UniTaskVoid Start()
|
||||||
{
|
{
|
||||||
//UniTaskAsyncEnumerable.EveryValueChanged(mcc, x => x.MyProperty)
|
//UniTaskAsyncEnumerable.EveryValueChanged(mcc, x => x.MyProperty)
|
||||||
// .Do(_ => { }, () => Debug.Log("COMPLETED"))
|
// .Do(_ => { }, () => Debug.Log("COMPLETED"))
|
||||||
|
@ -301,15 +304,23 @@ public class SandboxMain : MonoBehaviour
|
||||||
// })
|
// })
|
||||||
// .Forget();
|
// .Forget();
|
||||||
|
|
||||||
_ = Test1();
|
//_ = Test1();
|
||||||
Test2().Forget();
|
Test2().Forget();
|
||||||
StartCoroutine(Test3("https://bing.com/"));
|
//StartCoroutine(Test3("https://bing.com/"));
|
||||||
|
|
||||||
|
|
||||||
// DG.Tweening.Core.TweenerCore<int>
|
// DG.Tweening.Core.TweenerCore<int>
|
||||||
//okButton.GetComponent<RectTransform>().DOMoveX(10.2f, 30);
|
//Debug.Log("GO MOVEX");
|
||||||
|
//await okButton.GetComponent<RectTransform>().DOMoveX(-10.2f, 3).WithCancellation(CancellationToken.None);
|
||||||
|
//Debug.Log("END MOVEX");
|
||||||
|
|
||||||
|
|
||||||
|
//Debug.Log("AGAIN MOVE");
|
||||||
|
//await okButton.GetComponent<RectTransform>().DOMoveY(10.2f, 3).WithCancellation(CancellationToken.None);
|
||||||
|
//Debug.Log("AGAIN END MOVE");
|
||||||
|
|
||||||
|
|
||||||
|
await UniTask.Yield();
|
||||||
// DOTween.To(
|
// DOTween.To(
|
||||||
|
|
||||||
var cts = new CancellationTokenSource();
|
var cts = new CancellationTokenSource();
|
||||||
|
|
Loading…
Reference in New Issue