From 4743ad7c57b0db25673c2ee29dcc8d78dc4277d9 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 14 Oct 2021 18:19:15 +0900 Subject: [PATCH 1/5] mv --- .../GLTF/IO/Runtime/AwaitCaller.meta | 3 +++ .../Runtime/{ => AwaitCaller}/IAwaitCaller.cs | 22 --------------- .../{ => AwaitCaller}/IAwaitCaller.cs.meta | 0 .../IO/Runtime/AwaitCaller/ImmediateCaller.cs | 27 +++++++++++++++++++ .../AwaitCaller/ImmediateCaller.cs.meta | 11 ++++++++ 5 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller.meta rename Assets/VRMShaders/GLTF/IO/Runtime/{ => AwaitCaller}/IAwaitCaller.cs (70%) rename Assets/VRMShaders/GLTF/IO/Runtime/{ => AwaitCaller}/IAwaitCaller.cs.meta (100%) create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs.meta diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller.meta b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller.meta new file mode 100644 index 000000000..f759ea07f --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ea8ee11da1da4f82b988a3108a362c2f +timeCreated: 1634202988 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/IAwaitCaller.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/IAwaitCaller.cs similarity index 70% rename from Assets/VRMShaders/GLTF/IO/Runtime/IAwaitCaller.cs rename to Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/IAwaitCaller.cs index 2d31a73d5..c97e4d0ce 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/IAwaitCaller.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/IAwaitCaller.cs @@ -32,26 +32,4 @@ namespace VRMShaders /// Task Run(Func action); } - - /// - /// 同期実行 - /// - public sealed class ImmediateCaller : IAwaitCaller - { - public Task NextFrame() - { - return Task.FromResult(null); - } - - public Task Run(Action action) - { - action(); - return Task.FromResult(null); - } - - public Task Run(Func action) - { - return Task.FromResult(action()); - } - } } diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/IAwaitCaller.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/IAwaitCaller.cs.meta similarity index 100% rename from Assets/VRMShaders/GLTF/IO/Runtime/IAwaitCaller.cs.meta rename to Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/IAwaitCaller.cs.meta diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs new file mode 100644 index 000000000..f3e6d56a0 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs @@ -0,0 +1,27 @@ +using System; +using System.Threading.Tasks; + +namespace VRMShaders +{ + /// + /// 同期実行 + /// + public sealed class ImmediateCaller : IAwaitCaller + { + public Task NextFrame() + { + return Task.FromResult(null); + } + + public Task Run(Action action) + { + action(); + return Task.FromResult(null); + } + + public Task Run(Func action) + { + return Task.FromResult(action()); + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs.meta new file mode 100644 index 000000000..a128df3a9 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/ImmediateCaller.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30f43d5b7d6b4184fb775a315b835365 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From cb1e30a19535361948123eccd95c7f6628b5b763 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 14 Oct 2021 19:18:44 +0900 Subject: [PATCH 2/5] =?UTF-8?q?RuntimeOnlyAwaitCaller=20=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AwaitCaller/NextFrameTaskScheduler.cs | 56 +++++++++++++++++++ .../NextFrameTaskScheduler.cs.meta | 3 + .../AwaitCaller/RuntimeOnlyAwaitCaller.cs | 32 +++++++++++ .../RuntimeOnlyAwaitCaller.cs.meta | 3 + .../AwaitCaller/TinyManagedTaskScheduler.cs | 35 ++++++++++++ .../TinyManagedTaskScheduler.cs.meta | 3 + 6 files changed, 132 insertions(+) create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs.meta create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs.meta create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs create mode 100644 Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs.meta diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs new file mode 100644 index 000000000..a63ac742d --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using UnityEngine; +using Object = UnityEngine.Object; + +namespace VRMShaders +{ + public sealed class NextFrameTaskScheduler + { + public bool IsSupported => Application.isPlaying; + + public NextFrameTaskScheduler() + { + if (!IsSupported) + { + throw new NotSupportedException($"{nameof(NextFrameTaskScheduler)} is supported at runtime only."); + } + } + + public bool Enqueue(Action action) + { + var currentFrame = Time.frameCount; + + UnityLoopTaskScheduler.Instance.Scheduler.Enqueue(action, () => Time.frameCount != currentFrame); + + return true; + } + + private sealed class UnityLoopTaskScheduler : MonoBehaviour + { + private static UnityLoopTaskScheduler _instance; + + public static UnityLoopTaskScheduler Instance + { + get + { + if (_instance == null) + { + var go = new GameObject("UniGLTF UnityThreadScheduler"); + Object.DontDestroyOnLoad(go); + _instance = go.AddComponent(); + } + return _instance; + } + } + + public TinyManagedTaskScheduler Scheduler { get; } = new TinyManagedTaskScheduler(); + + private void Update() + { + Scheduler.ManagedUpdate(); + } + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs.meta new file mode 100644 index 000000000..02892074e --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3ce7defdc7144878a058274ae561d0be +timeCreated: 1634203513 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs new file mode 100644 index 000000000..bb6c180e0 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading.Tasks; + +namespace VRMShaders +{ + public sealed class RuntimeOnlyAwaitCaller : IAwaitCaller + { + private readonly NextFrameTaskScheduler _scheduler; + + public RuntimeOnlyAwaitCaller() + { + _scheduler = new NextFrameTaskScheduler(); + } + + public Task NextFrame() + { + var tcs = new TaskCompletionSource(); + _scheduler.Enqueue(() => tcs.SetResult(default)); + return tcs.Task; + } + + public Task Run(Action action) + { + return Task.Run(action); + } + + public Task Run(Func action) + { + return Task.Run(action); + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs.meta new file mode 100644 index 000000000..a9e2c5963 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e4e64b1835ca4cd2b682a6bda572b8fb +timeCreated: 1634203216 \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs new file mode 100644 index 000000000..2f96cc5ef --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using UnityEngine; + +namespace VRMShaders +{ + internal sealed class TinyManagedTaskScheduler + { + private readonly ConcurrentQueue<(Action, Func)> _continuationQueue = + new ConcurrentQueue<(Action, Func)>(); + + public void ManagedUpdate() + { + while (_continuationQueue.TryDequeue(out var tuple)) + { + var (continuation, canExecute) = tuple; + + if (canExecute()) + { + continuation(); + } + else + { + _continuationQueue.Enqueue(tuple); + } + } + } + + public void Enqueue(Action continuation, Func canExecute) + { + _continuationQueue.Enqueue((continuation, canExecute)); + } + } +} \ No newline at end of file diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs.meta b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs.meta new file mode 100644 index 000000000..3c81f82e0 --- /dev/null +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9c52ff07a0834bdc8f4c8d6c7f9a634f +timeCreated: 1634203919 \ No newline at end of file From 6f7e2b7ab4c0e2c4aff3b70ee499e3507c51282a Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 14 Oct 2021 19:33:41 +0900 Subject: [PATCH 3/5] Fix infinite loop --- .../IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs index 2f96cc5ef..e6fc0c5ee 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs @@ -9,6 +9,8 @@ namespace VRMShaders { private readonly ConcurrentQueue<(Action, Func)> _continuationQueue = new ConcurrentQueue<(Action, Func)>(); + private readonly ConcurrentQueue<(Action, Func)> _temporaryQueue = + new ConcurrentQueue<(Action, Func)>(); public void ManagedUpdate() { @@ -22,9 +24,14 @@ namespace VRMShaders } else { - _continuationQueue.Enqueue(tuple); + _temporaryQueue.Enqueue(tuple); } } + + while (_temporaryQueue.TryDequeue(out var tuple)) + { + _continuationQueue.Enqueue(tuple); + } } public void Enqueue(Action continuation, Func canExecute) From 7b085d9b5da75018638dbd4b286fce0072b2d866 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 14 Oct 2021 19:43:00 +0900 Subject: [PATCH 4/5] make internal --- .../GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs | 4 +--- .../GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs index a63ac742d..27df7af6a 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/NextFrameTaskScheduler.cs @@ -1,12 +1,10 @@ using System; -using System.Collections.Generic; -using System.Threading.Tasks; using UnityEngine; using Object = UnityEngine.Object; namespace VRMShaders { - public sealed class NextFrameTaskScheduler + internal sealed class NextFrameTaskScheduler { public bool IsSupported => Application.isPlaying; diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs index e6fc0c5ee..820feb7f9 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/TinyManagedTaskScheduler.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Concurrent; -using System.Threading.Tasks; -using UnityEngine; namespace VRMShaders { From 92f09afdabc023ac50500db924cf126b766d63c7 Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Thu, 14 Oct 2021 21:10:08 +0900 Subject: [PATCH 5/5] comment --- .../GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs index bb6c180e0..23cc7b592 100644 --- a/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs +++ b/Assets/VRMShaders/GLTF/IO/Runtime/AwaitCaller/RuntimeOnlyAwaitCaller.cs @@ -3,6 +3,10 @@ using System.Threading.Tasks; namespace VRMShaders { + /// + /// Runtime (Build 後と、Editor Playing) での非同期ロードを実現する AwaitCaller. + /// NOTE: 簡便に実装されたものなので、最適化の余地はある. + /// public sealed class RuntimeOnlyAwaitCaller : IAwaitCaller { private readonly NextFrameTaskScheduler _scheduler;