Example #1
0
        public void BackgroundUpdate(object sender, DoWorkEventArgs e)
        {
            Log.Out("[WalkerSim] Worker Start");

            MicroStopwatch updateWatch = new MicroStopwatch();

            updateWatch.Start();

            MicroStopwatch frameWatch = new MicroStopwatch();

            double totalElapsed = 0.0;
            double dtAverage    = 0.0;
            double nextReport   = 10.0;
            float  updateRate   = 1.0f / (float)_config.UpdateInterval;

            BackgroundWorker worker = sender as BackgroundWorker;

            while (worker.CancellationPending == false)
            {
                bool isPaused = !(_playerZones.HasPlayers() || !_config.PauseWithoutPlayers);

                double dt = updateWatch.ElapsedMicroseconds / 1000000.0;
                updateWatch.ResetAndRestart();

                totalElapsed += dt;

                if (!isPaused)
                {
                    dtAverage += dt;
                    dtAverage *= 0.5;

                    double dtScaled = dt;
                    dtScaled     *= _timeScale;
                    _accumulator += dtScaled;
                }
                else
                {
                    dtAverage = 0.0;
                }

                _server.Update();

                if (_accumulator < updateRate)
                {
                    if (isPaused)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                    else
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                }
                else
                {
                    frameWatch.ResetAndRestart();

                    try
                    {
                        while (_accumulator >= updateRate)
                        {
                            var world = GameManager.Instance.World;
                            if (world == null)
                            {
                                // Work-around for client only support, some events are skipped like for when the player exits.
                                Log.Out("[WalkerSim] World no longer exists, stopping simulation");
                                _worker.CancelAsync();
                                break;
                            }

                            _accumulator -= updateRate;

                            // Prevent long updates in case the timescale is cranked up.
                            if (frameWatch.ElapsedMilliseconds >= 66)
                            {
                                break;
                            }

                            UpdateInactiveZombies(updateRate);
                        }
                    }
                    catch (Exception ex)
                    {
                        //Log.Out("Exception in worker: {0}", ex.Message);
                        Log.Error("[WalkerSim] Exception in worker");
                        Log.Exception(ex);
                    }
                }

                BroadcastMapData();

                if (totalElapsed >= nextReport && !isPaused)
                {
                    double avgFps = 1 / dtAverage;
                    if (avgFps < (1.0f / updateRate))
                    {
                        Log.Warning("[WalkerSim] Detected bad performance, FPS Average: {0}", avgFps);
                    }
                    nextReport = totalElapsed + 60.0;
                }
            }

            Log.Out("[WalkerSim] Worker Finished");
            _running = false;
        }
Example #2
0
        public void BackgroundUpdate(object sender, DoWorkEventArgs e)
        {
            Logger.Info("Worker Start");

            MicroStopwatch updateWatch = new MicroStopwatch();

            updateWatch.Start();

            MicroStopwatch frameWatch = new MicroStopwatch();

            double totalElapsed = 0.0;
            double dtAverage    = 0.0;
            double nextReport   = 10.0;
            float  updateRate   = 1.0f / (float)Config.Instance.UpdateInterval;

            var worker = (BackgroundWorker)sender;

            while (worker.CancellationPending == false)
            {
#if DEBUG
                bool isPaused = false;
#else
                bool isPaused = !(_playerZones.HasPlayers() || !Config.Instance.PauseWithoutPlayers);
#endif
                if (Config.Instance.PauseDuringBloodmon && _state.IsBloodMoon)
                {
                    isPaused = true;
                }

                double dt = updateWatch.ElapsedMicroseconds / 1000000.0;
                updateWatch.ResetAndRestart();

                totalElapsed += dt;

                if (!isPaused)
                {
                    dtAverage += dt;
                    dtAverage *= 0.5;

                    double dtScaled = dt;
                    dtScaled     *= _state.Timescale;
                    _accumulator += dtScaled;
                }
                else
                {
                    dtAverage = 0.0;
                    lock (_worldEvents)
                    {
                        // Don't accumulate world events while paused.
                        _worldEvents.Clear();
                    }
                }

                _server.Update();

                if (_accumulator < updateRate)
                {
                    System.Threading.Thread.Sleep(isPaused ? 100 : 1);
                }
                else
                {
                    frameWatch.ResetAndRestart();

                    try
                    {
                        while (_accumulator >= updateRate)
                        {
                            var world = GameManager.Instance.World;
                            if (world == null)
                            {
                                // Work-around for client only support, some events are skipped like for when the player exits.
                                Logger.Info("World no longer exists, stopping simulation");
                                _worker.CancelAsync();
                                break;
                            }

                            _accumulator -= updateRate;

                            // Prevent long updates in case the timescale is cranked up.
                            if (frameWatch.ElapsedMilliseconds >= 66)
                            {
                                break;
                            }

                            UpdateInactiveZombies(updateRate);
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Exception in worker");
                        Log.Exception(ex);
                    }
                }

                lock (_server)
                {
                    SendPlayerZones(_server, null);
                    SendInactiveZombieList(_server, null);
                    SendActiveZombieList(_server, null);
                }

                if (totalElapsed >= nextReport && !isPaused)
                {
                    double avgFps = 1 / dtAverage;
                    if (avgFps < (1.0f / updateRate))
                    {
                        Logger.Warning("Detected bad performance, FPS Average: {0}", avgFps);
                    }
                    nextReport = totalElapsed + 60.0;
                }
            }

            Logger.Info("Worker Finished");
            _running = false;
        }