diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/AsyncAwaitUtil.asmdef b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/AsyncAwaitUtil.asmdef new file mode 100644 index 0000000..9f2f05c --- /dev/null +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/AsyncAwaitUtil.asmdef @@ -0,0 +1,20 @@ +{ + "name": "AsyncAwaitUtil", + "references": [ + "GUID:478a2357cc57436488a56e564b08d223" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.editorcoroutines", + "expression": "0.0.2-preview", + "define": "HAVE_EDITOR_COROUTINES" + } + ] +} \ No newline at end of file diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/AsyncAwaitUtil.asmdef.meta b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/AsyncAwaitUtil.asmdef.meta new file mode 100644 index 0000000..04d7208 --- /dev/null +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/AsyncAwaitUtil.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 77496ac4da31e304f9e7872e863b54e8 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/AsyncCoroutineRunner.cs b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/AsyncCoroutineRunner.cs index a3f5d6a..51dc734 100644 --- a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/AsyncCoroutineRunner.cs +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/AsyncCoroutineRunner.cs @@ -1,19 +1,49 @@ using System; using System.Collections; -using System.Collections.Generic; -using System.Linq; + using UnityEngine; +#if UNITY_EDITOR && HAVE_EDITOR_COROUTINES +using Unity.EditorCoroutines.Editor; +#endif namespace UnityAsyncAwaitUtil { - public class AsyncCoroutineRunner : MonoBehaviour + public class AsyncCoroutineRunner : MonoBehaviour, AsyncCoroutineRunner.ICoroutineRunner { - static AsyncCoroutineRunner _instance; + public interface ICoroutineRunner + { + object StartCoroutine(IEnumerator routine); + } + +#if UNITY_EDITOR + class EditorAsyncCoroutineRunner : ICoroutineRunner + { + object ICoroutineRunner.StartCoroutine(IEnumerator routine) + { +#if HAVE_EDITOR_COROUTINES + return EditorCoroutineUtility.StartCoroutine(routine, this); +#elif UNITY_2019_1_OR_NEWER + throw new NotImplementedException("Install package com.unity.editorcoroutines"); +#else + // asmdef "Version Defines" support doesn't exist yet + throw new NotImplementedException("Install package com.unity.editorcoroutines and define HAVE_EDITOR_COROUTINES"); +#endif + } + } +#endif + + static ICoroutineRunner _instance; - public static AsyncCoroutineRunner Instance + public static ICoroutineRunner Instance { get { +#if UNITY_EDITOR + if (_instance == null && !Application.isPlaying) + { + _instance = new EditorAsyncCoroutineRunner(); + } +#endif if (_instance == null) { _instance = new GameObject("AsyncCoroutineRunner") @@ -31,5 +61,10 @@ void Awake() DontDestroyOnLoad(gameObject); } + + object ICoroutineRunner.StartCoroutine(IEnumerator routine) + { + return StartCoroutine(routine); + } } -} +} \ No newline at end of file diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/SyncContextUtil.cs b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/SyncContextUtil.cs index 3d505a4..2b21b79 100644 --- a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/SyncContextUtil.cs +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Source/Internal/SyncContextUtil.cs @@ -10,6 +10,9 @@ namespace UnityAsyncAwaitUtil { public static class SyncContextUtil { +#if UNITY_EDITOR + [UnityEditor.InitializeOnLoadMethod] +#endif [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void Install() { diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor.meta b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor.meta new file mode 100644 index 0000000..d5ba2ab --- /dev/null +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 94b93817f8792fd45835bebba406b814 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor/TestMisc.cs b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor/TestMisc.cs new file mode 100644 index 0000000..a774905 --- /dev/null +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor/TestMisc.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.ExceptionServices; +using System.Threading.Tasks; + +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace UnityAsyncAwaitUtil +{ + class TestMisc + { + // Helper for writing async editor tests. + static IEnumerator AsUnityTest(Func body) + { + var task = Task.Run(body); + while (!task.IsCompleted) + { + yield return null; + } + if (task.IsFaulted) + { + ExceptionDispatchInfo.Capture(task.Exception.InnerExceptions[0]).Throw(); + } + } + + [UnityTest] + public IEnumerator TestAsyncCoroutineRunnerInEditor() + { + List result = new List(); + IEnumerator AppendResult() + { + yield return null; + result.Add(true); + } + AsyncCoroutineRunner.Instance.StartCoroutine(AppendResult()); + for (int i = 0; i < 10; ++i) + { + if (result.Count > 0) { yield break; } + yield return null; + } + Assert.Fail("Coroutine did not complete in the allotted time"); + } + + + [UnityTest] + public IEnumerator TestAwaitSecondsRealtime() => AsUnityTest(async () => + { + const float delay = .25f; + var start = DateTime.Now; + await new WaitForSecondsRealtime(delay); + Assert.Greater(DateTime.Now - start, TimeSpan.FromSeconds(delay - .01)); + }); + } +} diff --git a/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor/TestMisc.cs.meta b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor/TestMisc.cs.meta new file mode 100644 index 0000000..466b0c0 --- /dev/null +++ b/UnityProject/Assets/Plugins/AsyncAwaitUtil/Tests/Editor/TestMisc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 33b332b97e3f8004ab233b5da2bfa109 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: