using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using Unity.Collections; using Unity.Jobs; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; public struct MyJob : IJob { public int loopCount; public NativeArray inOut; public int result; public void Execute() { result = 0; for (int i = 0; i < loopCount; i++) { result++; } inOut[0] = result; } } public class SandboxMain : MonoBehaviour { public Button okButton; public Button cancelButton; public Text text; CancellationTokenSource cts; UniTaskCompletionSource ucs; async UniTask RunStandardDelayAsync() { UnityEngine.Debug.Log("DEB"); await UniTask.DelayFrame(30); UnityEngine.Debug.Log("DEB END"); } async UniTask RunJobAsync() { var job = new MyJob() { loopCount = 999, inOut = new NativeArray(1, Allocator.TempJob) }; JobHandle.ScheduleBatchedJobs(); var scheduled = job.Schedule(); UnityEngine.Debug.Log("OK"); await scheduled; // .ConfigureAwait(PlayerLoopTiming.Update); // .WaitAsync(PlayerLoopTiming.Update); UnityEngine.Debug.Log("OK2"); job.inOut.Dispose(); } void Start() { Application.SetStackTraceLogType(LogType.Error, StackTraceLogType.Full); Application.SetStackTraceLogType(LogType.Exception, StackTraceLogType.Full); var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetCurrentPlayerLoop(); ShowPlayerLoop.DumpPlayerLoop("Current", playerLoop); RunStandardDelayAsync().Forget(); //for (int i = 0; i < 14; i++) //{ // TimingDump((PlayerLoopTiming)i).Forget(); //} //StartCoroutine(CoroutineDump("yield WaitForEndOfFrame", new WaitForEndOfFrame())); //StartCoroutine(CoroutineDump("yield WaitForFixedUpdate", new WaitForFixedUpdate())); //StartCoroutine(CoroutineDump("yield null", null)); // ----- RunJobAsync().Forget(); //var cor = UniTask.ToCoroutine(async () => // { // var job = new MyJob() { loopCount = 999, inOut = new NativeArray(1, Allocator.TempJob) }; // JobHandle.ScheduleBatchedJobs(); // await job.Schedule().WaitAsync(PlayerLoopTiming.Update); // job.inOut.Dispose(); // }); //StartCoroutine(cor); Application.logMessageReceived += Application_logMessageReceived; ucs = new UniTaskCompletionSource(); okButton.onClick.AddListener(async () => { await InnerAsync(false); }); cancelButton.onClick.AddListener(async () => { text.text = ""; // ucs.TrySetResult(); await ucs.Task; }); } async UniTask SimpleAwait() { await UniTask.Yield(); await UniTask.Yield(); await UniTask.Yield(); throw new InvalidOperationException("bar!!!"); } IEnumerator SimpleCoroutine() { yield return null; yield return null; yield return null; throw new InvalidOperationException("foo!!!"); } async UniTask TimingDump(PlayerLoopTiming timing) { while (true) { await UniTask.Yield(timing); Debug.Log("PlayerLoopTiming." + timing); } } IEnumerator CoroutineDump(string msg, YieldInstruction waitObj) { while (true) { yield return waitObj; Debug.Log(msg); } } //private void Update() //{ // Debug.Log("Update"); //} //private void LateUpdate() //{ // Debug.Log("LateUpdate"); //} //private void FixedUpdate() //{ // Debug.Log("FixedUpdate"); //} private void Application_logMessageReceived(string condition, string stackTrace, LogType type) { text.text += "\n" + condition; } async UniTask OuterAsync(bool b) { UnityEngine.Debug.Log("START OUTER"); await InnerAsync(b); await InnerAsync(b); UnityEngine.Debug.Log("END OUTER"); // throw new InvalidOperationException("NAZO ERROR!?"); // error!? } async UniTask InnerAsync(bool b) { if (b) { UnityEngine.Debug.Log("Start delay:" + Time.frameCount); await UniTask.DelayFrame(60); UnityEngine.Debug.Log("End delay:" + Time.frameCount); await UniTask.DelayFrame(60); UnityEngine.Debug.Log("Onemore end delay:" + Time.frameCount); } else { UnityEngine.Debug.Log("Empty END"); throw new InvalidOperationException("FOOBARBAZ"); } } /* PlayerLoopTiming.Initialization PlayerLoopTiming.LastInitialization PlayerLoopTiming.EarlyUpdate PlayerLoopTiming.LastEarlyUpdate PlayerLoopTiming.PreUpdate PlayerLoopTiming.LastPreUpdate PlayerLoopTiming.Update Update yield null yield WaitForSeconds yield WWW yield StartCoroutine PlayerLoopTiming.LastUpdate PlayerLoopTiming.PreLateUpdate LateUpdate PlayerLoopTiming.LastPreLateUpdate PlayerLoopTiming.PostLateUpdate PlayerLoopTiming.LastPostLateUpdate yield WaitForEndOfFrame // --- Physics Loop PlayerLoopTiming.FixedUpdate FixedUpdate yield WaitForFixedUpdate PlayerLoopTiming.LastFixedUpdate */ private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) { // e.SetObserved(); // or other custom write code. UnityEngine.Debug.LogError("Unobserved:" + e.Exception.ToString()); } } public class ShowPlayerLoop { [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] static void Init() { var playerLoop = UnityEngine.LowLevel.PlayerLoop.GetDefaultPlayerLoop(); DumpPlayerLoop("Default", playerLoop); } public static void DumpPlayerLoop(string which, UnityEngine.LowLevel.PlayerLoopSystem playerLoop) { var sb = new StringBuilder(); sb.AppendLine($"{which} PlayerLoop List"); foreach (var header in playerLoop.subSystemList) { sb.AppendFormat("------{0}------", header.type.Name); sb.AppendLine(); foreach (var subSystem in header.subSystemList) { sb.AppendFormat("{0}.{1}", header.type.Name, subSystem.type.Name); sb.AppendLine(); if (subSystem.subSystemList != null) { UnityEngine.Debug.LogWarning("More Subsystem:" + subSystem.subSystemList.Length); } } } UnityEngine.Debug.Log(sb.ToString()); } }