mirror of
https://github.com/vrm-c/UniVRM.git
synced 2026-08-27 21:34:38 -05:00
fix
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -28,11 +29,74 @@ namespace UniGLTF.ExplicitTask
|
||||
IAwaiter<T> GetAwaiter();
|
||||
}
|
||||
|
||||
public delegate void EnequeueCallback(Action continuation);
|
||||
|
||||
public class TaskQueue : IDisposable
|
||||
{
|
||||
[ThreadStatic]
|
||||
static EnequeueCallback s_EnequeueCallback;
|
||||
|
||||
public static void EnequeueCurrent(Action continuation)
|
||||
{
|
||||
if (s_EnequeueCallback == null)
|
||||
{
|
||||
System.Threading.SynchronizationContext.Current.Post(_ =>
|
||||
{
|
||||
continuation();
|
||||
}, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_EnequeueCallback(continuation);
|
||||
}
|
||||
}
|
||||
|
||||
EnequeueCallback m_backup;
|
||||
|
||||
Queue<Action> m_tasks = new Queue<Action>();
|
||||
|
||||
public static TaskQueue Create()
|
||||
{
|
||||
return new TaskQueue();
|
||||
}
|
||||
|
||||
TaskQueue()
|
||||
{
|
||||
m_backup = s_EnequeueCallback;
|
||||
s_EnequeueCallback = x =>
|
||||
{
|
||||
m_tasks.Enqueue(x);
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
s_EnequeueCallback = m_backup;
|
||||
}
|
||||
|
||||
public bool ExecuteOneCallback()
|
||||
{
|
||||
if (m_tasks.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var task = m_tasks.Dequeue();
|
||||
task();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class Awaiter<T> : IAwaiter<T>
|
||||
{
|
||||
Task<T> m_task;
|
||||
|
||||
public bool IsCompleted => m_task.IsCompleted;
|
||||
public bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_task.IsCompleted;
|
||||
}
|
||||
}
|
||||
|
||||
public T GetResult()
|
||||
{
|
||||
@@ -41,7 +105,7 @@ namespace UniGLTF.ExplicitTask
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
continuation();
|
||||
TaskQueue.EnequeueCurrent(continuation);
|
||||
}
|
||||
|
||||
public Awaiter(Task<T> task)
|
||||
@@ -114,6 +178,29 @@ namespace UniGLTF.ExplicitTask
|
||||
{
|
||||
return new Awaiter<T>(_task);
|
||||
}
|
||||
|
||||
public bool IsCompleted => _task.IsCompleted;
|
||||
}
|
||||
|
||||
public struct ThreadTask
|
||||
{
|
||||
public static ExplicitTask<T> RunThreadAsync<T>(Func<T> callback)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<T>();
|
||||
System.Threading.ThreadPool.QueueUserWorkItem(_ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var t = callback();
|
||||
tcs.SetResult(t);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
}
|
||||
});
|
||||
return new ExplicitTask<T>(tcs.Task);
|
||||
}
|
||||
}
|
||||
|
||||
public struct Unit { }
|
||||
|
||||
@@ -383,7 +383,7 @@ namespace UniGLTF
|
||||
var index = i;
|
||||
using (MeasureTime("ReadMesh"))
|
||||
{
|
||||
var x = meshImporter.ReadMesh(this, index);
|
||||
var x= meshImporter.ReadMesh(this, index);
|
||||
var y = await BuildMeshAsync(nextFrame, x, index);
|
||||
Meshes.Add(y);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
using UniGLTF.ExplicitTask;
|
||||
|
||||
namespace UniGLTF
|
||||
{
|
||||
@@ -29,73 +27,22 @@ namespace UniGLTF
|
||||
self.Root.name = Path.GetFileNameWithoutExtension(path);
|
||||
}
|
||||
|
||||
// class TemporarySynchronizationContext : SynchronizationContext
|
||||
// {
|
||||
// Queue<Action> m_callbacks = new Queue<Action>();
|
||||
|
||||
// /// <summary>
|
||||
// /// await して中断された継続がここにくる。
|
||||
// ///
|
||||
// /// ex. await Task.Run(() =>{ /* ここ */ });
|
||||
// /// </summary>
|
||||
// /// <param name="d"></param>
|
||||
// /// <param name="state"></param>
|
||||
// public override void Post(SendOrPostCallback d, object state)
|
||||
// {
|
||||
// // Debug.Log($"Post");
|
||||
// m_callbacks.Enqueue(() => d(state));
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// 一個デキューして実行する。
|
||||
// /// Unityであれば毎フレームこのように消化しているであろう。
|
||||
// ///
|
||||
// /// https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Scripting/UnitySynchronizationContext.cs
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// public bool ExecuteOneCallback()
|
||||
// {
|
||||
// while (m_callbacks.Count == 0)
|
||||
// {
|
||||
// // Debug.Log($"empty callbacks");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// var callback = m_callbacks.Dequeue();
|
||||
// callback();
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
|
||||
/// <summary>
|
||||
/// Build unity objects from parsed gltf
|
||||
/// </summary>
|
||||
public static void Load(this ImporterContext self)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
using (var queue = TaskQueue.Create())
|
||||
{
|
||||
var task = self.LoadAsync();
|
||||
|
||||
// var tcs = new TemporarySynchronizationContext();
|
||||
|
||||
// // 元に戻すためバックアップ
|
||||
// var backup = SynchronizationContext.Current;
|
||||
// // 一時的に変更
|
||||
// SynchronizationContext.SetSynchronizationContext(tcs);
|
||||
// try
|
||||
// {
|
||||
// var task = self.LoadAsync();
|
||||
|
||||
// // 中断された await を消化する
|
||||
// while (!task.IsCompleted)
|
||||
// {
|
||||
// // execute synchronous
|
||||
// tcs.ExecuteOneCallback();
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// // 元に戻す
|
||||
// SynchronizationContext.SetSynchronizationContext(backup);
|
||||
// }
|
||||
// 中断された await を消化する
|
||||
while (!task.IsCompleted)
|
||||
{
|
||||
// execute synchronous
|
||||
queue.ExecuteOneCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user