]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Split GasTileOverlaySystem update over two ticks (#26542)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Sat, 30 Mar 2024 02:34:55 +0000 (15:34 +1300)
committerGitHub <noreply@github.com>
Sat, 30 Mar 2024 02:34:55 +0000 (13:34 +1100)
Split GasTileOverlaySystem update over ticks

Content.Server/Atmos/EntitySystems/GasTileOverlaySystem.cs

index 6d49feb0181018ce4ccf7bfb38bc938b3dba6555..003eed59e0360de6f150c60cbe5089f01447dfb5 100644 (file)
@@ -52,6 +52,8 @@ namespace Content.Server.Atmos.EntitySystems
             new DefaultObjectPool<Dictionary<NetEntity, HashSet<Vector2i>>>(
                 new DefaultPooledObjectPolicy<Dictionary<NetEntity, HashSet<Vector2i>>>(), 64);
 
+        private bool _doSessionUpdate;
+
         /// <summary>
         ///     Overlay update interval, in seconds.
         /// </summary>
@@ -192,7 +194,7 @@ namespace Content.Server.Atmos.EntitySystems
         /// <summary>
         ///     Updates the visuals for a tile on some grid chunk. Returns true if the visuals have changed.
         /// </summary>
-        private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index, GameTick curTick)
+        private bool UpdateChunkTile(GridAtmosphereComponent gridAtmosphere, GasOverlayChunk chunk, Vector2i index)
         {
             ref var oldData = ref chunk.TileData[chunk.GetDataIndex(index)];
             if (!gridAtmosphere.Tiles.TryGetValue(index, out var tile))
@@ -200,7 +202,7 @@ namespace Content.Server.Atmos.EntitySystems
                 if (oldData.Equals(default))
                     return false;
 
-                chunk.LastUpdate = curTick;
+                chunk.LastUpdate = _gameTiming.CurTick;
                 oldData = default;
                 return true;
             }
@@ -258,11 +260,11 @@ namespace Content.Server.Atmos.EntitySystems
             if (!changed)
                 return false;
 
-            chunk.LastUpdate = curTick;
+            chunk.LastUpdate = _gameTiming.CurTick;
             return true;
         }
 
-        private void UpdateOverlayData(GameTick curTick)
+        private void UpdateOverlayData()
         {
             // TODO parallelize?
             var query = EntityQueryEnumerator<GasTileOverlayComponent, GridAtmosphereComponent, MetaDataComponent>();
@@ -276,7 +278,7 @@ namespace Content.Server.Atmos.EntitySystems
                     if (!overlay.Chunks.TryGetValue(chunkIndex, out var chunk))
                         overlay.Chunks[chunkIndex] = chunk = new GasOverlayChunk(chunkIndex);
 
-                    changed |= UpdateChunkTile(gam, chunk, index, curTick);
+                    changed |= UpdateChunkTile(gam, chunk, index);
                 }
 
                 if (changed)
@@ -291,13 +293,28 @@ namespace Content.Server.Atmos.EntitySystems
             base.Update(frameTime);
             AccumulatedFrameTime += frameTime;
 
-            if (AccumulatedFrameTime < _updateInterval) return;
-            AccumulatedFrameTime -= _updateInterval;
+            if (_doSessionUpdate)
+            {
+                UpdateSessions();
+                return;
+            }
+
+            if (AccumulatedFrameTime < _updateInterval)
+                return;
 
-            var curTick = _gameTiming.CurTick;
+            AccumulatedFrameTime -= _updateInterval;
 
             // First, update per-chunk visual data for any invalidated tiles.
-            UpdateOverlayData(curTick);
+            UpdateOverlayData();
+
+            // Then, next tick we send the data to players.
+            // This is to avoid doing all the work in the same tick.
+            _doSessionUpdate = true;
+        }
+
+        public void UpdateSessions()
+        {
+            _doSessionUpdate = false;
 
             if (!PvsEnabled)
                 return;
@@ -315,11 +332,11 @@ namespace Content.Server.Atmos.EntitySystems
                 _sessions.Add(player);
             }
 
-            if (_sessions.Count > 0)
-            {
-                _updateJob.CurrentTick = curTick;
-                _parMan.ProcessNow(_updateJob, _sessions.Count);
-            }
+            if (_sessions.Count == 0)
+                return;
+
+            _parMan.ProcessNow(_updateJob, _sessions.Count);
+            _updateJob.LastSessionUpdate = _gameTiming.CurTick;
         }
 
         public void Reset(RoundRestartCleanupEvent ev)
@@ -352,7 +369,7 @@ namespace Content.Server.Atmos.EntitySystems
             public ObjectPool<HashSet<Vector2i>> ChunkIndexPool;
             public ObjectPool<Dictionary<NetEntity, HashSet<Vector2i>>> ChunkViewerPool;
 
-            public GameTick CurrentTick;
+            public GameTick LastSessionUpdate;
             public Dictionary<ICommonSession, Dictionary<NetEntity, HashSet<Vector2i>>> LastSentChunks;
             public List<ICommonSession> Sessions;
 
@@ -415,7 +432,7 @@ namespace Content.Server.Atmos.EntitySystems
 
                         if (previousChunks != null &&
                             previousChunks.Contains(gIndex) &&
-                            value.LastUpdate != CurrentTick)
+                            value.LastUpdate > LastSessionUpdate)
                         {
                             continue;
                         }