diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs index 4ee5f2a..2ba5938 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/ContinuationQueue.cs @@ -9,6 +9,8 @@ namespace Cysharp.Threading.Tasks.Internal { const int MaxArrayLength = 0X7FEFFFFF; const int InitialSize = 16; + + readonly PlayerLoopTiming timing; SpinLock gate = new SpinLock(); bool dequing = false; @@ -19,6 +21,11 @@ namespace Cysharp.Threading.Tasks.Internal int waitingListCount = 0; Action[] waitingList = new Action[InitialSize]; + public ContinuationQueue(PlayerLoopTiming timing) + { + this.timing = timing; + } + public void Enqueue(Action continuation) { bool lockTaken = false; @@ -72,7 +79,80 @@ namespace Cysharp.Threading.Tasks.Internal waitingList = new Action[InitialSize]; } + // delegate entrypoint. public void Run() + { + // for debugging, create named stacktrace. +#if DEBUG + switch (timing) + { + case PlayerLoopTiming.Initialization: + Initialization(); + break; + case PlayerLoopTiming.LastInitialization: + LastInitialization(); + break; + case PlayerLoopTiming.EarlyUpdate: + EarlyUpdate(); + break; + case PlayerLoopTiming.LastEarlyUpdate: + LastEarlyUpdate(); + break; + case PlayerLoopTiming.FixedUpdate: + FixedUpdate(); + break; + case PlayerLoopTiming.LastFixedUpdate: + LastFixedUpdate(); + break; + case PlayerLoopTiming.PreUpdate: + PreUpdate(); + break; + case PlayerLoopTiming.LastPreUpdate: + LastPreUpdate(); + break; + case PlayerLoopTiming.Update: + Update(); + break; + case PlayerLoopTiming.LastUpdate: + LastUpdate(); + break; + case PlayerLoopTiming.PreLateUpdate: + PreLateUpdate(); + break; + case PlayerLoopTiming.LastPreLateUpdate: + LastPreLateUpdate(); + break; + case PlayerLoopTiming.PostLateUpdate: + PostLateUpdate(); + break; + case PlayerLoopTiming.LastPostLateUpdate: + LastPostLateUpdate(); + break; + default: + break; + } +#else + RunCore(); +#endif + } + + void Initialization() => RunCore(); + void LastInitialization() => RunCore(); + void EarlyUpdate() => RunCore(); + void LastEarlyUpdate() => RunCore(); + void FixedUpdate() => RunCore(); + void LastFixedUpdate() => RunCore(); + void PreUpdate() => RunCore(); + void LastPreUpdate() => RunCore(); + void Update() => RunCore(); + void LastUpdate() => RunCore(); + void PreLateUpdate() => RunCore(); + void LastPreLateUpdate() => RunCore(); + void PostLateUpdate() => RunCore(); + void LastPostLateUpdate() => RunCore(); + + [System.Diagnostics.DebuggerHidden] + void RunCore() { { bool lockTaken = false; diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs index b0c0e47..621ba5a 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs @@ -8,6 +8,7 @@ namespace Cysharp.Threading.Tasks.Internal { const int InitialSize = 16; + readonly PlayerLoopTiming timing; readonly object runningAndQueueLock = new object(); readonly object arrayLock = new object(); readonly Action unhandledExceptionCallback; @@ -17,9 +18,12 @@ namespace Cysharp.Threading.Tasks.Internal IPlayerLoopItem[] loopItems = new IPlayerLoopItem[InitialSize]; MinimumQueue waitQueue = new MinimumQueue(InitialSize); - public PlayerLoopRunner() + + + public PlayerLoopRunner(PlayerLoopTiming timing) { this.unhandledExceptionCallback = ex => Debug.LogException(ex); + this.timing = timing; } public void AddAction(IPlayerLoopItem item) @@ -55,7 +59,80 @@ namespace Cysharp.Threading.Tasks.Internal } } + // delegate entrypoint. public void Run() + { + // for debugging, create named stacktrace. +#if DEBUG + switch (timing) + { + case PlayerLoopTiming.Initialization: + Initialization(); + break; + case PlayerLoopTiming.LastInitialization: + LastInitialization(); + break; + case PlayerLoopTiming.EarlyUpdate: + EarlyUpdate(); + break; + case PlayerLoopTiming.LastEarlyUpdate: + LastEarlyUpdate(); + break; + case PlayerLoopTiming.FixedUpdate: + FixedUpdate(); + break; + case PlayerLoopTiming.LastFixedUpdate: + LastFixedUpdate(); + break; + case PlayerLoopTiming.PreUpdate: + PreUpdate(); + break; + case PlayerLoopTiming.LastPreUpdate: + LastPreUpdate(); + break; + case PlayerLoopTiming.Update: + Update(); + break; + case PlayerLoopTiming.LastUpdate: + LastUpdate(); + break; + case PlayerLoopTiming.PreLateUpdate: + PreLateUpdate(); + break; + case PlayerLoopTiming.LastPreLateUpdate: + LastPreLateUpdate(); + break; + case PlayerLoopTiming.PostLateUpdate: + PostLateUpdate(); + break; + case PlayerLoopTiming.LastPostLateUpdate: + LastPostLateUpdate(); + break; + default: + break; + } +#else + RunCore(); +#endif + } + + void Initialization() => RunCore(); + void LastInitialization() => RunCore(); + void EarlyUpdate() => RunCore(); + void LastEarlyUpdate() => RunCore(); + void FixedUpdate() => RunCore(); + void LastFixedUpdate() => RunCore(); + void PreUpdate() => RunCore(); + void LastPreUpdate() => RunCore(); + void Update() => RunCore(); + void LastUpdate() => RunCore(); + void PreLateUpdate() => RunCore(); + void LastPreLateUpdate() => RunCore(); + void PostLateUpdate() => RunCore(); + void LastPostLateUpdate() => RunCore(); + + [System.Diagnostics.DebuggerHidden] + void RunCore() { lock (runningAndQueueLock) { diff --git a/src/UniTask/Assets/Plugins/UniTask/Runtime/PlayerLoopHelper.cs b/src/UniTask/Assets/Plugins/UniTask/Runtime/PlayerLoopHelper.cs index 8be1b59..66f44d1 100644 --- a/src/UniTask/Assets/Plugins/UniTask/Runtime/PlayerLoopHelper.cs +++ b/src/UniTask/Assets/Plugins/UniTask/Runtime/PlayerLoopHelper.cs @@ -233,40 +233,40 @@ namespace Cysharp.Threading.Tasks var copyList = playerLoop.subSystemList.ToArray(); // Initialization - copyList[0].subSystemList = InsertRunner(copyList[0], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), yielders[0] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldInitialization), yielders[1] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), runners[1] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastInitialization), runners[1] = new PlayerLoopRunner()); + copyList[0].subSystemList = InsertRunner(copyList[0], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldInitialization), yielders[0] = new ContinuationQueue(PlayerLoopTiming.Initialization), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldInitialization), yielders[1] = new ContinuationQueue(PlayerLoopTiming.LastInitialization), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerInitialization), runners[1] = new PlayerLoopRunner(PlayerLoopTiming.Initialization), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastInitialization), runners[1] = new PlayerLoopRunner(PlayerLoopTiming.LastInitialization)); // EarlyUpdate - copyList[1].subSystemList = InsertRunner(copyList[1], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), yielders[2] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldEarlyUpdate), yielders[3] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), runners[2] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastEarlyUpdate), runners[3] = new PlayerLoopRunner()); + copyList[1].subSystemList = InsertRunner(copyList[1], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldEarlyUpdate), yielders[2] = new ContinuationQueue(PlayerLoopTiming.EarlyUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldEarlyUpdate), yielders[3] = new ContinuationQueue(PlayerLoopTiming.LastEarlyUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerEarlyUpdate), runners[2] = new PlayerLoopRunner(PlayerLoopTiming.EarlyUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastEarlyUpdate), runners[3] = new PlayerLoopRunner(PlayerLoopTiming.LastEarlyUpdate)); // FixedUpdate - copyList[2].subSystemList = InsertRunner(copyList[2], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), yielders[4] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldFixedUpdate), yielders[5] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), runners[4] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastFixedUpdate), runners[5] = new PlayerLoopRunner()); + copyList[2].subSystemList = InsertRunner(copyList[2], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldFixedUpdate), yielders[4] = new ContinuationQueue(PlayerLoopTiming.FixedUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldFixedUpdate), yielders[5] = new ContinuationQueue(PlayerLoopTiming.LastFixedUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerFixedUpdate), runners[4] = new PlayerLoopRunner(PlayerLoopTiming.FixedUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastFixedUpdate), runners[5] = new PlayerLoopRunner(PlayerLoopTiming.LastFixedUpdate)); // PreUpdate - copyList[3].subSystemList = InsertRunner(copyList[3], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), yielders[6] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreUpdate), yielders[7] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), runners[6] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreUpdate), runners[7] = new PlayerLoopRunner()); + copyList[3].subSystemList = InsertRunner(copyList[3], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreUpdate), yielders[6] = new ContinuationQueue(PlayerLoopTiming.PreUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreUpdate), yielders[7] = new ContinuationQueue(PlayerLoopTiming.LastPreUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreUpdate), runners[6] = new PlayerLoopRunner(PlayerLoopTiming.PreUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreUpdate), runners[7] = new PlayerLoopRunner(PlayerLoopTiming.LastPreUpdate)); // Update - copyList[4].subSystemList = InsertRunner(copyList[4], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), yielders[8] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldUpdate), yielders[9] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), runners[8] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastUpdate), runners[9] = new PlayerLoopRunner()); + copyList[4].subSystemList = InsertRunner(copyList[4], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldUpdate), yielders[8] = new ContinuationQueue(PlayerLoopTiming.Update), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldUpdate), yielders[9] = new ContinuationQueue(PlayerLoopTiming.LastUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerUpdate), runners[8] = new PlayerLoopRunner(PlayerLoopTiming.Update), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastUpdate), runners[9] = new PlayerLoopRunner(PlayerLoopTiming.LastUpdate)); // PreLateUpdate - copyList[5].subSystemList = InsertRunner(copyList[5], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), yielders[10] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreLateUpdate), yielders[11] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), runners[10] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreLateUpdate), runners[11] = new PlayerLoopRunner()); + copyList[5].subSystemList = InsertRunner(copyList[5], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPreLateUpdate), yielders[10] = new ContinuationQueue(PlayerLoopTiming.PreLateUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPreLateUpdate), yielders[11] = new ContinuationQueue(PlayerLoopTiming.LastPreLateUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerPreLateUpdate), runners[10] = new PlayerLoopRunner(PlayerLoopTiming.PreLateUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPreLateUpdate), runners[11] = new PlayerLoopRunner(PlayerLoopTiming.LastPreLateUpdate)); // PostLateUpdate - copyList[6].subSystemList = InsertRunner(copyList[6], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), yielders[12] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPostLateUpdate), yielders[13] = new ContinuationQueue(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), runners[12] = new PlayerLoopRunner(), - typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPostLateUpdate), runners[13] = new PlayerLoopRunner()); + copyList[6].subSystemList = InsertRunner(copyList[6], typeof(UniTaskLoopRunners.UniTaskLoopRunnerYieldPostLateUpdate), yielders[12] = new ContinuationQueue(PlayerLoopTiming.PostLateUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastYieldPostLateUpdate), yielders[13] = new ContinuationQueue(PlayerLoopTiming.LastPostLateUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerPostLateUpdate), runners[12] = new PlayerLoopRunner(PlayerLoopTiming.PostLateUpdate), + typeof(UniTaskLoopRunners.UniTaskLoopRunnerLastPostLateUpdate), runners[13] = new PlayerLoopRunner(PlayerLoopTiming.LastPostLateUpdate)); playerLoop.subSystemList = copyList; PlayerLoop.SetPlayerLoop(playerLoop);