diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index 8e634a1c7d..cddfc3ee96 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -332,32 +332,40 @@ namespace Content.Server.Atmos var tile = tiles[i]; tile._tileAtmosInfo.FastDone = true; if (!(tile._tileAtmosInfo.MoleDelta > 0)) continue; - var eligibleDirections = new List(); - var amtEligibleAdj = 0; + var eligibleDirections = ArrayPool.Shared.Rent(4); + var eligibleDirectionCount = 0; foreach (var direction in Cardinal) { if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; - // skip anything that isn't part of our current processing block. Original one didn't do this unfortunately, which probably cause some massive lag. + // skip anything that isn't part of our current processing block. if (tile2._tileAtmosInfo.FastDone || tile2._tileAtmosInfo.LastQueueCycle != queueCycle) continue; - eligibleDirections.Add(direction); - amtEligibleAdj++; + eligibleDirections[eligibleDirectionCount++] = direction; } - if (amtEligibleAdj <= 0) + if (eligibleDirectionCount <= 0) continue; // Oof we've painted ourselves into a corner. Bad luck. Next part will handle this. - var molesToMove = tile._tileAtmosInfo.MoleDelta / amtEligibleAdj; + var molesToMove = tile._tileAtmosInfo.MoleDelta / eligibleDirectionCount; foreach (var direction in Cardinal) { - if (eligibleDirections.Contains(direction) || - !tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; + var hasDirection = false; + for (var j = 0; j < eligibleDirectionCount; j++) + { + if (eligibleDirections[j] != direction) continue; + hasDirection = true; + break; + } + + if (hasDirection || !tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; tile.AdjustEqMovement(direction, molesToMove); tile._tileAtmosInfo.MoleDelta -= molesToMove; tile2._tileAtmosInfo.MoleDelta += molesToMove; } + + ArrayPool.Shared.Return(eligibleDirections); } giverTilesLength = 0; @@ -446,7 +454,7 @@ namespace Content.Server.Atmos } } - ArrayPool.Shared.Return(queue, true); + ArrayPool.Shared.Return(queue); } else { @@ -516,7 +524,7 @@ namespace Content.Server.Atmos } } - ArrayPool.Shared.Return(queue, true); + ArrayPool.Shared.Return(queue); } for (var i = 0; i < tileCount; i++) @@ -537,9 +545,9 @@ namespace Content.Server.Atmos } } - ArrayPool.Shared.Return(tiles, true); - ArrayPool.Shared.Return(giverTiles, true); - ArrayPool.Shared.Return(takerTiles, true); + ArrayPool.Shared.Return(tiles); + ArrayPool.Shared.Return(giverTiles); + ArrayPool.Shared.Return(takerTiles); } } @@ -925,16 +933,22 @@ namespace Content.Server.Atmos public void ExplosivelyDepressurize(int cycleNum) { if (Air == null) return; + + const int limit = Atmospherics.ZumosTileLimit; + var totalGasesRemoved = 0f; var queueCycle = ++_gridAtmosphereComponent.EqualizationQueueCycleControl; - var tiles = new List(); - var spaceTiles = new List(); - tiles.Add(this); + var tiles = ArrayPool.Shared.Rent(limit); + var spaceTiles = ArrayPool.Shared.Rent(limit); + + var tileCount = 0; + var spaceTileCount = 0; + + tiles[tileCount++] = this; ResetTileAtmosInfo(); _tileAtmosInfo.LastQueueCycle = queueCycle; - var tileCount = 1; for (var i = 0; i < tileCount; i++) { var tile = tiles[i]; @@ -942,40 +956,44 @@ namespace Content.Server.Atmos tile._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid; if (tile.Air.Immutable) { - spaceTiles.Add(tile); + spaceTiles[spaceTileCount++] = tile; tile.PressureSpecificTarget = tile; } else { - if (i > Atmospherics.ZumosTileLimit) continue; foreach (var direction in Cardinal) { if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue; - if (tile2?.Air == null) continue; + if (tile2.Air == null) continue; if (tile2._tileAtmosInfo.LastQueueCycle == queueCycle) continue; + tile.ConsiderFirelocks(tile2); - if (tile._adjacentTiles[direction]?.Air != null) - { - tile2.ResetTileAtmosInfo(); - tile2._tileAtmosInfo.LastQueueCycle = queueCycle; - tiles.Add(tile2); - tileCount++; - } + + // The firelocks might have closed on us. + if (tile._adjacentTiles[direction]?.Air == null) continue; + tile2.ResetTileAtmosInfo(); + tile2._tileAtmosInfo.LastQueueCycle = queueCycle; + tiles[tileCount++] = tile2; } } + + if (tileCount >= limit || spaceTileCount >= limit) + break; } var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl; - var progressionOrder = new List(); - foreach (var tile in spaceTiles) + var progressionOrder = ArrayPool.Shared.Rent(limit * 2); + var progressionCount = 0; + + for (var i = 0; i < spaceTileCount; i++) { - progressionOrder.Add(tile); + var tile = spaceTiles[i]; + progressionOrder[progressionCount++] = tile; tile._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow; tile._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid; } - var progressionCount = progressionOrder.Count; - for (int i = 0; i < progressionCount; i++) + for (var i = 0; i < progressionCount; i++) { var tile = progressionOrder[i]; foreach (var direction in Cardinal) @@ -988,8 +1006,7 @@ namespace Content.Server.Atmos tile2._tileAtmosInfo.CurrentTransferAmount = 0; tile2.PressureSpecificTarget = tile.PressureSpecificTarget; tile2._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow; - progressionOrder.Add(tile2); - progressionCount++; + progressionOrder[progressionCount++] = tile2; } } @@ -1017,6 +1034,10 @@ namespace Content.Server.Atmos tile.UpdateVisuals(); tile.HandleDecompressionFloorRip(sum); } + + ArrayPool.Shared.Return(tiles); + ArrayPool.Shared.Return(spaceTiles); + ArrayPool.Shared.Return(progressionOrder); } private void HandleDecompressionFloorRip(float sum) @@ -1029,7 +1050,6 @@ namespace Content.Server.Atmos private void ConsiderFirelocks(TileAtmosphere other) { // TODO ATMOS firelocks! - //throw new NotImplementedException(); } private void React() diff --git a/SpaceStation14.sln.DotSettings b/SpaceStation14.sln.DotSettings index c93412bf8d..14abc1df09 100644 --- a/SpaceStation14.sln.DotSettings +++ b/SpaceStation14.sln.DotSettings @@ -51,6 +51,7 @@ <data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Lidgren.Network" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data> True True + True True True True