예제 #1
0
 /// <summary>
 ///     Called when [pre tick].
 /// </summary>
 protected virtual void OnPreTick() => PreTick?.Invoke(this, EventArgs.Empty);
예제 #2
0
        /// <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);
                }
            }
        }