From f4294d3752ba066192f860371e79008204c413f4 Mon Sep 17 00:00:00 2001 From: neuecc Date: Thu, 4 Jun 2020 14:52:36 +0900 Subject: [PATCH] Task Pool moved from Internal --- .../Plugins/UniTask/Runtime/Internal/Hack.cs | 23 -- .../UniTask/Runtime/Internal/Hack.cs.meta | 11 - .../UniTask/Runtime/Internal/TaskTracker.cs | 16 +- .../Runtime/{Internal => }/TaskPool.cs | 2 +- .../Runtime/{Internal => }/TaskPool.cs.meta | 0 .../UniTask/Runtime/UniTask.Factory.cs | 206 +++++++++++++++++- src/UniTask/Assets/Scenes/SandboxMain.cs | 16 +- 7 files changed, 223 insertions(+), 51 deletions(-) delete mode 100644 src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs delete mode 100644 src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs.meta rename src/UniTask/Assets/Plugins/UniTask/Runtime/{Internal => }/TaskPool.cs (98%) rename src/UniTask/Assets/Plugins/UniTask/Runtime/{Internal => }/TaskPool.cs.meta (100%) diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs deleted file mode 100644 index d7cb43e..0000000 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if NET_4_6 || NET_STANDARD_2_0 || CSHARP_7_OR_LATER - -using System; - -namespace Cysharp.Threading.Tasks.Internal -{ - internal static class FuncExtensions - { - // avoid lambda capture - - internal static Action AsFuncOfT(this Action action) - { - return new Action(action.Invoke); - } - - static void Invoke(this Action action, T unused) - { - action(); - } - } -} - -#endif \ No newline at end of file diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs.meta b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs.meta deleted file mode 100644 index e77edfc..0000000 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/Hack.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4d5a9a3e1f0f069478969f752fde29a9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskTracker.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskTracker.cs index c22a8e0..c163e22 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskTracker.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskTracker.cs @@ -71,9 +71,19 @@ namespace Cysharp.Threading.Tasks dirty = true; if (!EditorEnableState.EnableTracking) return; var stackTrace = EditorEnableState.EnableStackTrace ? new StackTrace(skipFrame, true).CleanupAsyncStackTrace() : ""; - var sb = new StringBuilder(); - TypeBeautify(task.GetType(), sb); - tracking.TryAdd(task, (sb.ToString(), Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace)); + + string typeName; + if (EditorEnableState.EnableStackTrace) + { + var sb = new StringBuilder(); + TypeBeautify(task.GetType(), sb); + typeName = sb.ToString(); + } + else + { + typeName = task.GetType().Name; + } + tracking.TryAdd(task, (typeName, Interlocked.Increment(ref trackingId), DateTime.UtcNow, stackTrace)); #endif } diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskPool.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/TaskPool.cs similarity index 98% rename from src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskPool.cs rename to src/UniTask/Assets/Plugins/UniTask/Runtime/TaskPool.cs index 8860854..57fa7cb 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskPool.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/TaskPool.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; -namespace Cysharp.Threading.Tasks.Internal +namespace Cysharp.Threading.Tasks { // internaly used but public, allow to user create custom operator with pooling. diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskPool.cs.meta b/src/UniTask/Assets/Plugins/UniTask/Runtime/TaskPool.cs.meta similarity index 100% rename from src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/TaskPool.cs.meta rename to src/UniTask/Assets/Plugins/UniTask/Runtime/TaskPool.cs.meta diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Factory.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Factory.cs index 4a4d953..17619f8 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Factory.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/UniTask.Factory.cs @@ -1,6 +1,8 @@ #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member +using Cysharp.Threading.Tasks.Internal; using System; +using System.Runtime.CompilerServices; using System.Threading; namespace Cysharp.Threading.Tasks @@ -102,8 +104,7 @@ namespace Cysharp.Threading.Tasks } /// - /// helper of create add UniTaskVoid to delegate. - /// For example: FooEvent += () => UniTask.Void(async () => { /* */ }) + /// helper of fire and forget void action. /// public static void Void(Func asyncAction) { @@ -111,7 +112,7 @@ namespace Cysharp.Threading.Tasks } /// - /// helper of create add UniTaskVoid to delegate. + /// helper of fire and forget void action. /// public static void Void(Func asyncAction, CancellationToken cancellationToken) { @@ -119,8 +120,7 @@ namespace Cysharp.Threading.Tasks } /// - /// helper of create add UniTaskVoid to delegate. - /// For example: FooEvent += (sender, e) => UniTask.Void(async arg => { /* */ }, (sender, e)) + /// helper of fire and forget void action. /// public static void Void(Func asyncAction, T state) { @@ -133,7 +133,7 @@ namespace Cysharp.Threading.Tasks /// public static Action Action(Func asyncAction) { - return () => asyncAction().Forget(); + return AsyncAction.Create(asyncAction); } /// @@ -141,7 +141,7 @@ namespace Cysharp.Threading.Tasks /// public static Action Action(Func asyncAction, CancellationToken cancellationToken) { - return () => asyncAction(cancellationToken).Forget(); + return AsyncActionWithCancellation.Create(asyncAction, cancellationToken); } #if UNITY_2018_3_OR_NEWER @@ -152,7 +152,7 @@ namespace Cysharp.Threading.Tasks /// public static UnityEngine.Events.UnityAction UnityAction(Func asyncAction) { - return () => asyncAction().Forget(); + return AsyncUnityAction.Create(asyncAction); } /// @@ -161,7 +161,7 @@ namespace Cysharp.Threading.Tasks /// public static UnityEngine.Events.UnityAction UnityAction(Func asyncAction, CancellationToken cancellationToken) { - return () => asyncAction(cancellationToken).Forget(); + return AsyncUnityActionWithCancellation.Create(asyncAction, cancellationToken); } #endif @@ -260,6 +260,194 @@ namespace Cysharp.Threading.Tasks return task.Status; } } + + sealed class AsyncAction : ITaskPoolNode + { + static TaskPool pool; + + public AsyncAction NextNode { get; set; } + + static AsyncAction() + { + TaskPool.RegisterSizeGetter(typeof(AsyncAction), () => pool.Size); + } + + readonly Action runDelegate; + Func voidAction; + + AsyncAction() + { + runDelegate = Run; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Action Create(Func voidAction) + { + if (!pool.TryPop(out var item)) + { + item = new AsyncAction(); + } + + item.voidAction = voidAction; + return item.runDelegate; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + var call = voidAction; + voidAction = null; + if (call != null) + { + pool.TryPush(this); + call.Invoke(); + } + } + } + + sealed class AsyncActionWithCancellation : ITaskPoolNode + { + static TaskPool pool; + + public AsyncActionWithCancellation NextNode { get; set; } + + static AsyncActionWithCancellation() + { + TaskPool.RegisterSizeGetter(typeof(AsyncActionWithCancellation), () => pool.Size); + } + + readonly Action runDelegate; + CancellationToken cancellationToken; + Func voidAction; + + AsyncActionWithCancellation() + { + runDelegate = Run; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Action Create(Func voidAction, CancellationToken cancellationToken) + { + if (!pool.TryPop(out var item)) + { + item = new AsyncActionWithCancellation(); + } + + item.voidAction = voidAction; + item.cancellationToken = cancellationToken; + return item.runDelegate; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + var call = voidAction; + var ct = cancellationToken; + voidAction = null; + cancellationToken = default; + if (call != null) + { + pool.TryPush(this); + call.Invoke(ct); + } + } + } + +#if UNITY_2018_3_OR_NEWER + + sealed class AsyncUnityAction : ITaskPoolNode + { + static TaskPool pool; + + public AsyncUnityAction NextNode { get; set; } + + static AsyncUnityAction() + { + TaskPool.RegisterSizeGetter(typeof(AsyncUnityAction), () => pool.Size); + } + + readonly UnityEngine.Events.UnityAction runDelegate; + Func voidAction; + + AsyncUnityAction() + { + runDelegate = Run; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UnityEngine.Events.UnityAction Create(Func voidAction) + { + if (!pool.TryPop(out var item)) + { + item = new AsyncUnityAction(); + } + + item.voidAction = voidAction; + return item.runDelegate; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + var call = voidAction; + voidAction = null; + if (call != null) + { + pool.TryPush(this); + call.Invoke(); + } + } + } + + sealed class AsyncUnityActionWithCancellation : ITaskPoolNode + { + static TaskPool pool; + + public AsyncUnityActionWithCancellation NextNode { get; set; } + + static AsyncUnityActionWithCancellation() + { + TaskPool.RegisterSizeGetter(typeof(AsyncUnityActionWithCancellation), () => pool.Size); + } + + readonly UnityEngine.Events.UnityAction runDelegate; + CancellationToken cancellationToken; + Func voidAction; + + AsyncUnityActionWithCancellation() + { + runDelegate = Run; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UnityEngine.Events.UnityAction Create(Func voidAction, CancellationToken cancellationToken) + { + if (!pool.TryPop(out var item)) + { + item = new AsyncUnityActionWithCancellation(); + } + + item.voidAction = voidAction; + item.cancellationToken = cancellationToken; + return item.runDelegate; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void Run() + { + var call = voidAction; + var ct = cancellationToken; + voidAction = null; + cancellationToken = default; + if (call != null) + { + pool.TryPush(this); + call.Invoke(ct); + } + } + } + +#endif } internal static class CompletedTasks diff --git a/src/UniTask/Assets/Scenes/SandboxMain.cs b/src/UniTask/Assets/Scenes/SandboxMain.cs index e6fc580..27d2979 100644 --- a/src/UniTask/Assets/Scenes/SandboxMain.cs +++ b/src/UniTask/Assets/Scenes/SandboxMain.cs @@ -295,6 +295,12 @@ public class SandboxMain : MonoBehaviour return req; } + async Task Test() + { + await Task.Yield(); + return 10; + } + async UniTaskVoid Start() { @@ -323,13 +329,15 @@ public class SandboxMain : MonoBehaviour //await okButton.GetComponent().DOMoveY(10.2f, 3).WithCancellation(CancellationToken.None); //Debug.Log("AGAIN END MOVE"); + Debug.Log(Test().GetType().FullName); + // check stacktrace - await UniTaskAsyncEnumerable.EveryUpdate().Where((x, i) => i % 2 == 0).Select(x => x).DistinctUntilChanged().ForEachAsync(x => - { - Debug.Log("test"); - }); + // await UniTaskAsyncEnumerable.EveryUpdate().Where((x, i) => i % 2 == 0).Select(x => x).DistinctUntilChanged().ForEachAsync(x => + //{ + // Debug.Log("test"); + //});