/// <summary> /// Called when [post tick]. /// </summary> protected virtual void OnPostTick() => PostTick?.Invoke(this, EventArgs.Empty);
/// <summary> /// The method that performs ticks. This is subscribed to the Timer Elapsed event. /// </summary> private void Tick(object sender, ElapsedEventArgs args) { //===== //We use a lock and use Monitor to check if we can aquire it. We dont use lock as we want to end the execution instead of pausing it. //===== bool haveLock = false; try { Monitor.TryEnter(_tickLock, ref haveLock); //If we were not able to get the lock, return. if (!haveLock) { return; } //*** TICK BODY *** //Convert the tick delay to a float in seconds. float ticktimeinseconds = TickDelay / 1000; //This is called when we tick. PreTick?.Invoke(_session, ticktimeinseconds); //Execute any delegates that are waiting. for (int x = 0; x < SessionActionsQueue.Count; x++) { SessionAction sessionAction; while (SessionActionsQueue.TryDequeue(out sessionAction)) { sessionAction.Invoke(_session, TickDelay); } } //Check if there are any new tickables in the queue. TryDequingNewTickables(); //Execute all ticks for (int i = TickTargets.Count - 1; i >= 0; i--) { if (TickTargets[i].ShouldBeRemoved) { TickTargets.RemoveAt(i); } else { TickTargets[i].Tick(ticktimeinseconds); } } #region Low Priority //Check if we should tick low priority targets. //Increase the timer and check its value. _lowPriorityTicksPassed++; if (_lowPriorityTicksPassed >= _lowPriorityRate) { //Tick all low priority objects for (int i = LowPriorityTickTargets.Count - 1; i >= 0; i--) { if (LowPriorityTickTargets[i].ShouldBeRemoved) { LowPriorityTickTargets.RemoveAt(i); } else { LowPriorityTickTargets[i].Tick(ticktimeinseconds * _lowPriorityRate); } } //Invoke event LowPriorityTick?.Invoke(_session, ticktimeinseconds * _lowPriorityRate); //Reset counter _lowPriorityTicksPassed = 0; } #endregion //Post tick event. PostTick?.Invoke(_session, ticktimeinseconds); } catch (System.Exception e) { #if UNITY_EDITOR //Log the exception on the main thread. //Only worth doing in the editor otherwise it will never be seen in some random file. //However we still want to catch these exceptions, just do nothing. Game.CurrentSession.TaskManager.Tasks.Enqueue(() => { UnityEngine.Debug.LogError(e.Message); }); #endif } finally { if (haveLock) { Monitor.Exit(_tickLock); } } }