/// <summary>Updates whatever needs updating.</summary> /// <param name="gameTime">Time passed since the last call to Update.</param> protected override void Update(GameTime gameTime) { // For graph data. _watch.Restart(); // Update the rest of the game. base.Update(gameTime); // Get ingame stats, if a game is running. IManager manager = null; if (_server != null) { manager = _server.Controller.Simulation.Manager; _gameSpeedHistory.Put(_server.Controller.ActualSpeed); _gameLoadHistory.Put(_server.Controller.CurrentLoad); } else if (_client != null && _client.Controller.Session.ConnectionState == ClientState.Connected) { manager = _client.Controller.Simulation.Manager; _gameSpeedHistory.Put(_client.Controller.ActualSpeed); _gameLoadHistory.Put(_client.Controller.CurrentLoad); } if (manager != null) { _componentsHistory.Put(manager.ComponentCount); } // Update the audio engine if we have one (setting one up can cause // issues on some systems, so we have to check, because in case we // failed it will be null). if (_audioEngine != null) { _audioEngine.Update(); } // Post-update disposable of game components that were removed // from our the components list. foreach (var component in _pendingComponents) { var disposable = component as IDisposable; if (disposable != null) { (disposable).Dispose(); } } _pendingComponents.Clear(); // Grab actual graph data. _watch.Stop(); _updateHistory.Put(1000 * _watch.ElapsedTicks / (float)Stopwatch.Frequency); }
/// <summary>This is called when the game should draw itself.</summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { // For graph data. _watch.Restart(); // Fixes funny error messages due to buggy XNA, e.g. when restoring // from a minimized state. At least I couldn't reproduce it since // this line is in... I claim this to be XNA's fault because of this: // http://xboxforums.create.msdn.com/forums/t/76414.aspx GraphicsDevice.SamplerStates[1] = SamplerState.LinearClamp; // Clear screen. GraphicsDevice.Clear(Color.Black); // Draw world elements if we're in a game. if (_client != null) { _client.Controller.Draw((float)gameTime.ElapsedGameTime.TotalMilliseconds); } // Draw other stuff (GUI for example). base.Draw(gameTime); // Collect graph data. _fpsHistory.Put(1 / (float)gameTime.ElapsedGameTime.TotalSeconds); _memoryHistory.Put(GC.GetTotalMemory(false)); // Draw some debug info on top of everything. DrawDebugInfo(); // Grab actual graph data. _watch.Stop(); _drawHistory.Put(1000 * _watch.ElapsedTicks / (float)Stopwatch.Frequency); // Draw graphs after everything else, to avoid filters on the // other screen data to affect us. if (GraphsVisible) { _fpsGraph.Draw(); _updateGraph.Draw(); _drawGraph.Draw(); _memoryGraph.Draw(); _componentGraph.Draw(); _gameSpeedGraph.Draw(); _gameLoadGraph.Draw(); } }
/// <summary>Process data to build actual data points to draw the graph through, in relative values.</summary> /// <returns></returns> private void BuildCurves() { // Clear previous results. _points.Clear(); // Skip if there is no data. if (_enumerator == null) { _min = _max = _average = _now = 0; return; } // Initialize values to impossible values to override them. _min = float.PositiveInfinity; _max = float.NegativeInfinity; _now = float.NaN; // And start the average at zero, of course. _average = 0; var count = 0; // Start walking over our data source. var processed = 0; _enumerator.Reset(); while (_enumerator.MoveNext()) { var data = _enumerator.Current; // Build average based on smoothing parameter. _movingAverage.Put(data); var value = (float)_movingAverage.Mean(); if (++processed > Smoothing) { // Store value in our data point list. _points.Add(value); // Update our extrema. if (value < _min) { _min = value; } if (value > _max) { _max = value; } _average += value; ++count; _now = data; } } // Adjust maximum. if (FixedMaximum.HasValue) { _recentMax = FixedMaximum.Value; } else if (!float.IsInfinity(_max)) { if (_max > _recentMax) { _recentMax = MathHelper.Lerp(_recentMax, _max, 0.1f); } else { _recentMax = MathHelper.Lerp(_recentMax, _max, 0.01f); } } // Scale curve to fit in the graphing area. for (int i = 0, j = _points.Count; i < j; i++) { _points[i] /= _recentMax; } // Adjust average. _average /= count; }