]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix the sensor monitoring console forcing a GC every 3 seconds (#38146)
authorArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Fri, 27 Jun 2025 11:37:00 +0000 (04:37 -0700)
committerGitHub <noreply@github.com>
Fri, 27 Jun 2025 11:37:00 +0000 (13:37 +0200)
* Optimize sensor monitoring window graph drawing

* Add shared static Vector2 pool for all GraphView instances

* Address requested changes

* remove lock

Content.Client/SensorMonitoring/SensorMonitoringWindow.xaml.cs

index 717ab4076559a367a4a5b487ef537a978bd15c50..e833e7d7a998678205870177c34926e848f87dbf 100644 (file)
@@ -25,6 +25,29 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
     private TimeSpan _retentionTime;
     private readonly Dictionary<int, SensorData> _sensorData = new();
 
+    /// <summary>
+    /// <para>A shared array used to store vertices for drawing graphs in <see cref="GraphView"/>.
+    /// Prevents excessive allocations by reusing the same array across multiple graph views.</para>
+    /// <para>This effectively makes it so that each <see cref="SensorMonitoringWindow"/> has its own pooled array.</para>
+    /// </summary>
+    private Vector2[] _sharedVertices = [];
+
+    /// <summary>
+    /// Retrieves a shared array of vertices, ensuring that it has at least the requested size.
+    /// Assigns a new array of the requested size if the current shared array is smaller than the requested size.
+    /// </summary>
+    /// <param name="requestedSize">The minimum number of vertices required in the shared array.</param>
+    /// <returns>An array of <see cref="System.Numerics.Vector2"/> representing the shared vertices.</returns>
+    /// <remarks>This does not prevent other threads from accessing the same shared pool.</remarks>
+    public Vector2[] GetSharedVertices(int requestedSize)
+    {
+        if (_sharedVertices.Length < requestedSize)
+        {
+            _sharedVertices = new Vector2[requestedSize];
+        }
+        return _sharedVertices;
+    }
+
     public SensorMonitoringWindow()
     {
         RobustXamlLoader.Load(this);
@@ -145,7 +168,7 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
                     }
                 });
 
-                Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f) { MinHeight = 150 });
+                Asdf.AddChild(new GraphView(stream.Samples, startTime, curTime, maxValue * 1.1f, this) { MinHeight = 150 });
                 Asdf.AddChild(new PanelContainer { StyleClasses = { StyleBase.ClassLowDivider } });
             }
         }
@@ -197,31 +220,37 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
         private readonly TimeSpan _startTime;
         private readonly TimeSpan _curTime;
         private readonly float _maxY;
+        private readonly SensorMonitoringWindow _parentWindow;
 
-        public GraphView(Queue<SensorSample> samples, TimeSpan startTime, TimeSpan curTime, float maxY)
+        public GraphView(Queue<SensorSample> samples,
+            TimeSpan startTime,
+            TimeSpan curTime,
+            float maxY,
+            SensorMonitoringWindow parentWindow)
         {
             _samples = samples;
             _startTime = startTime;
             _curTime = curTime;
             _maxY = maxY;
             RectClipContent = true;
+            _parentWindow = parentWindow;
         }
 
         protected override void Draw(DrawingHandleScreen handle)
         {
             base.Draw(handle);
 
-            var window = (float) (_curTime - _startTime).TotalSeconds;
-
-            // TODO: omg this is terrible don't fucking hardcode this size to something uncached huge omfg.
-            var vertices = new Vector2[25000];
+            var window = (float)(_curTime - _startTime).TotalSeconds;
             var countVtx = 0;
 
             var lastPoint = new Vector2(float.NaN, float.NaN);
+            var requiredVertices = 6 * (_samples.Count - 1);
+
+            var vertices = _parentWindow.GetSharedVertices(requiredVertices);
 
             foreach (var (time, sample) in _samples)
             {
-                var relTime = (float) (time - _startTime).TotalSeconds;
+                var relTime = (float)(time - _startTime).TotalSeconds;
 
                 var posY = PixelHeight - (sample / _maxY) * PixelHeight;
                 var posX = (relTime / window) * PixelWidth;
@@ -242,8 +271,9 @@ public sealed partial class SensorMonitoringWindow : FancyWindow, IComputerWindo
 
                 lastPoint = newPoint;
             }
-
-            handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList, vertices.AsSpan(0, countVtx), Color.White.WithAlpha(0.1f));
+            handle.DrawPrimitives(DrawPrimitiveTopology.TriangleList,
+                vertices.AsSpan(0, countVtx),
+                Color.White.WithAlpha(0.1f));
         }
     }
 }