From 6914df7de0945a0a12789275aa95dcfbda7cc587 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Fri, 19 Feb 2021 16:23:57 +0900 Subject: [PATCH] not Generic --- .../Runtime/UniGLTF/IO/AltTask/Awaitable.cs | 141 ++++++++++++++++++ .../UniGLTF/IO/AltTask/Awaitable.cs.meta | 11 ++ .../{GenericTask.cs => GenericAwaitable.cs} | 17 --- ...cTask.cs.meta => GenericAwaitable.cs.meta} | 0 .../Runtime/UniGLTF/IO/ImporterContext.cs | 28 ++-- .../IO/MaterialLoader/MaterialFactory.cs | 3 +- .../Runtime/UniGLTF/IO/MeshImporter.cs | 10 +- .../VRM.Samples/Scripts/VRMRuntimeLoader.cs | 5 +- Assets/VRM.Samples/Scripts/ViewerUI.cs | 7 +- Assets/VRM/Runtime/IO/VRMImporterContext.cs | 18 +-- 10 files changed, 180 insertions(+), 60 deletions(-) create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs create mode 100644 Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs.meta rename Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/{GenericTask.cs => GenericAwaitable.cs} (89%) rename Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/{GenericTask.cs.meta => GenericAwaitable.cs.meta} (100%) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs new file mode 100644 index 000000000..b199f68e4 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs @@ -0,0 +1,141 @@ +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; + + +namespace UniGLTF.AltTask +{ + public interface IAwaiter : INotifyCompletion + { + bool IsCompleted { get; } + void GetResult(); + } + + public interface IAwaitable + { + IAwaiter GetAwaiter(); + } + + public struct AwaitableMethodBuilder + { + // https://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs + private AsyncTaskMethodBuilder _methodBuilder; + + public static AwaitableMethodBuilder Create() => + new AwaitableMethodBuilder { _methodBuilder = AsyncTaskMethodBuilder.Create() }; + + public void Start(ref TStateMachine stateMachine) + where TStateMachine : IAsyncStateMachine + { + _methodBuilder.Start(ref stateMachine); + } + + public void SetStateMachine(IAsyncStateMachine stateMachine) + { + _methodBuilder.SetStateMachine(stateMachine); + } + public void SetException(Exception exception) + { + _methodBuilder.SetException(exception); + } + public void SetResult() + { + _methodBuilder.SetResult(); + } + + public void AwaitOnCompleted( + ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : INotifyCompletion + where TStateMachine : IAsyncStateMachine + { + _methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine); + } + public void AwaitUnsafeOnCompleted( + ref TAwaiter awaiter, ref TStateMachine stateMachine) + where TAwaiter : ICriticalNotifyCompletion + where TStateMachine : IAsyncStateMachine + { + _methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); + } + + public Awaitable Task => new Awaitable(_methodBuilder.Task); + } + + [AsyncMethodBuilder(typeof(AwaitableMethodBuilder))] + public struct Awaitable : IAwaitable + { + private Task _task; + + public Awaitable(Task task) + { + _task = task; + } + + public bool IsCompleted => _task.IsCompleted; + + public IAwaiter GetAwaiter() + { + return new Awaiter(this); + } + + public void ContinueWith(Action action) + { + _task.ContinueWith((Task, _) => + { + action(); + }, null); + } + + public static Awaitable Delay() + { + var task = Task.FromResult(default); + return new Awaitable(task); + } + + public static Awaitable Run(Func action) + { + return new Awaitable(Task.Run(action)); + } + + public static Awaitable Run(Action action) + { + return new Awaitable(Task.Run(action)); + } + + public static Awaitable FromResult(T result) + { + return new Awaitable(Task.FromResult(result)); + } + } + + public class Awaiter : IAwaiter + { + Awaitable m_task; + + public bool IsCompleted + { + get + { + return m_task.IsCompleted; + } + } + + public void GetResult() + { + } + + public void OnCompleted(Action continuation) + { + var context = TaskQueue.Current; + this.m_task.ContinueWith(() => + { + context.Post(_ => continuation(), null); + }); + } + + public Awaiter(Awaitable task) + { + m_task = task; + } + } +} diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs.meta new file mode 100644 index 000000000..4b6350805 --- /dev/null +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/Awaitable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4a5d6155408ca734297a104d9e590d1f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericTask.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericAwaitable.cs similarity index 89% rename from Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericTask.cs rename to Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericAwaitable.cs index 348764c03..8b4c51bbe 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericTask.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericAwaitable.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Threading; using System.Threading.Tasks; @@ -98,19 +96,6 @@ namespace UniGLTF.AltTask } } - public static class Awaitable - { - public static Awaitable Run(Func action) - { - return new Awaitable(Task.Run(action)); - } - - public static Awaitable FromResult(T result) - { - return new Awaitable(Task.FromResult(result)); - } - } - public class Awaiter : IAwaiter { Awaitable m_task; @@ -142,6 +127,4 @@ namespace UniGLTF.AltTask m_task = task; } } - - public struct Unit { } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericTask.cs.meta b/Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericAwaitable.cs.meta similarity index 100% rename from Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericTask.cs.meta rename to Assets/UniGLTF/Runtime/UniGLTF/IO/AltTask/GenericAwaitable.cs.meta diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index 26ea6d5eb..96b69ba24 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -12,7 +12,7 @@ using UnityEditor; namespace UniGLTF { - using Task = Awaitable; + /// /// GLTF importer @@ -355,13 +355,8 @@ namespace UniGLTF public bool EnableLoadBalancing; - public virtual async Awaitable LoadAsync(Func nextFrame = null) + public virtual async Awaitable LoadAsync() { - if (nextFrame == null) - { - nextFrame = () => Task.Delay(); - } - if (Root == null) { Root = new GameObject("_root_"); @@ -384,7 +379,7 @@ namespace UniGLTF using (MeasureTime("ReadMesh")) { var x = meshImporter.ReadMesh(this, index); - var y = await BuildMeshAsync(nextFrame, x, index); + var y = await BuildMeshAsync(x, index); Meshes.Add(y); } } @@ -396,7 +391,7 @@ namespace UniGLTF Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform); } } - await nextFrame(); + await Awaitable.Delay(); using (MeasureTime("BuildHierarchy")) { @@ -421,38 +416,35 @@ namespace UniGLTF t.SetParent(Root.transform, false); } } - await nextFrame(); + await Awaitable.Delay(); using (MeasureTime("AnimationImporter")) { AnimationImporter.Import(this); } - await OnLoadModel(nextFrame); + await OnLoadModel(); if (m_showSpeedLog) { Debug.Log(GetSpeedLog()); } - - return new Unit(); } - protected virtual async Task OnLoadModel(Func nextFrame) + protected virtual async Awaitable OnLoadModel() { Root.name = "GLTF"; - await nextFrame(); - return new Unit(); + await Awaitable.Delay(); } - async Awaitable BuildMeshAsync(Func nextFrame, MeshImporter.MeshContext x, int i) + async Awaitable BuildMeshAsync(MeshImporter.MeshContext x, int i) { using (MeasureTime("BuildMesh")) { MeshWithMaterials meshWithMaterials; if (EnableLoadBalancing) { - meshWithMaterials = await MeshImporter.BuildMeshAsync(nextFrame, MaterialFactory, x); + meshWithMaterials = await MeshImporter.BuildMeshAsync(MaterialFactory, x); } else { diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs index de4574945..915882998 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs @@ -69,7 +69,7 @@ namespace UniGLTF return m_materials[index]; } - public async Awaitable LoadMaterialsAsync(GetTextureAsyncFunc getTexture) + public async Awaitable LoadMaterialsAsync(GetTextureAsyncFunc getTexture) { if (m_gltf.materials == null || m_gltf.materials.Count == 0) { @@ -84,7 +84,6 @@ namespace UniGLTF AddMaterial(material); } } - return new Unit(); } public static Material CreateMaterial(int index, glTFMaterial src, string shaderName) diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs index bdc14bb1f..5952b9349 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs @@ -8,7 +8,7 @@ using UnityEngine; namespace UniGLTF { - using Task = Awaitable; + public class MeshImporter { @@ -654,15 +654,15 @@ namespace UniGLTF return result; } - public static async Awaitable BuildMeshAsync(Func nextFrame, MaterialFactory ctx, MeshImporter.MeshContext meshContext) + public static async Awaitable BuildMeshAsync(MaterialFactory ctx, MeshImporter.MeshContext meshContext) { var (mesh, recalculateTangents) = _BuildMesh(meshContext); if (recalculateTangents) { - await nextFrame(); + await Awaitable.Delay(); mesh.RecalculateTangents(); - await nextFrame(); + await Awaitable.Delay(); } // 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい @@ -672,7 +672,7 @@ namespace UniGLTF Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x)).ToArray() }; - await nextFrame(); + await Awaitable.Delay(); if (meshContext.BlendShapes.Count > 0) { var emptyVertices = new Vector3[mesh.vertexCount]; diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs index 7a0aafac1..34aba0ad2 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs @@ -7,7 +7,7 @@ using UnityEngine; namespace VRM.Samples { - using Task = Awaitable; + public class VRMRuntimeLoader : MonoBehaviour { @@ -165,7 +165,7 @@ namespace VRM.Samples } - async Task LoadAsync(VRMImporterContext context) + async Awaitable LoadAsync(VRMImporterContext context) { #if true var now = Time.time; @@ -178,7 +178,6 @@ namespace VRM.Samples // ローカルファイルシステムからロードします VRMImporter.LoadVrmAsync(path, OnLoaded); #endif - return new Unit(); } void LoadBVHClicked() diff --git a/Assets/VRM.Samples/Scripts/ViewerUI.cs b/Assets/VRM.Samples/Scripts/ViewerUI.cs index 73a68b164..a760a8fc6 100644 --- a/Assets/VRM.Samples/Scripts/ViewerUI.cs +++ b/Assets/VRM.Samples/Scripts/ViewerUI.cs @@ -10,7 +10,7 @@ using UnityEngine.UI; namespace VRM.Samples { - using Task = Awaitable; + public class ViewerUI : MonoBehaviour { @@ -87,7 +87,7 @@ namespace VRM.Samples m_textDistributionOther.text = ""; } - public async Task UpdateMetaAsync(VRMImporterContext context) + public async Awaitable UpdateMetaAsync(VRMImporterContext context) { var meta = await context.ReadMetaAsync(true); @@ -107,10 +107,9 @@ namespace VRM.Samples m_textDistributionOther.text = meta.OtherLicenseUrl; m_thumbnail.texture = meta.Thumbnail; - - return new Unit(); } } + [SerializeField] TextFields m_texts = default; diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index af4567fed..3f4029003 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -9,7 +9,7 @@ using UniGLTF.AltTask; namespace VRM { - using Task = Awaitable; + public class VRMImporterContext : ImporterContext { @@ -53,7 +53,7 @@ namespace VRM } #region OnLoad - protected override async Task OnLoadModel(Func nextFrame) + protected override async Awaitable OnLoadModel() { Root.name = "VRM"; @@ -61,43 +61,39 @@ namespace VRM { await LoadMetaAsync(); } - await nextFrame(); + await Awaitable.Delay(); using (MeasureTime("VRM LoadHumanoid")) { LoadHumanoid(); } - await nextFrame(); + await Awaitable.Delay(); using (MeasureTime("VRM LoadBlendShapeMaster")) { LoadBlendShapeMaster(); } - await nextFrame(); + await Awaitable.Delay(); using (MeasureTime("VRM LoadSecondary")) { VRMSpringUtility.LoadSecondary(Root.transform, Nodes, VRM.secondaryAnimation); } - await nextFrame(); + await Awaitable.Delay(); using (MeasureTime("VRM LoadFirstPerson")) { LoadFirstPerson(); } - - return new Unit(); } - async Task LoadMetaAsync() + async Awaitable LoadMetaAsync() { var meta = await ReadMetaAsync(); var _meta = Root.AddComponent(); _meta.Meta = meta; Meta = meta; - - return new Unit(); } void LoadFirstPerson()