| #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member | 
|   | 
| using System; | 
| using System.Threading; | 
|   | 
| namespace Cysharp.Threading.Tasks.Internal | 
| { | 
|     internal sealed class ContinuationQueue | 
|     { | 
|         const int MaxArrayLength = 0X7FEFFFFF; | 
|         const int InitialSize = 16; | 
|   | 
|         readonly PlayerLoopTiming timing; | 
|   | 
|         SpinLock gate = new SpinLock(false); | 
|         bool dequing = false; | 
|   | 
|         int actionListCount = 0; | 
|         Action[] actionList = new Action[InitialSize]; | 
|   | 
|         int waitingListCount = 0; | 
|         Action[] waitingList = new Action[InitialSize]; | 
|   | 
|         public ContinuationQueue(PlayerLoopTiming timing) | 
|         { | 
|             this.timing = timing; | 
|         } | 
|   | 
|         public void Enqueue(Action continuation) | 
|         { | 
|             bool lockTaken = false; | 
|             try | 
|             { | 
|                 gate.Enter(ref lockTaken); | 
|   | 
|                 if (dequing) | 
|                 { | 
|                     // Ensure Capacity | 
|                     if (waitingList.Length == waitingListCount) | 
|                     { | 
|                         var newLength = waitingListCount * 2; | 
|                         if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength; | 
|   | 
|                         var newArray = new Action[newLength]; | 
|                         Array.Copy(waitingList, newArray, waitingListCount); | 
|                         waitingList = newArray; | 
|                     } | 
|                     waitingList[waitingListCount] = continuation; | 
|                     waitingListCount++; | 
|                 } | 
|                 else | 
|                 { | 
|                     // Ensure Capacity | 
|                     if (actionList.Length == actionListCount) | 
|                     { | 
|                         var newLength = actionListCount * 2; | 
|                         if ((uint)newLength > MaxArrayLength) newLength = MaxArrayLength; | 
|   | 
|                         var newArray = new Action[newLength]; | 
|                         Array.Copy(actionList, newArray, actionListCount); | 
|                         actionList = newArray; | 
|                     } | 
|                     actionList[actionListCount] = continuation; | 
|                     actionListCount++; | 
|                 } | 
|             } | 
|             finally | 
|             { | 
|                 if (lockTaken) gate.Exit(false); | 
|             } | 
|         } | 
|   | 
|         public int Clear() | 
|         { | 
|             var rest = actionListCount + waitingListCount; | 
|   | 
|             actionListCount = 0; | 
|             actionList = new Action[InitialSize]; | 
|   | 
|             waitingListCount = 0; | 
|             waitingList = new Action[InitialSize]; | 
|   | 
|             return rest; | 
|         } | 
|   | 
|         // 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; | 
| #if UNITY_2020_2_OR_NEWER | 
|                 case PlayerLoopTiming.TimeUpdate: | 
|                     TimeUpdate(); | 
|                     break; | 
|                 case PlayerLoopTiming.LastTimeUpdate: | 
|                     LastTimeUpdate(); | 
|                     break; | 
| #endif | 
|                 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(); | 
| #if UNITY_2020_2_OR_NEWER | 
|         void TimeUpdate() => RunCore(); | 
|         void LastTimeUpdate() => RunCore(); | 
| #endif | 
|   | 
|         [System.Diagnostics.DebuggerHidden] | 
|         void RunCore() | 
|         { | 
|             { | 
|                 bool lockTaken = false; | 
|                 try | 
|                 { | 
|                     gate.Enter(ref lockTaken); | 
|                     if (actionListCount == 0) return; | 
|                     dequing = true; | 
|                 } | 
|                 finally | 
|                 { | 
|                     if (lockTaken) gate.Exit(false); | 
|                 } | 
|             } | 
|   | 
|             for (int i = 0; i < actionListCount; i++) | 
|             { | 
|   | 
|                 var action = actionList[i]; | 
|                 actionList[i] = null; | 
|                 try | 
|                 { | 
|                     action(); | 
|                 } | 
|                 catch (Exception ex) | 
|                 { | 
|                     UnityEngine.Debug.LogException(ex); | 
|                 } | 
|             } | 
|   | 
|             { | 
|                 bool lockTaken = false; | 
|                 try | 
|                 { | 
|                     gate.Enter(ref lockTaken); | 
|                     dequing = false; | 
|   | 
|                     var swapTempActionList = actionList; | 
|   | 
|                     actionListCount = waitingListCount; | 
|                     actionList = waitingList; | 
|   | 
|                     waitingListCount = 0; | 
|                     waitingList = swapTempActionList; | 
|                 } | 
|                 finally | 
|                 { | 
|                     if (lockTaken) gate.Exit(false); | 
|                 } | 
|             } | 
|         } | 
|     } | 
| } |