remove AltTask. replace IAwaitCaller

This commit is contained in:
ousttrue
2021-03-02 18:04:43 +09:00
parent 4bd37e3e19
commit f3454d55e9
25 changed files with 176 additions and 522 deletions

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: fb77f0e0a8472cd45a97a75e7cfbb51b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,12 +0,0 @@
namespace System.Runtime.CompilerServices
{
public sealed class AsyncMethodBuilderAttribute : Attribute
{
public AsyncMethodBuilderAttribute(Type builderType)
{
BuilderType = builderType;
}
public Type BuilderType { get; }
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 010eb0dc48af5e645af2ff8cb7f7d1d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,155 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace UniGLTF.AltTask
{
/// <summary>
/// Importer 向けに Task を wrap した。
///
/// * EditorやUnitTestなどで、Unity の MainLoop を進行させずに 非同期を進行させることが目的
///
/// Global変数 SynchronizationContext.Current を一時的に変更したいのだが、
/// システムに予期せぬ副作用を与える可能性があるのでこれを回避。
/// UniGLTF.AltTask.TaskQueue.Current に同じ機能を与えて、タスクのPost先を制御することにした。
/// </summary>
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<TStateMachine>(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<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
_methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
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;
if (_task.Exception != null)
{
throw _task.Exception;
}
}
public bool IsCompleted => _task.IsCompleted;
public Exception Exception => _task.Exception;
public IAwaiter GetAwaiter()
{
return new Awaiter(this);
}
public void ContinueWith(Action action)
{
_task.ContinueWith((Task, _) =>
{
action();
}, null);
}
public static Awaitable<T> Run<T>(Func<T> action)
{
return new Awaitable<T>(Task.Run(action));
}
public static Awaitable Run(Action action)
{
return new Awaitable(Task.Run(action));
}
public static Awaitable<T> FromResult<T>(T result)
{
return new Awaitable<T>(Task.FromResult(result));
}
}
public class Awaiter : IAwaiter
{
Awaitable m_task;
public bool IsCompleted
{
get
{
return m_task.IsCompleted;
}
}
public void GetResult()
{
if (m_task.Exception != null)
{
throw m_task.Exception;
}
}
public void OnCompleted(Action continuation)
{
var context = TaskQueue.Current;
this.m_task.ContinueWith(() =>
{
context.Post(_ => continuation(), null);
});
}
public Awaiter(Awaitable task)
{
m_task = task;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4a5d6155408ca734297a104d9e590d1f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,138 +0,0 @@
using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace UniGLTF.AltTask
{
public interface IAwaiter<out T> : INotifyCompletion
{
bool IsCompleted { get; }
T GetResult();
}
public interface IAwaitable<out T>
{
IAwaiter<T> GetAwaiter();
}
public struct ExplicitTaskMethodBuilder<T>
{
// https://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs
private AsyncTaskMethodBuilder<T> _methodBuilder;
public static ExplicitTaskMethodBuilder<T> Create() =>
new ExplicitTaskMethodBuilder<T> { _methodBuilder = AsyncTaskMethodBuilder<T>.Create() };
public void Start<TStateMachine>(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(T result)
{
_methodBuilder.SetResult(result);
}
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : INotifyCompletion
where TStateMachine : IAsyncStateMachine
{
_methodBuilder.AwaitOnCompleted(ref awaiter, ref stateMachine);
}
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
ref TAwaiter awaiter, ref TStateMachine stateMachine)
where TAwaiter : ICriticalNotifyCompletion
where TStateMachine : IAsyncStateMachine
{
_methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
}
public Awaitable<T> Task => new Awaitable<T>(_methodBuilder.Task);
}
[AsyncMethodBuilder(typeof(ExplicitTaskMethodBuilder<>))]
public struct Awaitable<T> : IAwaitable<T>
{
private Task<T> _task;
public Awaitable(Task<T> task)
{
_task = task;
if (_task.Exception != null)
{
throw _task.Exception;
}
}
public bool IsCompleted => _task.IsCompleted;
public T Result => _task.Result;
public Exception Exception => _task.Exception;
public IAwaiter<T> GetAwaiter()
{
return new Awaiter<T>(this);
}
public void ContinueWith(Action action)
{
_task.ContinueWith((Task, _) =>
{
action();
}, null);
}
public static Awaitable<T> Delay()
{
var task = Task.FromResult<T>(default);
return new Awaitable<T>(task);
}
}
public class Awaiter<T> : IAwaiter<T>
{
Awaitable<T> m_task;
public bool IsCompleted
{
get
{
return m_task.IsCompleted;
}
}
public T GetResult()
{
if (m_task.Exception != null)
{
throw m_task.Exception;
}
return m_task.Result;
}
public void OnCompleted(Action continuation)
{
var context = TaskQueue.Current;
this.m_task.ContinueWith(() =>
{
context.Post(_ => continuation(), null);
});
}
public Awaiter(Awaitable<T> task)
{
m_task = task;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 58f3a0011aba9ec4cb9d57a9efd35524
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,17 +0,0 @@
using System;
namespace UniGLTF.AltTask
{
public static class NextFrameAwaitable
{
// TODO
// loop スレッド使わないようにしたい
public static Awaitable Create()
{
return Awaitable.Run(() =>
{
System.Threading.Thread.Sleep(10);
});
}
}
}

View File

@@ -1,60 +0,0 @@
using System;
using System.Collections.Generic;
using System.Threading;
namespace UniGLTF.AltTask
{
public class TaskQueue : SynchronizationContext, IDisposable
{
[ThreadStatic]
static TaskQueue s_queue;
public new static SynchronizationContext Current
{
get
{
if (s_queue == null)
{
return System.Threading.SynchronizationContext.Current;
}
else
{
return s_queue;
}
}
}
public override void Post(SendOrPostCallback d, object state)
{
m_tasks.Enqueue(() => d(state));
}
Queue<Action> m_tasks = new Queue<Action>();
public static TaskQueue Create()
{
return new TaskQueue();
}
TaskQueue()
{
s_queue = this;
}
public void Dispose()
{
s_queue = null;
}
public bool ExecuteOneCallback()
{
if (m_tasks.Count == 0)
{
return false;
}
var task = m_tasks.Dequeue();
task();
return true;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6a65e00e71613c24e865e35173c30be0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
using System;
using System.Threading;
using System.Threading.Tasks;
namespace UniGLTF
{
/// <summary>
/// ImporterContext の 非同期実行 LoadAsync を補助する。
/// この関数を経由して await すること。
/// そうしないと、同期実行 Load 時にデッドロックに陥るかもしれない。
/// (SynchronizationContext に Post された 継続が再開されない)
/// </summary>
public interface IAwaitCaller
{
/// <summary>
/// フレームレートを維持するために1フレーム待つ
/// </summary>
/// <returns></returns>
Task NextFrame();
/// <summary>
/// 非同期に実行して、終了を待つ
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
Task Run(Action action);
/// <summary>
/// 非同期に実行して、終了を待つ
/// </summary>
/// <param name="action"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
Task<T> Run<T>(Func<T> action);
}
/// <summary>
/// 同期実行
/// </summary>
public struct ImmediateCaller : IAwaitCaller
{
public Task NextFrame()
{
return Task.FromResult<object>(null);
}
public Task Run(Action action)
{
action();
return Task.FromResult<object>(null);
}
public Task<T> Run<T>(Func<T> action)
{
return Task.FromResult(action());
}
}
/// <summary>
/// 非同期実行
/// </summary>
public class TaskCaller : IAwaitCaller
{
public Task NextFrame()
{
return Task.Run(() =>
{
Thread.Sleep(10);
});
}
public Task Run(Action action)
{
return Task.Run(action);
}
public Task<T> Run<T>(Func<T> action)
{
return Task.Run(action);
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 81795a4f6e605d74787f604354a8565f
guid: 9cd79193a3dfa7148bb76882f4988071
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -2,7 +2,7 @@
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UniGLTF.AltTask;
using System.Threading.Tasks;
namespace UniGLTF
{
@@ -37,6 +37,8 @@ namespace UniGLTF
TextureFactory m_textureFactory;
public TextureFactory TextureFactory => m_textureFactory;
IAwaitCaller m_awaitCaller;
public ImporterContext(GltfParser parser,
LoadTextureAsyncFunc loadTextureAsync = null,
IEnumerable<(string, UnityEngine.Object)> externalObjectMap = null)
@@ -45,11 +47,11 @@ namespace UniGLTF
if (loadTextureAsync == null)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
loadTextureAsync = (index, used) => UnityWebRequestTextureLoader.LoadTextureAsync(index);
loadTextureAsync = (awaitCaller, index, used) => UnityWebRequestTextureLoader.LoadTextureAsync(index);
#else
loadTextureAsync = async (index, used) =>
loadTextureAsync = async (awaitCaller, index, used) =>
{
var texture = await GltfTextureLoader.LoadTextureAsync(GLTF, Storage, index);
var texture = await GltfTextureLoader.LoadTextureAsync(awaitCaller, GLTF, Storage, index);
return new TextureLoadInfo(texture, used, false);
};
#endif
@@ -74,8 +76,14 @@ namespace UniGLTF
public Axises InvertAxis = Axises.Z;
#region Load. Build unity objects
public virtual async Awaitable LoadAsync(Func<string, IDisposable> MeasureTime = null)
public virtual async Task LoadAsync(IAwaitCaller awaitCaller = null, Func<string, IDisposable> MeasureTime = null)
{
if (awaitCaller == null)
{
awaitCaller = new TaskCaller();
}
m_awaitCaller = awaitCaller;
if (MeasureTime == null)
{
MeasureTime = new ImporterContextSpeedLog().MeasureTime;
@@ -108,7 +116,7 @@ namespace UniGLTF
using (MeasureTime("LoadMaterials"))
{
await m_materialFactory.LoadMaterialsAsync(m_textureFactory.GetTextureAsync);
await m_materialFactory.LoadMaterialsAsync(m_awaitCaller, m_textureFactory.GetTextureAsync);
}
var meshImporter = new MeshImporter();
@@ -130,7 +138,7 @@ namespace UniGLTF
Nodes.Add(NodeImporter.ImportNode(GLTF.nodes[i], i).transform);
}
}
await NextFrameAwaitable.Create();
await m_awaitCaller.NextFrame();
using (MeasureTime("BuildHierarchy"))
{
@@ -155,26 +163,26 @@ namespace UniGLTF
t.SetParent(Root.transform, false);
}
}
await NextFrameAwaitable.Create();
await m_awaitCaller.NextFrame();
using (MeasureTime("AnimationImporter"))
{
AnimationImporter.Import(this);
}
await OnLoadModel(MeasureTime);
await OnLoadModel(m_awaitCaller, MeasureTime);
}
protected virtual async Awaitable OnLoadModel(Func<string, IDisposable> MeasureTime)
protected virtual async Task OnLoadModel(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
{
// do nothing
}
async Awaitable<MeshWithMaterials> BuildMeshAsync(Func<string, IDisposable> MeasureTime, MeshImporter.MeshContext x, int i)
async Task<MeshWithMaterials> BuildMeshAsync(Func<string, IDisposable> MeasureTime, MeshImporter.MeshContext x, int i)
{
using (MeasureTime("BuildMesh"))
{
var meshWithMaterials = await MeshImporter.BuildMeshAsync(MaterialFactory, x);
var meshWithMaterials = await MeshImporter.BuildMeshAsync(m_awaitCaller, MaterialFactory, x);
var mesh = meshWithMaterials.Mesh;
// mesh name

View File

@@ -1,5 +1,4 @@
using System.IO;
using UniGLTF.AltTask;
using System;
using UnityEngine;
namespace UniGLTF
@@ -12,21 +11,15 @@ namespace UniGLTF
public static void Load(this ImporterContext self)
{
var meassureTime = new ImporterContextSpeedLog();
using (var queue = TaskQueue.Create())
var task = self.LoadAsync(default(ImmediateCaller), meassureTime.MeasureTime);
if (!task.IsCompleted)
{
var task = self.LoadAsync(meassureTime.MeasureTime);
// 中断された await を消化する
while (!task.IsCompleted)
{
// execute synchronous
queue.ExecuteOneCallback();
}
throw new Exception();
}
#if VRM_DEVELOP
Debug.Log(meassureTime.GetSpeedLog());
#endif
}
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UniGLTF.AltTask;
namespace UniGLTF
{
@@ -41,7 +41,7 @@ namespace UniGLTF
}
}
public delegate Awaitable<Material> CreateMaterialAsyncFunc(glTF gltf, int i, GetTextureAsyncFunc getTexture);
public delegate Task<Material> CreateMaterialAsyncFunc(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture);
CreateMaterialAsyncFunc m_createMaterialAsync;
public CreateMaterialAsyncFunc CreateMaterialAsync
{
@@ -101,12 +101,12 @@ namespace UniGLTF
/// </summary>
/// <param name="getTexture"></param>
/// <returns></returns>
public async Awaitable LoadMaterialsAsync(GetTextureAsyncFunc getTexture)
public async Task LoadMaterialsAsync(IAwaitCaller awaitCaller, GetTextureAsyncFunc getTexture)
{
if (m_gltf.materials == null || m_gltf.materials.Count == 0)
{
// no material. work around.
var material = await CreateMaterialAsync(m_gltf, 0, getTexture);
var material = await CreateMaterialAsync(awaitCaller, m_gltf, 0, getTexture);
m_materials.Add(new MaterialLoadInfo(material, false));
return;
}
@@ -119,7 +119,7 @@ namespace UniGLTF
continue;
}
material = await CreateMaterialAsync(m_gltf, i, getTexture);
material = await CreateMaterialAsync(awaitCaller, m_gltf, i, getTexture);
m_materials.Add(new MaterialLoadInfo(material, false));
}
}
@@ -161,22 +161,22 @@ namespace UniGLTF
}
}
public static Awaitable<Material> DefaultCreateMaterialAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture)
public static Task<Material> DefaultCreateMaterialAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (i < 0 || i >= gltf.materials.Count)
{
UnityEngine.Debug.LogWarning("glTFMaterial is empty");
return PBRMaterialItem.CreateAsync(gltf, i, getTexture);
return PBRMaterialItem.CreateAsync(awaitCaller, gltf, i, getTexture);
}
var x = gltf.materials[i];
if (glTF_KHR_materials_unlit.IsEnable(x))
{
var hasVertexColor = gltf.MaterialHasVertexColor(i);
return UnlitMaterialItem.CreateAsync(gltf, i, getTexture, hasVertexColor);
return UnlitMaterialItem.CreateAsync(awaitCaller, gltf, i, getTexture, hasVertexColor);
}
return PBRMaterialItem.CreateAsync(gltf, i, getTexture);
return PBRMaterialItem.CreateAsync(awaitCaller, gltf, i, getTexture);
}
/// <summary>
@@ -192,7 +192,7 @@ namespace UniGLTF
{
materials = new System.Collections.Generic.List<glTFMaterial> { material },
};
var task = DefaultCreateMaterialAsync(gltf, i, null);
var task = DefaultCreateMaterialAsync(default(ImmediateCaller), gltf, i, null);
return task.Result;
}

View File

@@ -1,5 +1,5 @@

using UniGLTF.AltTask;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
@@ -65,11 +65,11 @@ namespace UniGLTF
return GetTextureParam.CreateNormal(gltf, src.normalTexture.index);
}
public static async Awaitable<Material> CreateAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture)
public static async Task<Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (getTexture == null)
{
getTexture = (_x, _y) => Awaitable.FromResult<Texture2D>(null);
getTexture = (_x, _y, _z) => Task.FromResult<Texture2D>(null);
}
var src = gltf.materials[i];
@@ -88,7 +88,7 @@ namespace UniGLTF
if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1)
{
material.mainTexture = await getTexture(gltf, BaseColorTexture(gltf, src));
material.mainTexture = await getTexture(awaitCaller, gltf, BaseColorTexture(gltf, src));
// Texture Offset and Scale
MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex");
@@ -98,7 +98,7 @@ namespace UniGLTF
{
material.EnableKeyword("_METALLICGLOSSMAP");
var texture = await getTexture(gltf, MetallicRoughnessTexture(gltf, src));
var texture = await getTexture(awaitCaller, gltf, MetallicRoughnessTexture(gltf, src));
if (texture != null)
{
material.SetTexture(GetTextureParam.METALLIC_GLOSS_PROP, texture);
@@ -121,7 +121,7 @@ namespace UniGLTF
if (src.normalTexture != null && src.normalTexture.index != -1)
{
material.EnableKeyword("_NORMALMAP");
var texture = await getTexture(gltf, NormalTexture(gltf, src));
var texture = await getTexture(awaitCaller, gltf, NormalTexture(gltf, src));
if (texture != null)
{
material.SetTexture(GetTextureParam.NORMAL_PROP, texture);
@@ -134,7 +134,7 @@ namespace UniGLTF
if (src.occlusionTexture != null && src.occlusionTexture.index != -1)
{
var texture = await getTexture(gltf, OcclusionTexture(gltf, src));
var texture = await getTexture(awaitCaller, gltf, OcclusionTexture(gltf, src));
if (texture != null)
{
material.SetTexture(GetTextureParam.OCCLUSION_PROP, texture);
@@ -158,7 +158,7 @@ namespace UniGLTF
if (src.emissiveTexture != null && src.emissiveTexture.index != -1)
{
var texture = await getTexture(gltf, GetTextureParam.Create(gltf, src.emissiveTexture.index));
var texture = await getTexture(awaitCaller, gltf, GetTextureParam.Create(gltf, src.emissiveTexture.index));
if (texture != null)
{
material.SetTexture("_EmissionMap", texture);

View File

@@ -1,4 +1,5 @@
using UniGLTF.AltTask;

using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
@@ -7,11 +8,11 @@ namespace UniGLTF
{
public const string ShaderName = "UniGLTF/UniUnlit";
public static async Awaitable<Material> CreateAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor)
public static async Task<Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture, bool hasVertexColor)
{
if (getTexture == null)
{
getTexture = (_x, _y) => Awaitable.FromResult<Texture2D>(default);
getTexture = (_x, _y, _z) => Task.FromResult<Texture2D>(default);
}
var src = gltf.materials[i];
@@ -20,7 +21,7 @@ namespace UniGLTF
// texture
if (src.pbrMetallicRoughness.baseColorTexture != null)
{
material.mainTexture = await getTexture(gltf, GetTextureParam.Create(gltf, src.pbrMetallicRoughness.baseColorTexture.index));
material.mainTexture = await getTexture(awaitCaller, gltf, GetTextureParam.Create(gltf, src.pbrMetallicRoughness.baseColorTexture.index));
// Texture Offset and Scale
MaterialFactory.SetTextureOffsetAndScale(material, src.pbrMetallicRoughness.baseColorTexture, "_MainTex");

View File

@@ -2,7 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UniGLTF.AltTask;
using System.Threading.Tasks;
using UnityEngine;
@@ -670,15 +670,15 @@ namespace UniGLTF
}
}
public static async Awaitable<MeshWithMaterials> BuildMeshAsync(MaterialFactory ctx, MeshImporter.MeshContext meshContext)
public static async Task<MeshWithMaterials> BuildMeshAsync(IAwaitCaller awaitCaller, MaterialFactory ctx, MeshImporter.MeshContext meshContext)
{
var (mesh, recalculateTangents) = _BuildMesh(meshContext);
if (recalculateTangents)
{
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
mesh.RecalculateTangents();
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
}
// 先にすべてのマテリアルを作成済みなのでテクスチャーは生成済み。Resultを使ってよい
@@ -688,7 +688,7 @@ namespace UniGLTF
Materials = meshContext.MaterialIndices.Select(x => ctx.GetMaterial(x)).ToArray()
};
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
if (meshContext.BlendShapes.Count > 0)
{
var emptyVertices = new Vector3[mesh.vertexCount];

View File

@@ -1,5 +1,5 @@
using System;
using UniGLTF.AltTask;
using System.Threading.Tasks;
using UnityEngine;
namespace UniGLTF
@@ -24,9 +24,9 @@ namespace UniGLTF
}
}
public static async Awaitable<Texture2D> LoadTextureAsync(glTF gltf, IStorage storage, int textureIndex)
public static async Task<Texture2D> LoadTextureAsync(IAwaitCaller awaitCaller, glTF gltf, IStorage storage, int textureIndex)
{
var imageBytes = await Awaitable.Run(() =>
var imageBytes = await awaitCaller.Run(() =>
{
var imageIndex = gltf.textures[textureIndex].source;
var segments = gltf.GetImageBytes(storage, imageIndex);

View File

@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using UniGLTF.AltTask;
using UnityEngine;
using System.Linq;
using System.Threading.Tasks;
#if UNITY_EDITOR
using UnityEditor;
#endif
@@ -40,8 +40,8 @@ namespace UniGLTF
}
}
public delegate Awaitable<TextureLoadInfo> LoadTextureAsyncFunc(int index, bool used);
public delegate Awaitable<Texture2D> GetTextureAsyncFunc(glTF gltf, GetTextureParam param);
public delegate Task<TextureLoadInfo> LoadTextureAsyncFunc(IAwaitCaller awaitCaller, int index, bool used);
public delegate Task<Texture2D> GetTextureAsyncFunc(IAwaitCaller awaitCaller, glTF gltf, GetTextureParam param);
public class TextureFactory : IDisposable
{
Dictionary<string, Texture2D> m_externalMap;
@@ -97,12 +97,12 @@ namespace UniGLTF
public LoadTextureAsyncFunc LoadTextureAsync;
async Awaitable<TextureLoadInfo> GetOrCreateBaseTexture(glTF gltf, int textureIndex, bool used)
async Task<TextureLoadInfo> GetOrCreateBaseTexture(IAwaitCaller awaitCaller, glTF gltf, int textureIndex, bool used)
{
var name = gltf.textures[textureIndex].name;
if (!m_textureCache.TryGetValue(name, out TextureLoadInfo cacheInfo))
{
cacheInfo = await LoadTextureAsync(textureIndex, used);
cacheInfo = await LoadTextureAsync(awaitCaller, textureIndex, used);
m_textureCache.Add(name, cacheInfo);
}
return cacheInfo;
@@ -116,7 +116,7 @@ namespace UniGLTF
/// <param name="roughnessFactor">METALLIC_GLOSS_PROPの追加パラメーター</param>
/// <param name="indices">gltf の texture index</param>
/// <returns></returns>
public async Awaitable<Texture2D> GetTextureAsync(glTF gltf, GetTextureParam param)
public async Task<Texture2D> GetTextureAsync(IAwaitCaller awaitCaller, glTF gltf, GetTextureParam param)
{
if (m_textureCache.TryGetValue(param.Name, out TextureLoadInfo cacheInfo))
{
@@ -133,7 +133,7 @@ namespace UniGLTF
{
if (Application.isPlaying)
{
var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, false);
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false);
var converted = new NormalConverter().GetImportTexture(baseTexture.Texture);
var info = new TextureLoadInfo(converted, true, false);
m_textureCache.Add(param.Name, info);
@@ -142,7 +142,7 @@ namespace UniGLTF
else
{
#if UNITY_EDITOR
var info = await LoadTextureAsync(param.Index0.Value, true);
var info = await LoadTextureAsync(awaitCaller, param.Index0.Value, true);
var name = gltf.textures[param.Index0.Value].name;
m_textureCache.Add(name, info);
@@ -156,7 +156,7 @@ namespace UniGLTF
case GetTextureParam.METALLIC_GLOSS_PROP:
{
// Bake roughnessFactor values into a texture.
var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, false);
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false);
var converted = new MetallicRoughnessConverter(param.MetallicFactor).GetImportTexture(baseTexture.Texture);
converted.name = param.Name;
var info = new TextureLoadInfo(converted, true, false);
@@ -166,7 +166,7 @@ namespace UniGLTF
case GetTextureParam.OCCLUSION_PROP:
{
var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, false);
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, false);
var converted = new OcclusionConverter().GetImportTexture(baseTexture.Texture);
converted.name = param.Name;
var info = new TextureLoadInfo(converted, true, false);
@@ -176,7 +176,7 @@ namespace UniGLTF
default:
{
var baseTexture = await GetOrCreateBaseTexture(gltf, param.Index0.Value, true);
var baseTexture = await GetOrCreateBaseTexture(awaitCaller, gltf, param.Index0.Value, true);
return baseTexture.Texture;
}

View File

@@ -32,7 +32,7 @@ namespace UniGLTF
}
}
string m_textureName;
string m_textureName = default;
public void ProcessOnAnyThread()
{
}

View File

@@ -1,8 +1,8 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UniGLTF;
using UniGLTF.AltTask;
using UniHumanoid;
using UnityEngine;
using UnityEngine.UI;
@@ -87,9 +87,9 @@ namespace VRM.Samples
m_textDistributionOther.text = "";
}
public async Awaitable UpdateMetaAsync(VRMImporterContext context)
public async Task UpdateMetaAsync(VRMImporterContext context)
{
var meta = await context.ReadMetaAsync(true);
var meta = await context.ReadMetaAsync(default(TaskCaller), true);
m_textModelTitle.text = meta.Title;
m_textModelVersion.text = meta.Version;

View File

@@ -51,7 +51,7 @@ namespace VRM
var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab");
// save texture assets !
LoadTextureAsyncFunc textureLoader = async (textureIndex, used) =>
LoadTextureAsyncFunc textureLoader = async (caller, textureIndex, used) =>
{
var gltfTexture = parser.GLTF.textures[textureIndex];
var gltfImage = parser.GLTF.images[gltfTexture.source];

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
using UniGLTF;
using UnityEngine;
using UniJSON;
using UniGLTF.AltTask;
using System.Threading.Tasks;
namespace VRM
{
@@ -21,7 +21,7 @@ namespace VRM
{
VRM = vrm;
// override material importer
MaterialFactory.CreateMaterialAsync = new VRMMaterialImporter(VRM.materialProperties).CreateMaterial;
MaterialFactory.CreateMaterialAsync = new VRMMaterialImporter(VRM.materialProperties).CreateMaterialAsync;
}
else
{
@@ -30,7 +30,7 @@ namespace VRM
}
#region OnLoad
protected override async Awaitable OnLoadModel(Func<string, IDisposable> MeasureTime)
protected override async Task OnLoadModel(IAwaitCaller awaitCaller, Func<string, IDisposable> MeasureTime)
{
Root.name = "VRM";
@@ -38,26 +38,26 @@ namespace VRM
{
await LoadMetaAsync();
}
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
using (MeasureTime("VRM LoadHumanoid"))
{
LoadHumanoid();
}
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
using (MeasureTime("VRM LoadBlendShapeMaster"))
{
LoadBlendShapeMaster();
}
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
using (MeasureTime("VRM LoadSecondary"))
{
VRMSpringUtility.LoadSecondary(Root.transform, Nodes,
VRM.secondaryAnimation);
}
await NextFrameAwaitable.Create();
await awaitCaller.NextFrame();
using (MeasureTime("VRM LoadFirstPerson"))
{
@@ -65,7 +65,7 @@ namespace VRM
}
}
async Awaitable LoadMetaAsync()
async Task LoadMetaAsync()
{
var meta = await ReadMetaAsync();
var _meta = Root.AddComponent<VRMMeta>();
@@ -273,8 +273,13 @@ namespace VRM
public BlendShapeAvatar BlendShapeAvatar;
public VRMMetaObject Meta;
public async Awaitable<VRMMetaObject> ReadMetaAsync(bool createThumbnail = false)
public async Task<VRMMetaObject> ReadMetaAsync(IAwaitCaller awaitCaller = null, bool createThumbnail = false)
{
if (awaitCaller == null)
{
awaitCaller = default(ImmediateCaller);
}
var meta = ScriptableObject.CreateInstance<VRMMetaObject>();
meta.name = "Meta";
meta.ExporterVersion = VRM.exporterVersion;
@@ -285,7 +290,7 @@ namespace VRM
meta.ContactInformation = gltfMeta.contactInformation;
meta.Reference = gltfMeta.reference;
meta.Title = gltfMeta.title;
meta.Thumbnail = await TextureFactory.GetTextureAsync(GLTF, GetTextureParam.Create(GLTF, gltfMeta.texture));
meta.Thumbnail = await TextureFactory.GetTextureAsync(awaitCaller, GLTF, GetTextureParam.Create(GLTF, gltfMeta.texture));
meta.AllowedUser = gltfMeta.allowedUser;
meta.ViolentUssage = gltfMeta.violentUssage;
meta.SexualUssage = gltfMeta.sexualUssage;

View File

@@ -4,7 +4,6 @@ using UnityEngine;
using System.Linq;
using System;
using System.Threading.Tasks;
using UniGLTF.AltTask;
namespace VRM
{
@@ -22,7 +21,7 @@ namespace VRM
"VRM/UnlitTransparentZWrite",
};
public static async Awaitable<Material> CreateAsync(glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
public static async Task<Material> CreateAsync(IAwaitCaller awaitCaller, glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
{
var item = vrmMaterial;
var shaderName = item.shader;
@@ -40,7 +39,7 @@ namespace VRM
{
Debug.LogWarningFormat("unknown shader {0}.", shaderName);
}
return await MaterialFactory.DefaultCreateMaterialAsync(gltf, m_index, getTexture);
return await MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, gltf, m_index, getTexture);
}
//
@@ -72,7 +71,7 @@ namespace VRM
foreach (var kv in item.textureProperties)
{
var param = GetTextureParam.Create(gltf, kv.Value, kv.Key);
var texture = await getTexture(gltf, param);
var texture = await getTexture(awaitCaller, gltf, param);
if (texture != null)
{
material.SetTexture(kv.Key, texture);
@@ -113,15 +112,15 @@ namespace VRM
m_materials = materials;
}
public Awaitable<Material> CreateMaterial(glTF gltf, int i, GetTextureAsyncFunc getTexture)
public Task<Material> CreateMaterialAsync(IAwaitCaller awaitCaller, glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (i == 0 && m_materials.Count == 0)
{
// dummy
return MaterialFactory.DefaultCreateMaterialAsync(gltf, i, getTexture);
return MaterialFactory.DefaultCreateMaterialAsync(awaitCaller, gltf, i, getTexture);
}
return MToonMaterialItem.CreateAsync(gltf, i, m_materials[i], getTexture);
return MToonMaterialItem.CreateAsync(awaitCaller, gltf, i, m_materials[i], getTexture);
}
}
}