動いた

This commit is contained in:
ousttrue 2021-02-19 14:30:10 +09:00
parent 92ced5ea89
commit 282a81e894
15 changed files with 118 additions and 112 deletions

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 280fce2afcd83f645bdd03f9bf7875c6
guid: fb77f0e0a8472cd45a97a75e7cfbb51b
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace System.Runtime.CompilerServices
@ -16,7 +17,7 @@ namespace System.Runtime.CompilerServices
}
}
namespace UniGLTF.ExplicitTask
namespace UniGLTF.AltTask
{
public interface IAwaiter<out T> : INotifyCompletion
{
@ -29,30 +30,26 @@ namespace UniGLTF.ExplicitTask
IAwaiter<T> GetAwaiter();
}
public delegate void EnequeueCallback(Action continuation);
public class TaskQueue : IDisposable
public class TaskQueue : SynchronizationContext, IDisposable
{
[ThreadStatic]
static EnequeueCallback s_EnequeueCallback;
static TaskQueue s_queue;
public static void EnequeueCurrent(Action continuation)
public new static SynchronizationContext Current
{
if (s_EnequeueCallback == null)
get
{
System.Threading.SynchronizationContext.Current.Post(_ =>
if (s_queue == null)
{
continuation();
}, null);
}
else
{
s_EnequeueCallback(continuation);
return System.Threading.SynchronizationContext.Current;
}
else
{
return s_queue;
}
}
}
EnequeueCallback m_backup;
Queue<Action> m_tasks = new Queue<Action>();
public static TaskQueue Create()
@ -62,16 +59,12 @@ namespace UniGLTF.ExplicitTask
TaskQueue()
{
m_backup = s_EnequeueCallback;
s_EnequeueCallback = x =>
{
m_tasks.Enqueue(x);
};
s_queue = this;
}
public void Dispose()
{
s_EnequeueCallback = m_backup;
s_queue = null;
}
public bool ExecuteOneCallback()
@ -86,34 +79,6 @@ namespace UniGLTF.ExplicitTask
}
}
public class Awaiter<T> : IAwaiter<T>
{
Task<T> m_task;
public bool IsCompleted
{
get
{
return m_task.IsCompleted;
}
}
public T GetResult()
{
return m_task.Result;
}
public void OnCompleted(Action continuation)
{
TaskQueue.EnequeueCurrent(continuation);
}
public Awaiter(Task<T> task)
{
m_task = task;
}
}
public struct ExplicitTaskMethodBuilder<T>
{
// https://referencesource.microsoft.com/#mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs
@ -156,50 +121,85 @@ namespace UniGLTF.ExplicitTask
_methodBuilder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
}
public ExplicitTask<T> Task => new ExplicitTask<T>(_methodBuilder.Task);
public Awaitable<T> Task => new Awaitable<T>(_methodBuilder.Task);
}
[AsyncMethodBuilder(typeof(ExplicitTaskMethodBuilder<>))]
public struct ExplicitTask<T> : IAwaitable<T>
public struct Awaitable<T> : IAwaitable<T>
{
private Task<T> _task;
public ExplicitTask(Task<T> task) => _task = task;
public static ExplicitTask<T> Delay()
public Awaitable(Task<T> task)
{
var task = Task.FromResult<T>(default);
return new ExplicitTask<T>(task);
_task = task;
}
public bool IsCompleted => _task.IsCompleted;
public T Result => _task.Result;
public IAwaiter<T> GetAwaiter()
{
return new Awaiter<T>(_task);
return new Awaiter<T>(this);
}
public bool IsCompleted => _task.IsCompleted;
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 struct ThreadTask
public static class Awaitable
{
public static ExplicitTask<T> RunThreadAsync<T>(Func<T> callback)
public static Awaitable<T> Run<T>(Func<T> action)
{
var tcs = new TaskCompletionSource<T>();
System.Threading.ThreadPool.QueueUserWorkItem(_ =>
return new Awaitable<T>(Task.Run(action));
}
public static Awaitable<T> FromResult<T>(T result)
{
return new Awaitable<T>(Task.FromResult(result));
}
}
public class Awaiter<T> : IAwaiter<T>
{
Awaitable<T> m_task;
public bool IsCompleted
{
get
{
try
{
var t = callback();
tcs.SetResult(t);
}
catch (Exception ex)
{
tcs.SetException(ex);
}
return m_task.IsCompleted;
}
}
public T GetResult()
{
return m_task.Result;
}
public void OnCompleted(Action continuation)
{
var context = TaskQueue.Current;
this.m_task.ContinueWith(() =>
{
context.Post(_ => continuation(), null);
});
return new ExplicitTask<T>(tcs.Task);
}
public Awaiter(Awaitable<T> task)
{
m_task = task;
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: bd83742422647d4409888a3c5710c14a
guid: 58f3a0011aba9ec4cb9d57a9efd35524
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -5,14 +5,14 @@ using UnityEngine;
using System.IO;
using System.Text;
using UniJSON;
using UniGLTF.ExplicitTask;
using UniGLTF.AltTask;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UniGLTF
{
using Task = ExplicitTask<Unit>;
using Task = Awaitable<Unit>;
/// <summary>
/// GLTF importer
@ -355,7 +355,7 @@ namespace UniGLTF
public bool EnableLoadBalancing;
public virtual async Task LoadAsync(Func<Task> nextFrame = null)
public virtual async Awaitable<Unit> LoadAsync(Func<Task> nextFrame = null)
{
if (nextFrame == null)
{
@ -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);
}
@ -445,7 +445,7 @@ namespace UniGLTF
return new Unit();
}
async ExplicitTask<MeshWithMaterials> BuildMeshAsync(Func<Task> nextFrame, MeshImporter.MeshContext x, int i)
async Awaitable<MeshWithMaterials> BuildMeshAsync(Func<Task> nextFrame, MeshImporter.MeshContext x, int i)
{
using (MeasureTime("BuildMesh"))
{

View File

@ -1,5 +1,5 @@
using System.IO;
using UniGLTF.ExplicitTask;
using UniGLTF.AltTask;
namespace UniGLTF
{

View File

@ -1,9 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UniGLTF.AltTask;
namespace UniGLTF
{
@ -17,7 +16,7 @@ namespace UniGLTF
m_storage = storage;
}
public delegate Task<Material> CreateMaterialAsyncFunc(glTF glTF, int i, GetTextureAsyncFunc getTexture);
public delegate Awaitable<Material> CreateMaterialAsyncFunc(glTF glTF, int i, GetTextureAsyncFunc getTexture);
CreateMaterialAsyncFunc m_createMaterialAsync;
public CreateMaterialAsyncFunc CreateMaterialAsync
{
@ -70,7 +69,7 @@ namespace UniGLTF
return m_materials[index];
}
public async Task LoadMaterialsAsync(GetTextureAsyncFunc getTexture)
public async Awaitable<Unit> LoadMaterialsAsync(GetTextureAsyncFunc getTexture)
{
if (m_gltf.materials == null || m_gltf.materials.Count == 0)
{
@ -85,6 +84,7 @@ namespace UniGLTF
AddMaterial(material);
}
}
return new Unit();
}
public static Material CreateMaterial(int index, glTFMaterial src, string shaderName)
@ -124,7 +124,7 @@ namespace UniGLTF
}
}
public static Task<Material> DefaultCreateMaterialAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture)
public static Awaitable<Material> DefaultCreateMaterialAsync(glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (i < 0 || i >= gltf.materials.Count)

View File

@ -1,4 +1,5 @@
using System.Threading.Tasks;

using UniGLTF.AltTask;
using UnityEngine;
namespace UniGLTF
@ -42,11 +43,11 @@ namespace UniGLTF
Transparent
}
public static async Task<Material> CreateAsync(int i, glTFMaterial src, GetTextureAsyncFunc getTexture)
public static async Awaitable<Material> CreateAsync(int i, glTFMaterial src, GetTextureAsyncFunc getTexture)
{
if (getTexture == null)
{
getTexture = _ => Task.FromResult<Texture2D>(null);
getTexture = _ => Awaitable.FromResult<Texture2D>(null);
}
var material = MaterialFactory.CreateMaterial(i, src, ShaderName);

View File

@ -1,4 +1,4 @@
using System.Threading.Tasks;
using UniGLTF.AltTask;
using UnityEngine;
namespace UniGLTF
@ -7,11 +7,11 @@ namespace UniGLTF
{
public const string ShaderName = "UniGLTF/UniUnlit";
public static async Task<Material> CreateAsync(int i, glTFMaterial src, GetTextureAsyncFunc getTexture, bool hasVertexColor)
public static async Awaitable<Material> CreateAsync(int i, glTFMaterial src, GetTextureAsyncFunc getTexture, bool hasVertexColor)
{
if (getTexture == null)
{
getTexture = _ => Task.FromResult<Texture2D>(null);
getTexture = _ => Awaitable.FromResult<Texture2D>(null);
}
var material = MaterialFactory.CreateMaterial(i, src, ShaderName);

View File

@ -2,13 +2,13 @@
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using UniGLTF.ExplicitTask;
using UniGLTF.AltTask;
using UnityEngine;
namespace UniGLTF
{
using Task = ExplicitTask<Unit>;
using Task = Awaitable<Unit>;
public class MeshImporter
{
@ -654,7 +654,7 @@ namespace UniGLTF
return result;
}
public static async ExplicitTask<MeshWithMaterials> BuildMeshAsync(Func<Task> nextFrame, MaterialFactory ctx, MeshImporter.MeshContext meshContext)
public static async Awaitable<MeshWithMaterials> BuildMeshAsync(Func<Task> nextFrame, MaterialFactory ctx, MeshImporter.MeshContext meshContext)
{
var (mesh, recalculateTangents) = _BuildMesh(meshContext);

View File

@ -1,5 +1,5 @@
using System;
using System.Threading.Tasks;
using UniGLTF.AltTask;
using UnityEngine;
namespace UniGLTF
@ -24,13 +24,16 @@ namespace UniGLTF
}
}
public static async Task<Texture2D> LoadTextureAsync(glTF gltf, IStorage storage, int index)
public static async Awaitable<Texture2D> LoadTextureAsync(glTF gltf, IStorage storage, int index)
{
string m_textureName = default;
var imageIndex = gltf.GetImageIndexFromTextureIndex(index);
var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
var imageBytes = ToArray(segments);
var imageBytes = await Awaitable.Run(() =>
{
var imageIndex = gltf.GetImageIndexFromTextureIndex(index);
var segments = gltf.GetImageBytes(storage, imageIndex, out m_textureName);
return ToArray(segments);
});
//
// texture from image(png etc) bytes

View File

@ -1,12 +1,13 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UniGLTF.AltTask;
using UnityEditor;
using UnityEngine;
namespace UniGLTF
{
public delegate Task<Texture2D> GetTextureAsyncFunc(GetTextureParam param);
public delegate Awaitable<Texture2D> GetTextureAsyncFunc(GetTextureParam param);
public class TextureFactory : IDisposable
{
@ -40,7 +41,7 @@ namespace UniGLTF
Dictionary<GetTextureParam, Texture2D> m_textureCache = new Dictionary<GetTextureParam, Texture2D>();
public virtual Task<Texture2D> LoadTextureAsync(int index)
public virtual Awaitable<Texture2D> LoadTextureAsync(int index)
{
#if UNIGLTF_USE_WEBREQUEST_TEXTURELOADER
return UnityWebRequestTextureLoader.LoadTextureAsync(index);
@ -57,7 +58,7 @@ namespace UniGLTF
/// <param name="roughnessFactor">METALLIC_GLOSS_PROPの追加パラメーター</param>
/// <param name="indices">gltf の texture index</param>
/// <returns></returns>
public async Task<Texture2D> GetTextureAsync(GetTextureParam param)
public async Awaitable<Texture2D> GetTextureAsync(GetTextureParam param)
{
if (m_textureCache.TryGetValue(param, out Texture2D texture))
{

View File

@ -1,13 +1,13 @@
#pragma warning disable 0414
using System.IO;
using UniGLTF;
using UniGLTF.ExplicitTask;
using UniGLTF.AltTask;
using UnityEngine;
namespace VRM.Samples
{
using Task = ExplicitTask<Unit>;
using Task = Awaitable<Unit>;
public class VRMRuntimeLoader : MonoBehaviour
{

View File

@ -2,7 +2,7 @@
using System.IO;
using System.Linq;
using UniGLTF;
using UniGLTF.ExplicitTask;
using UniGLTF.AltTask;
using UniHumanoid;
using UnityEngine;
using UnityEngine.UI;
@ -10,7 +10,7 @@ using UnityEngine.UI;
namespace VRM.Samples
{
using Task = ExplicitTask<Unit>;
using Task = Awaitable<Unit>;
public class ViewerUI : MonoBehaviour
{

View File

@ -5,11 +5,11 @@ using UniGLTF;
using UnityEngine;
using System.IO;
using UniJSON;
using UniGLTF.ExplicitTask;
using UniGLTF.AltTask;
namespace VRM
{
using Task = ExplicitTask<Unit>;
using Task = Awaitable<Unit>;
public class VRMImporterContext : ImporterContext
{
@ -299,7 +299,7 @@ namespace VRM
public BlendShapeAvatar BlendShapeAvatar;
public VRMMetaObject Meta;
public async ExplicitTask<VRMMetaObject> ReadMetaAsync(bool createThumbnail = false)
public async Awaitable<VRMMetaObject> ReadMetaAsync(bool createThumbnail = false)
{
var meta = ScriptableObject.CreateInstance<VRMMetaObject>();
meta.name = "Meta";

View File

@ -4,6 +4,7 @@ using UnityEngine;
using System.Linq;
using System;
using System.Threading.Tasks;
using UniGLTF.AltTask;
namespace VRM
{
@ -21,7 +22,7 @@ namespace VRM
"VRM/UnlitTransparentZWrite",
};
public static async Task<Material> CreateAsync(glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
public static async Awaitable<Material> CreateAsync(glTF gltf, int m_index, glTF_VRM_Material vrmMaterial, GetTextureAsyncFunc getTexture)
{
var item = vrmMaterial;
var shaderName = item.shader;
@ -111,7 +112,7 @@ namespace VRM
m_materials = materials;
}
public Task<Material> CreateMaterial(glTF gltf, int i, GetTextureAsyncFunc getTexture)
public Awaitable<Material> CreateMaterial(glTF gltf, int i, GetTextureAsyncFunc getTexture)
{
if (i == 0 && m_materials.Count == 0)
{