From 677ccf9d58b5724f40a7135f333c424261b32f56 Mon Sep 17 00:00:00 2001 From: ousttrue Date: Tue, 16 Feb 2021 20:16:21 +0900 Subject: [PATCH] remove DepthFirstScheduler #450 --- .../UniGLTF/Runtime/DepthFirstScheduler.meta | 8 - .../Runtime/DepthFirstScheduler/Functor.cs | 200 -------------- .../DepthFirstScheduler/Functor.cs.meta | 12 - .../IEnumeratorExtensions.cs | 37 --- .../IEnumeratorExtensions.cs.meta | 11 - .../Runtime/DepthFirstScheduler/LockQueue.cs | 95 ------- .../DepthFirstScheduler/LockQueue.cs.meta | 12 - .../MainThreadDispatcher.cs | 150 ----------- .../MainThreadDispatcher.cs.meta | 12 - .../DepthFirstScheduler/MonitorQueue.cs | 47 ---- .../DepthFirstScheduler/MonitorQueue.cs.meta | 12 - .../DepthFirstScheduler/Schedulable.cs | 253 ------------------ .../DepthFirstScheduler/Schedulable.cs.meta | 12 - .../Runtime/DepthFirstScheduler/Scheduler.cs | 9 - .../DepthFirstScheduler/Scheduler.cs.meta | 12 - .../DepthFirstScheduler/Scheduler.meta | 8 - .../Scheduler/CurrentThreadScheduler.cs | 102 ------- .../Scheduler/CurrentThreadScheduler.cs.meta | 11 - .../Scheduler/StepScheduler.cs | 52 ---- .../Scheduler/StepScheduler.cs.meta | 12 - .../Scheduler/ThreadPoolScheduler.cs | 42 --- .../Scheduler/ThreadPoolScheduler.cs.meta | 12 - .../Scheduler/ThreadScheduler.cs | 101 ------- .../Scheduler/ThreadScheduler.cs.meta | 12 - .../Runtime/DepthFirstScheduler/TaskChain.cs | 91 ------- .../DepthFirstScheduler/TaskChain.cs.meta | 12 - .../Runtime/DepthFirstScheduler/Unit.cs | 41 --- .../Runtime/DepthFirstScheduler/Unit.cs.meta | 12 - .../Runtime/UniGLTF/IO/ImporterContext.cs | 200 ++++++-------- .../UniGLTF/IO/ImporterContextExtensions.cs | 64 +---- .../IO/MaterialLoader/MaterialFactory.cs | 22 +- .../Runtime/UniGLTF/IO/MeshImporter.cs | 11 +- .../IO/TemporarySynchronizationContext.cs | 23 +- Assets/UniGLTF/Tests/DepthFirstScheduler.meta | 8 - .../DepthFirstScheduler.cs | 24 -- .../DepthFirstScheduler.cs.meta | 12 - .../VRM.Samples/Scripts/VRMRuntimeExporter.cs | 4 +- .../VRM.Samples/Scripts/VRMRuntimeLoader.cs | 13 +- Assets/VRM.Samples/Scripts/ViewerUI.cs | 4 + Assets/VRM/Runtime/IO/VRMImporterContext.cs | 17 +- 40 files changed, 126 insertions(+), 1666 deletions(-) delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs.meta delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs delete mode 100644 Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs.meta delete mode 100644 Assets/UniGLTF/Tests/DepthFirstScheduler.meta delete mode 100644 Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs delete mode 100644 Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs.meta diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler.meta deleted file mode 100644 index 0d4cf3d12..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 59e97de25dbef7844afdb7923e5497df -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs deleted file mode 100644 index 735dbbdf2..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace DepthFirstScheduler -{ - public enum ExecutionStatus - { - Unknown, - Done, - Continue, // coroutine or schedulable - Error, - } - - public interface IFunctor - { - T GetResult(); - Exception GetError(); - ExecutionStatus Execute(); - } - - #region Functor - public class Functor : IFunctor - { - T m_result; - public T GetResult() - { - return m_result; - } - - Exception m_error; - public Exception GetError() - { - return m_error; - } - - Action m_pred; - public Functor(Func func) - { - m_pred = () => m_result = func(); - } - - public ExecutionStatus Execute() - { - try - { - m_pred(); - return ExecutionStatus.Done; - } - catch (Exception ex) - { - m_error = ex; - return ExecutionStatus.Error; - } - } - } - - public static class Functor - { - /// - /// 引数の型を隠蔽した実行器を生成する - /// - /// 引数の型 - /// 結果の型 - /// - /// - /// - public static Functor Create(Func arg, Func pred) - { - return new Functor(() => pred(arg())); - } - } - #endregion - - #region CoroutineFunctor - public class CoroutineFunctor : IFunctor - { - public T GetResult() - { - if (m_last?.Current == null) return default; - - try - { - return (T)m_last.Current; - } - catch - { - return default; - } - } - - Exception m_error; - public Exception GetError() - { - return m_error; - } - - Func m_starter; - Stack m_it; - private IEnumerator m_last; - public CoroutineFunctor(Func starter) - { - m_starter = starter; - } - - public ExecutionStatus Execute() - { - if (m_it == null) - { - m_it = new Stack(); - m_it.Push(m_starter()); - } - - try - { - if (m_it.Count!=0) - { - if (m_it.Peek().MoveNext()) - { - var nested = m_it.Peek().Current as IEnumerator; - if (nested!=null) - { - m_it.Push(nested); - } - } - else - { - m_last = m_it.Pop(); - } - return ExecutionStatus.Continue; - } - else - { - return ExecutionStatus.Done; - } - - } - catch(Exception ex) - { - m_error = ex; - return ExecutionStatus.Error; - } - } - } - - public static class CoroutineFunctor - { - /// 引数の型 - /// 結果の型 - public static CoroutineFunctor Create(Func arg, Func starter) - { - return new CoroutineFunctor(() => starter(arg())); - } - } - #endregion - - /* - public class SchedulableFunctor : IFunctor - { - Schedulable m_schedulable; - Func> m_starter; - TaskChain m_chain; - - public SchedulableFunctor(Func> starter) - { - m_starter = starter; - } - - public ExecutionStatus Execute() - { - if (m_chain == null) - { - m_schedulable = m_starter(); - m_chain = TaskChain.Schedule(m_schedulable, ex => m_error = ex); - } - - return m_chain.Next(); - } - - Exception m_error; - public Exception GetError() - { - return m_error; - } - - public T GetResult() - { - return m_schedulable.Func.GetResult(); - } - } - - public static class SchedulableFunctor - { - public static SchedulableFunctor Create(Func> starter) - { - return new SchedulableFunctor(starter); - } - } - */ -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs.meta deleted file mode 100644 index 713019b19..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Functor.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: c320f3f577dde634a871dc88266c2a20 -timeCreated: 1520084196 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs deleted file mode 100644 index cb89c4c9b..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - - -namespace DepthFirstScheduler -{ - public static class IEnumeratorExtensions - { - [Obsolete("Use CoroutineToEnd")] - public static void CoroutinetoEnd(this IEnumerator coroutine) - { - CoroutineToEnd(coroutine); - } - - public static void CoroutineToEnd(this IEnumerator coroutine) - { - var stack = new Stack(); - stack.Push(coroutine); - while (stack.Count > 0) - { - if (stack.Peek().MoveNext()) - { - var nested = stack.Peek().Current as IEnumerator; - if (nested != null) - { - stack.Push(nested); - } - } - else - { - stack.Pop(); - } - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs.meta deleted file mode 100644 index b8a9f110a..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/IEnumeratorExtensions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4719fc9e6319c654b8a4818bef2c3a85 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs deleted file mode 100644 index 205edb0b1..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.Collections; -using System.Collections.Generic; - - -namespace DepthFirstScheduler -{ - public class LockQueue where T : class - { - List m_queue = new List(); - public int Count - { - get - { - lock (((ICollection)m_queue).SyncRoot) - { - return m_queue.Count; - } - } - } - - public void Enqueue(T t) - { - lock (((ICollection)m_queue).SyncRoot) - { - m_queue.Add(t); - } - } - - public T Dequeue(out int remain) - { - lock (((ICollection)m_queue).SyncRoot) - { - if (m_queue.Count == 0) - { - remain = 0; - return null; - } - var item = m_queue[0]; - m_queue.RemoveAt(0); - remain = m_queue.Count; - return item; - } - } - - public T Dequeue() - { - lock (((ICollection)m_queue).SyncRoot) - { - if (m_queue.Count == 0) return null; - var item = m_queue[0]; - m_queue.RemoveAt(0); - return item; - } - } - } - - public class LockQueueForValue where T : struct - { - List m_queue = new List(); - public int Count - { - get - { - lock (((ICollection)m_queue).SyncRoot) - { - return m_queue.Count; - } - } - } - - public void Enqueue(T t) - { - lock (((ICollection)m_queue).SyncRoot) - { - m_queue.Add(t); - } - } - - public bool TryDequeue(out T t) - { - lock (((ICollection)m_queue).SyncRoot) - { - if (m_queue.Count == 0) - { - t = default(T); - return false; - } - - t = m_queue[0]; - m_queue.RemoveAt(0); - return true; - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs.meta deleted file mode 100644 index cc5d5cfa9..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/LockQueue.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: f6b1eb436e400704ab6e2ad6eff29f4b -timeCreated: 1519978475 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs deleted file mode 100644 index bb01dfff6..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; - -namespace DepthFirstScheduler -{ - /// - /// UniRxのMainThreadDispatcherを参考にした。 - /// * https://github.com/neuecc/UniRx/blob/master/Assets/Plugins/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs - /// - public class MainThreadDispatcher : MonoBehaviour - { - - [Header("Debug")] - public int TaskCount; - - IEnumerable Ancestors(Transform t) - { - yield return t; - - if (t.parent != null) - { - foreach (var x in Ancestors(t.parent)) - { - yield return x; - } - } - } - - private void Update() - { - TaskCount = Scheduler.MainThread.UpdateAndGetTaskCount(); - } - - static MainThreadDispatcher instance; - static bool initialized; - static bool isQuitting = false; - - public static bool IsInitialized - { - get { return initialized && instance != null; } - } - - [ThreadStatic] - static object mainThreadToken; - - public static MainThreadDispatcher Instance - { - get - { - Initialize(); - return instance; - } - } - - public static void Initialize() - { - if (!initialized) - { -#if UNITY_EDITOR - if (!Application.isPlaying) - { - return; - } -#endif - MainThreadDispatcher dispatcher = null; - - try - { - dispatcher = GameObject.FindObjectOfType(); - } - catch - { - // Throw exception when calling from a worker thread. - var ex = new Exception( - "DepthFirstScheduler requires a MainThreadDispatcher component created on the main thread." - + " Make sure it is added to the scene before calling DepthFirstScheduler from a worker thread."); - UnityEngine.Debug.LogException(ex); - throw ex; - } - - if (isQuitting) - { - // don't create new instance after quitting - // avoid "Some objects were not cleaned up when closing the scene find target" error. - return; - } - - if (dispatcher == null) - { - // awake call immediately from UnityEngine - new GameObject("DepthFirstScheduler").AddComponent(); - } - else - { - dispatcher.Awake(); // force awake - } - } - } - - public static bool IsInMainThread - { - get - { - return (mainThreadToken != null); - } - } - - - void Awake() - { - if (instance == null) - { - Debug.Log("Initialize UniTask.MainThreadDispatcher"); - - instance = this; - mainThreadToken = new object(); - initialized = true; - - DontDestroyOnLoad(gameObject); - } - else - { - if (this != instance) - { - Debug.LogWarning("There is already a MainThreadDispatcher in the scene."); - } - } - } - - void OnDestroy() - { - if (instance == this) - { - instance = GameObject.FindObjectOfType(); - initialized = instance != null; - } - - if (Scheduler.SingleWorkerThread != null) - { - Scheduler.SingleWorkerThread.Dispose(); - } - } - - void OnApplicationQuit() - { - isQuitting = true; - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs.meta deleted file mode 100644 index 5777e1aba..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MainThreadDispatcher.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: b030a9507e46dd3488c080be0227b219 -timeCreated: 1519977925 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs deleted file mode 100644 index 79bf9823a..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; - - -namespace DepthFirstScheduler -{ - /// - /// http://blogs.msdn.com/b/toub/archive/2006/04/12/blocking-queues.aspx - /// - /// 終了を通知するにはnullを投入する手が使える - /// - /// - public class MonitorQueue - { - private Int32 _count = 0; - public Int32 Count - { - get - { - return _count; - } - } - - private Queue _queue = new Queue(); - - public T Dequeue() - { - lock (_queue) - { - while (_count <= 0) Monitor.Wait(_queue); - _count--; - return _queue.Dequeue(); - } - } - - public void Enqueue(T data) - { - lock (_queue) - { - _queue.Enqueue(data); - _count++; - Monitor.Pulse(_queue); - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs.meta deleted file mode 100644 index 2b6391747..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/MonitorQueue.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5e968e04ff53e1c4a9a2869b7cf76055 -timeCreated: 1519990411 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs deleted file mode 100644 index 587355a88..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs +++ /dev/null @@ -1,253 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER) -using System.Threading.Tasks; -#endif - -namespace DepthFirstScheduler -{ - public interface ISchedulable - { - /// 実行が終了したか?Coroutineの実行が一回で終わらない場合がある - ExecutionStatus Execute(); - Exception GetError(); - IScheduler Scheduler { get; } - - ISchedulable Parent { get; set; } - void AddChild(ISchedulable child); - IEnumerable Traverse(); - } - - public static class ISchedulableExtensions - { - public static ISchedulable GetRoot(this ISchedulable self) - { - var current = self; - while (current.Parent != null) - { - current = current.Parent; - } - return current; - } - } - - public class NoParentException: Exception - { - public NoParentException():base("No parent task can't ContinueWith or OnExecute. First AddTask") - { - } - } - - public class Schedulable : ISchedulable - { - List m_children = new List(); - public void AddChild(ISchedulable child) - { - child.Parent = this; - m_children.Add(child); - } - public IEnumerable Traverse() - { - yield return this; - - foreach (var child in m_children) - { - foreach (var x in child.Traverse()) - { - yield return x; - } - } - } - - public ISchedulable Parent - { - get; - set; - } - - public IScheduler Scheduler - { - get; - private set; - } - - public IFunctor Func - { - get; - private set; - } - - public Exception GetError() - { - return Func.GetError(); - } - - public Schedulable() - { - } - - public Schedulable(IScheduler scheduler, IFunctor func) - { - Scheduler = scheduler; - Func = func; - } - - public ExecutionStatus Execute() - { - if (Func == null) - { - return ExecutionStatus.Done; - } - return Func.Execute(); - } - - /// - /// スケジュールされたタスクをすべて即時に実行する - /// - public void ExecuteAll() - { - foreach (var x in this.GetRoot().Traverse()) - { - while (true) - { - var status = x.Execute(); - if (status != ExecutionStatus.Continue) - { - if (status == ExecutionStatus.Error) - { - // throw x.GetError(); - UnityEngine.Debug.LogException(x.GetError()); - } - break; - } - // Coroutineタスクが継続している - } - } - } - - public Schedulable AddTask(IScheduler scheduler, Action pred) - { - return AddTask(scheduler, () => { pred(); return Unit.Default; }); - } - - public Schedulable AddTask(IScheduler scheduler, Func pred) - { - var schedulable = new Schedulable(scheduler, Functor.Create(() => Unit.Default, _ => pred())); - AddChild(schedulable); - return schedulable; - } - - public Schedulable AddCoroutine(IScheduler scheduler, Func starter) - { - var func = CoroutineFunctor.Create(() => default(Unit), _ => starter()); - var schedulable = new Schedulable(scheduler, func); - AddChild(schedulable); - return schedulable; - } - - public Schedulable ContinueWith(IScheduler scheduler, Action pred) - { - return ContinueWith(scheduler, t => { pred(t); return Unit.Default; }); - } - - public Schedulable ContinueWith(IScheduler scheduler, Func pred) - { - if (Parent == null) - { - throw new NoParentException(); - } - - Func getResult = null; - if (Func != null) - { - getResult = Func.GetResult; - } - var func = Functor.Create(getResult, pred); - var schedulable = new Schedulable(scheduler, func); - Parent.AddChild(schedulable); - return schedulable; - } - - public Schedulable ContinueWithCoroutine(IScheduler scheduler, Func starter) - { - return ContinueWithCoroutine(scheduler, _ => starter()); - } - - public Schedulable ContinueWithCoroutine(IScheduler scheduler, Func starter) - { - if (Parent == null) - { - throw new NoParentException(); - } - - Func getResult = null; - if (Func != null) - { - getResult = Func.GetResult; - } - - var func = CoroutineFunctor.Create(getResult, starter); - var schedulable = new Schedulable(scheduler, func); - Parent.AddChild(schedulable); - return schedulable; - } - - public Schedulable OnExecute(IScheduler scheduler, Action> pred) - { - if (Parent == null) - { - throw new NoParentException(); - } - - Func getResult = null; - if (Func != null) - { - getResult = Func.GetResult; - } - - var schedulable = new Schedulable(); - schedulable.Func = Functor.Create(getResult, _ => { pred(schedulable); return Unit.Default; }); - Parent.AddChild(schedulable); - return schedulable; - } - } - - public static class Schedulable - { - public static Schedulable Create() - { - return new Schedulable().AddTask(Scheduler.CurrentThread, () => - { - }); - } - } - - public static class SchedulableExtensions - { - public static void Subscribe( - this Schedulable schedulable, - IScheduler scheduler, - Action onCompleted, - Action onError) - { - schedulable.ContinueWith(scheduler, onCompleted); - TaskChain.Schedule(schedulable.GetRoot(), onError); - } - -#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER) - public static Task ToTask(this Schedulable schedulable) - { - return ToTask(schedulable, Scheduler.MainThread); - } - - public static Task ToTask(this Schedulable schedulable, IScheduler scheduler) - { - var tcs = new TaskCompletionSource(); - schedulable.Subscribe(scheduler, r => tcs.TrySetResult(r), ex => tcs.TrySetException(ex)); - return tcs.Task; - } -#endif - - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs.meta deleted file mode 100644 index 439f4a26b..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Schedulable.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 45e21e7db278f344fbaeffc4c4b82b1e -timeCreated: 1519981307 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs deleted file mode 100644 index 41d898fe8..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace DepthFirstScheduler -{ - public interface IScheduler : IDisposable - { - void Enqueue(TaskChain item); - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs.meta deleted file mode 100644 index 38b437574..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 5a160dc164df4094dbbc892055ac82ae -timeCreated: 1520084097 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.meta deleted file mode 100644 index b816b6019..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6c7a6e7b95b40f74fa32896e23dbac93 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs deleted file mode 100644 index 2fa03e26b..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; - -namespace DepthFirstScheduler -{ - public static partial class Scheduler - { - private static IScheduler currentThread; - - public static IScheduler CurrentThread - { - get { return currentThread ?? (currentThread = new CurrentThreadScheduler()); } - } - - public class CurrentThreadScheduler : IScheduler - { - [ThreadStatic] - private static Queue queue; - - private static Queue GetQueue() - { - return queue; - } - - private static void SetQueue(Queue newQueue) - { - queue = newQueue; - } - - public void Enqueue(TaskChain item) - { - var q = GetQueue(); - - if (q == null) - { - q = new Queue(5); - q.Enqueue(item); - SetQueue(q); - - try - { - Trampoline.Run(q); - } - finally - { - SetQueue(null); - } - } - else - { - q.Enqueue(item); - } - } - - #region IDisposable Support - - private bool disposedValue = false; - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - var queue = GetQueue(); - if (queue != null) queue.Clear(); - SetQueue(null); - } - disposedValue = true; - } - } - - public void Dispose() - { - Dispose(true); - } - - #endregion - } - - static class Trampoline - { - public static void Run(Queue queue) - { - while (queue.Count > 0) - { - var chain = queue.Dequeue(); - - while (true) - { - var status = chain.Next(); - if (status != ExecutionStatus.Continue) - { - break; - } - } - } - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs.meta deleted file mode 100644 index 57b7907fd..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/CurrentThreadScheduler.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 21979cc7137a17d4ea8b6202381a02d0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs deleted file mode 100644 index e5406ebe0..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs +++ /dev/null @@ -1,52 +0,0 @@ -namespace DepthFirstScheduler -{ - public static partial class Scheduler - { - private static StepScheduler mainThread; - - public static StepScheduler MainThread - { - get - { - if (mainThread != null) return mainThread; - mainThread = new StepScheduler(); - MainThreadDispatcher.Initialize(); - return mainThread; - } - } - - public class StepScheduler : IScheduler - { - LockQueue m_taskQueue = new LockQueue(); - - public void Enqueue(TaskChain item) - { - m_taskQueue.Enqueue(item); - } - - TaskChain m_chain; - - public int UpdateAndGetTaskCount() - { - if (m_chain != null) - { - var status = m_chain.Next(); - if (status == ExecutionStatus.Continue) - { - // m_item継続中 - return m_taskQueue.Count; - } - m_chain = null; - } - - int count; - m_chain = m_taskQueue.Dequeue(out count); - return count; - } - - public void Dispose() - { - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs.meta deleted file mode 100644 index f5e8c0920..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/StepScheduler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 84161938c020c37419bc79f021f849fb -timeCreated: 1520062584 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs deleted file mode 100644 index 6c2dbea93..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; - -namespace DepthFirstScheduler -{ - public static partial class Scheduler - { - private static IScheduler threadPool; - - public static IScheduler ThreadPool - { - get { return threadPool ?? (threadPool = new ThreadPoolScheduler()); } - } - - public class ThreadPoolScheduler : IScheduler - { - public void Enqueue(TaskChain item) - { - System.Threading.ThreadPool.QueueUserWorkItem(_ => - { - if (item == null) - { - return; - } - - while (true) - { - var status = item.Next(); - if (status != ExecutionStatus.Continue) - { - break; - } - } - - }); - } - - public void Dispose() - { - } - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs.meta deleted file mode 100644 index 42a8066ec..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadPoolScheduler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: d8a8d78a486bbdf4b95ae83d02b480d8 -timeCreated: 1524110819 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs deleted file mode 100644 index 0c44c5507..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using System.Threading; - -namespace DepthFirstScheduler -{ - public static partial class Scheduler - { - private static IScheduler singleWorkerThread; - - public static IScheduler SingleWorkerThread - { - get { return singleWorkerThread ?? (singleWorkerThread = new ThreadScheduler()); } - } - - public class ThreadScheduler : IScheduler - { - MonitorQueue m_queue = new MonitorQueue(); - - Thread m_thread; - - public ThreadScheduler() - { - // start worker thread - m_thread = new Thread(new ParameterizedThreadStart(Worker)); - m_thread.Start(m_queue); - } - - static void Worker(Object arg) - { - MonitorQueue queue = (MonitorQueue)arg; - while (true) - { - var chain = queue.Dequeue(); - if (chain == null) - { - break; - } - - while (true) - { - var status = chain.Next(); - if (status != ExecutionStatus.Continue) - { - break; - } - } - } - - // end - } - - public void Enqueue(TaskChain item) - { - m_queue.Enqueue(item); - } - - #region IDisposable Support - - private bool disposedValue = false; // 重複する呼び出しを検出するには - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: マネージ状態を破棄します (マネージ オブジェクト)。 - if (m_thread != null) - { - m_queue.Enqueue(null); - m_thread.Join(); - m_thread = null; - } - } - - // TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下のファイナライザーをオーバーライドします。 - // TODO: 大きなフィールドを null に設定します。 - - disposedValue = true; - } - } - - // TODO: 上の Dispose(bool disposing) にアンマネージ リソースを解放するコードが含まれる場合にのみ、ファイナライザーをオーバーライドします。 - // ~ThreadScheduler() { - // // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 - // Dispose(false); - // } - - // このコードは、破棄可能なパターンを正しく実装できるように追加されました。 - public void Dispose() - { - // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 - Dispose(true); - // TODO: 上のファイナライザーがオーバーライドされる場合は、次の行のコメントを解除してください。 - // GC.SuppressFinalize(this); - } - - #endregion - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs.meta deleted file mode 100644 index 9e4cb5569..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Scheduler/ThreadScheduler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 8df1de98bdc0b534bbe68e8f2f8a858f -timeCreated: 1520062592 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs deleted file mode 100644 index 7e16a94e7..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; - - -namespace DepthFirstScheduler -{ - public enum ChainStatus - { - Unknown, - Continue, - Done, - Error, - } - - public class TaskChain - { - public IEnumerator Enumerator; - public Action OnError; - public ChainStatus ChainStatus; - - public static TaskChain Schedule(ISchedulable schedulable, Action onError) - { - var item = new TaskChain - { - Enumerator = schedulable.Traverse().GetEnumerator(), - OnError = onError - }; - - if (item.Enumerator.MoveNext()) - { - if (item.Enumerator.Current.Scheduler == null) - { - // default - Scheduler.MainThread.Enqueue(item); - } - else - { - item.Enumerator.Current.Scheduler.Enqueue(item); - } - } - - return item; - } - - /// - /// - /// - /// - public ExecutionStatus Next() - { - if (this.ChainStatus == ChainStatus.Done - || this.ChainStatus== ChainStatus.Error) - { - return ExecutionStatus.Done; - } - - { - var status = Enumerator.Current.Execute(); - if (status == ExecutionStatus.Error) - { - ChainStatus = ChainStatus.Error; - OnError(Enumerator.Current.GetError()); - } - if (status == ExecutionStatus.Continue) - { - // 中断(coroutine) - ChainStatus = ChainStatus.Continue; - return ExecutionStatus.Continue; - } - } - - if (!Enumerator.MoveNext()) - { - // 終了 - ChainStatus = ChainStatus.Done; - return ExecutionStatus.Done; - } - - if (Enumerator.Current.Scheduler != null) - { - // Scheduleして中断 - ChainStatus = ChainStatus.Continue; - Enumerator.Current.Scheduler.Enqueue(this); - return ExecutionStatus.Done; - } - - return Next(); - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs.meta deleted file mode 100644 index e50b9f19b..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/TaskChain.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 38fc7e076ba93a847ad72d3d459d06b6 -timeCreated: 1520084019 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs deleted file mode 100644 index fed9eb64c..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace DepthFirstScheduler -{ - [Serializable] - public struct Unit : IEquatable - { - static readonly Unit @default = new Unit(); - - public static Unit Default { get { return @default; } } - - public static bool operator ==(Unit first, Unit second) - { - return true; - } - - public static bool operator !=(Unit first, Unit second) - { - return false; - } - - public bool Equals(Unit other) - { - return true; - } - public override bool Equals(object obj) - { - return obj is Unit; - } - - public override int GetHashCode() - { - return 0; - } - - public override string ToString() - { - return "()"; - } - } -} diff --git a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs.meta b/Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs.meta deleted file mode 100644 index 24f0ea548..000000000 --- a/Assets/UniGLTF/Runtime/DepthFirstScheduler/Unit.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 98bd42f8c3a895d4bac6cbcf523878bb -timeCreated: 1520081817 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs index c5b64334e..f07f4ff63 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContext.cs @@ -5,8 +5,8 @@ using UnityEngine; using System.IO; using System.Text; using System.Collections; -using DepthFirstScheduler; using UniJSON; +using System.Threading.Tasks; #if UNITY_EDITOR using UnityEditor; #endif @@ -354,129 +354,30 @@ namespace UniGLTF public bool EnableLoadBalancing; - public virtual Schedulable LoadAsync() + public virtual async Task LoadAsync() { - return - Schedulable.Create() - .AddTask(Scheduler.ThreadPool, () => - { - // root task. do nothing - }) - .ContinueWithCoroutine(Scheduler.MainThread, () => - { - using (MeasureTime("LoadMaterials")) - { - return m_materialFactory.LoadMaterials(m_textureFactory.GetTextureAsync); - } - }) - .OnExecute(Scheduler.ThreadPool, parent => - { - // UniGLTF does not support draco - // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md#conformance - if (GLTF.extensionsRequired.Contains("KHR_draco_mesh_compression")) - { - throw new UniGLTFNotSupportedException("draco is not supported"); - } - - // meshes - var meshImporter = new MeshImporter(); - for (int i = 0; i < GLTF.meshes.Count; ++i) - { - var index = i; - parent.AddTask(Scheduler.ThreadPool, - () => - { - using (MeasureTime("ReadMesh")) - { - return meshImporter.ReadMesh(this, index); - } - }) - .ContinueWithCoroutine(Scheduler.MainThread, x => BuildMesh(x, index)) - .ContinueWith(Scheduler.ThreadPool, x => Meshes.Add(x)) - ; - } - }) - .ContinueWithCoroutine(Scheduler.MainThread, LoadNodes) - .ContinueWithCoroutine(Scheduler.MainThread, BuildHierarchy) - .ContinueWith(Scheduler.MainThread, _ => - { - using (MeasureTime("AnimationImporter")) - { - AnimationImporter.Import(this); - } - }) - .ContinueWithCoroutine(Scheduler.MainThread, OnLoadModel) - .ContinueWith(Scheduler.CurrentThread, - _ => - { - if (m_showSpeedLog) - { - Debug.Log(GetSpeedLog()); - } - return Unit.Default; - }); - } - - protected virtual IEnumerator OnLoadModel() - { - Root.name = "GLTF"; - yield break; - } - - - IEnumerator BuildMesh(MeshImporter.MeshContext x, int i) - { - using (MeasureTime("BuildMesh")) + // UniGLTF does not support draco + // https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_draco_mesh_compression/README.md#conformance + if (GLTF.extensionsRequired.Contains("KHR_draco_mesh_compression")) { - MeshWithMaterials meshWithMaterials; - if (EnableLoadBalancing) - { - var buildMesh = MeshImporter.BuildMeshCoroutine(MaterialFactory, x); - yield return buildMesh; - meshWithMaterials = buildMesh.Current as MeshWithMaterials; - } - else - { - meshWithMaterials = MeshImporter.BuildMesh(MaterialFactory, x); - } - - var mesh = meshWithMaterials.Mesh; - - // mesh name - if (string.IsNullOrEmpty(mesh.name)) - { - mesh.name = string.Format("UniGLTF import#{0}", i); - } - var originalName = mesh.name; - for (int j = 1; Meshes.Any(y => y.Mesh.name == mesh.name); ++j) - { - mesh.name = string.Format("{0}({1})", originalName, j); - } - - yield return meshWithMaterials; + throw new UniGLTFNotSupportedException("draco is not supported"); } - } - IEnumerator LoadMeshes() - { + await m_materialFactory.LoadMaterialsAsync(m_textureFactory.GetTextureAsync); + + // meshes var meshImporter = new MeshImporter(); for (int i = 0; i < GLTF.meshes.Count; ++i) { - var meshContext = meshImporter.ReadMesh(this, i); - var meshWithMaterials = MeshImporter.BuildMesh(MaterialFactory, meshContext); - var mesh = meshWithMaterials.Mesh; - if (string.IsNullOrEmpty(mesh.name)) + var index = i; + using (MeasureTime("ReadMesh")) { - mesh.name = string.Format("UniGLTF import#{0}", i); + var x = await Task.Run(() => meshImporter.ReadMesh(this, index)); + var y = await BuildMeshAsync(x, index); + Meshes.Add(y); } - Meshes.Add(meshWithMaterials); - - yield return null; } - } - IEnumerator LoadNodes() - { using (MeasureTime("LoadNodes")) { for (int i = 0; i < GLTF.nodes.Count; i++) @@ -484,12 +385,8 @@ namespace UniGLTF Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform); } } + // yield return null; - yield return null; - } - - IEnumerator BuildHierarchy() - { using (MeasureTime("BuildHierarchy")) { var nodes = new List(); @@ -517,8 +414,73 @@ namespace UniGLTF t.SetParent(Root.transform, false); } } + // yield return null; - yield return null; + using (MeasureTime("AnimationImporter")) + { + AnimationImporter.Import(this); + } + + await OnLoadModel(); + + if (m_showSpeedLog) + { + Debug.Log(GetSpeedLog()); + } + } + + protected virtual async Task OnLoadModel() + { + Root.name = "GLTF"; + } + + async Task BuildMeshAsync(MeshImporter.MeshContext x, int i) + { + using (MeasureTime("BuildMesh")) + { + MeshWithMaterials meshWithMaterials; + if (EnableLoadBalancing) + { + meshWithMaterials = await MeshImporter.BuildMeshAsync(MaterialFactory, x); + } + else + { + meshWithMaterials = MeshImporter.BuildMesh(MaterialFactory, x); + } + + var mesh = meshWithMaterials.Mesh; + + // mesh name + if (string.IsNullOrEmpty(mesh.name)) + { + mesh.name = string.Format("UniGLTF import#{0}", i); + } + var originalName = mesh.name; + for (int j = 1; Meshes.Any(y => y.Mesh.name == mesh.name); ++j) + { + mesh.name = string.Format("{0}({1})", originalName, j); + } + + return meshWithMaterials; + } + } + + IEnumerator LoadMeshes() + { + var meshImporter = new MeshImporter(); + for (int i = 0; i < GLTF.meshes.Count; ++i) + { + var meshContext = meshImporter.ReadMesh(this, i); + var meshWithMaterials = MeshImporter.BuildMesh(MaterialFactory, meshContext); + var mesh = meshWithMaterials.Mesh; + if (string.IsNullOrEmpty(mesh.name)) + { + mesh.name = string.Format("UniGLTF import#{0}", i); + } + Meshes.Add(meshWithMaterials); + + yield return null; + } } #endregion diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs index c7526278e..86ad8927d 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/ImporterContextExtensions.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections; using System.IO; -using UnityEngine; -using DepthFirstScheduler; -using System.Threading.Tasks; namespace UniGLTF { @@ -36,64 +31,17 @@ namespace UniGLTF /// public static void Load(this ImporterContext self) { - var schedulable = self.LoadAsync(); - schedulable.ExecuteAll(); - } - - public static IEnumerator LoadCoroutine(this ImporterContext self, Action onError = null) - { - return self.LoadCoroutine(() => { }, onError); - } - - public static IEnumerator LoadCoroutine(this ImporterContext self, Action onLoaded, Action onError = null) - { - if (onLoaded == null) + var tcs = new TemporarySynchronizationContext(); + using (tcs.Hijack()) { - onLoaded = () => { }; - } + var task = self.LoadAsync(); - if (onError == null) - { - onError = Debug.LogError; - } - - var schedulable = self.LoadAsync(); - foreach (var x in schedulable.GetRoot().Traverse()) - { - while (true) + while (!task.IsCompleted) { - var status = x.Execute(); - if (status != ExecutionStatus.Continue) - { - break; - } - yield return null; + // execute synchronous + tcs.ExecuteOneCallback(); } } - - onLoaded(); } - - public static void LoadAsync(this ImporterContext self, Action onLoaded, Action onError = null) - { - if (onError == null) - { - onError = Debug.LogError; - } - - self.LoadAsync() - .Subscribe(Scheduler.MainThread, - _ => onLoaded(), - onError - ); - } - -#if ((NET_4_6 || NET_STANDARD_2_0) && UNITY_2017_1_OR_NEWER && !UNITY_WEBGL) - public static async Task LoadAsyncTask(this ImporterContext self) - { - await self.LoadAsync().ToTask(); - return self.Root; - } -#endif } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs index c4e63eeb2..03d514f05 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MaterialLoader/MaterialFactory.cs @@ -70,33 +70,21 @@ namespace UniGLTF return m_materials[index]; } - public IEnumerator LoadMaterials(GetTextureAsyncFunc getTexture) + public async Task LoadMaterialsAsync(GetTextureAsyncFunc getTexture) { if (m_gltf.materials == null || m_gltf.materials.Count == 0) { - var task = CreateMaterialAsync(m_gltf, 0, getTexture); - - foreach (var x in task.AsIEnumerator()) - { - yield return x; - } - - AddMaterial(task.Result); + var material = await CreateMaterialAsync(m_gltf, 0, getTexture); + AddMaterial(material); } else { for (int i = 0; i < m_gltf.materials.Count; ++i) { - var task = CreateMaterialAsync(m_gltf, i, getTexture); - foreach (var x in task.AsIEnumerator()) - { - yield return null; - } - - AddMaterial(task.Result); + var material = await CreateMaterialAsync(m_gltf, i, getTexture); + AddMaterial(material); } } - yield return null; } 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 0f2701cc8..718838d7f 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/MeshImporter.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; +using System.Threading.Tasks; using UnityEngine; @@ -652,15 +653,15 @@ namespace UniGLTF return result; } - public static IEnumerator BuildMeshCoroutine(MaterialFactory ctx, MeshImporter.MeshContext meshContext) + public static async Task BuildMeshAsync(MaterialFactory ctx, MeshImporter.MeshContext meshContext) { var (mesh, recalculateTangents) = _BuildMesh(meshContext); if (recalculateTangents) { - yield return null; + // yield return null; mesh.RecalculateTangents(); - yield return null; + // yield return null; } // 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい @@ -670,7 +671,7 @@ namespace UniGLTF Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x)).ToArray() }; - yield return null; + // yield return null; if (meshContext.BlendShapes.Count > 0) { var emptyVertices = new Vector3[mesh.vertexCount]; @@ -680,7 +681,7 @@ namespace UniGLTF } } - yield return result; + return result; } } } diff --git a/Assets/UniGLTF/Runtime/UniGLTF/IO/TemporarySynchronizationContext.cs b/Assets/UniGLTF/Runtime/UniGLTF/IO/TemporarySynchronizationContext.cs index 836edeeaa..1e9a9c3cf 100644 --- a/Assets/UniGLTF/Runtime/UniGLTF/IO/TemporarySynchronizationContext.cs +++ b/Assets/UniGLTF/Runtime/UniGLTF/IO/TemporarySynchronizationContext.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using UnityEngine; namespace UniGLTF { @@ -15,27 +16,21 @@ namespace UniGLTF public override void Post(SendOrPostCallback d, object state) { + // Debug.Log($"Post"); m_callbacks.Enqueue(() => d(state)); } - public void ExecuteSync() + public bool ExecuteOneCallback() { - while (m_callbacks.Count > 0) + while (m_callbacks.Count == 0) { - var callback = m_callbacks.Dequeue(); - callback(); + // Debug.Log($"empty callbacks"); + return false; } - } - public IEnumerator AsCoroutine() - { - throw new NotImplementedException(); - } - - public Task AsTask() - { - // repost to SynchronizationContext.Current - throw new NotImplementedException(); + var callback = m_callbacks.Dequeue(); + callback(); + return true; } class Hijacker : IDisposable diff --git a/Assets/UniGLTF/Tests/DepthFirstScheduler.meta b/Assets/UniGLTF/Tests/DepthFirstScheduler.meta deleted file mode 100644 index adcbf986e..000000000 --- a/Assets/UniGLTF/Tests/DepthFirstScheduler.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: abe759a0ef0133e4b9e51332a2e46a6f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs b/Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs deleted file mode 100644 index 10141080b..000000000 --- a/Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs +++ /dev/null @@ -1,24 +0,0 @@ -using NUnit.Framework; -using System.Linq; - - -namespace DepthFirstScheduler -{ - public class DepthFirstScheduler - { - [Test] - public void ScheduleTreeTest() - { - var s = Schedulable.Create(); - - var tasks = s.GetRoot().Traverse().ToArray(); - Assert.AreEqual(2, tasks.Length); - - var task_int = s.AddTask(Scheduler.CurrentThread, () => 0); - task_int = task_int.ContinueWith(Scheduler.CurrentThread, _ => 1); - - var status = s.Execute(); - Assert.AreEqual(ExecutionStatus.Done, status); - } - } -} diff --git a/Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs.meta b/Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs.meta deleted file mode 100644 index 8053a0ee4..000000000 --- a/Assets/UniGLTF/Tests/DepthFirstScheduler/DepthFirstScheduler.cs.meta +++ /dev/null @@ -1,12 +0,0 @@ -fileFormatVersion: 2 -guid: 3003e87b5df13394eadfda925bb816e5 -timeCreated: 1540294752 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs index 1d4e3ac84..53f846acd 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeExporter.cs @@ -57,7 +57,9 @@ namespace VRM.Samples Debug.LogFormat("meta: title:{0}", meta.Title); // ParseしたJSONをシーンオブジェクトに変換していく - context.LoadAsync(() => OnLoaded(context)); + await context.LoadAsync(); + + OnLoaded(context); } void OnLoaded(VRMImporterContext context) diff --git a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs index e31c3ab0e..459186ead 100644 --- a/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs +++ b/Assets/VRM.Samples/Scripts/VRMRuntimeLoader.cs @@ -164,16 +164,15 @@ namespace VRM.Samples } - void LoadAsync(VRMImporterContext context) + async void LoadAsync(VRMImporterContext context) { #if true var now = Time.time; - context.LoadAsync(() => - { - var delta = Time.time - now; - Debug.LogFormat("LoadAsync {0:0.0} seconds", delta); - OnLoaded(context); - }); + await context.LoadAsync(); + + var delta = Time.time - now; + Debug.LogFormat("LoadAsync {0:0.0} seconds", delta); + OnLoaded(context); #else // ローカルファイルシステムからロードします VRMImporter.LoadVrmAsync(path, OnLoaded); diff --git a/Assets/VRM.Samples/Scripts/ViewerUI.cs b/Assets/VRM.Samples/Scripts/ViewerUI.cs index 72e0137bb..fa57f118e 100644 --- a/Assets/VRM.Samples/Scripts/ViewerUI.cs +++ b/Assets/VRM.Samples/Scripts/ViewerUI.cs @@ -310,7 +310,11 @@ namespace VRM.Samples var file = File.ReadAllBytes(path); context.ParseGlb(file); await m_texts.UpdateMetaAsync(context); +#if true + await context.LoadAsync(); +#else context.Load(); +#endif context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); diff --git a/Assets/VRM/Runtime/IO/VRMImporterContext.cs b/Assets/VRM/Runtime/IO/VRMImporterContext.cs index c15c9995c..f2560d274 100644 --- a/Assets/VRM/Runtime/IO/VRMImporterContext.cs +++ b/Assets/VRM/Runtime/IO/VRMImporterContext.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using UniGLTF; using UnityEngine; using System.IO; -using System.Collections; using UniJSON; using System.Threading.Tasks; @@ -52,38 +51,34 @@ namespace VRM } #region OnLoad - protected override IEnumerator OnLoadModel() + protected override async Task OnLoadModel() { Root.name = "VRM"; using (MeasureTime("VRM LoadMeta")) { - var task = LoadMetaAsync(); - foreach (var x in task.AsIEnumerator()) - { - yield return x; - } + await LoadMetaAsync(); } - yield return null; + // yield return null; using (MeasureTime("VRM LoadHumanoid")) { LoadHumanoid(); } - yield return null; + // yield return null; using (MeasureTime("VRM LoadBlendShapeMaster")) { LoadBlendShapeMaster(); } - yield return null; + // yield return null; using (MeasureTime("VRM LoadSecondary")) { VRMSpringUtility.LoadSecondary(Root.transform, Nodes, VRM.secondaryAnimation); } - yield return null; + // yield return null; using (MeasureTime("VRM LoadFirstPerson")) {