From 268791abc5f2194923f99d0f9858aed26ca271f2 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sun, 19 Nov 2023 17:06:00 +1300 Subject: [PATCH] Reduce explosion allocations (#21769) --- .../ExplosionSystem.Processing.cs | 20 ++++++++++++------- .../EntitySystems/ExplosionSystem.cs | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index aa3f114c0e..91cbba648c 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -55,6 +55,8 @@ public sealed partial class ExplosionSystem /// private int _previousTileIteration; + private List _anchored = new(); + private void OnMapChanged(MapChangedEvent ev) { // If a map was deleted, check the explosion currently being processed belongs to that map. @@ -194,7 +196,7 @@ public sealed partial class ExplosionSystem /// /// True if the underlying tile can be uprooted, false if the tile is blocked by a dense entity internal bool ExplodeTile(BroadphaseComponent lookup, - MapGridComponent grid, + Entity grid, Vector2i tile, float throwForce, DamageSpecifier damage, @@ -202,7 +204,8 @@ public sealed partial class ExplosionSystem HashSet processed, string id) { - var gridBox = new Box2(tile * grid.TileSize, (tile + 1) * grid.TileSize); + var size = grid.Comp.TileSize; + var gridBox = new Box2(tile * size, (tile + 1) * size); // get the entities on a tile. Note that we cannot process them directly, or we get // enumerator-changed-while-enumerating errors. @@ -223,8 +226,9 @@ public sealed partial class ExplosionSystem // process anchored entities var tileBlocked = false; - var anchoredList = grid.GetAnchoredEntities(tile).ToList(); - foreach (var entity in anchoredList) + _anchored.Clear(); + _map.GetAnchoredEntities(grid, tile, _anchored); + foreach (var entity in _anchored) { processed.Add(entity); ProcessEntity(entity, epicenter, damage, throwForce, id, null); @@ -234,9 +238,11 @@ public sealed partial class ExplosionSystem // the purposes of destroying floors. Again, ideally the process of damaging an entity should somehow return // information about the entities that were spawned as a result, but without that information we just have to // re-check for new anchored entities. Compared to entity spawning & deleting, this should still be relatively minor. - if (anchoredList.Count > 0) + if (_anchored.Count > 0) { - foreach (var entity in grid.GetAnchoredEntities(tile)) + _anchored.Clear(); + _map.GetAnchoredEntities(grid, tile, _anchored); + foreach (var entity in _anchored) { tileBlocked |= IsBlockingTurf(entity); } @@ -786,7 +792,7 @@ sealed class Explosion // damage entities on the tile. Also figures out whether there are any solid entities blocking the floor // from being destroyed. var canDamageFloor = _system.ExplodeTile(_currentLookup, - _currentGrid, + (_currentGrid.Owner, _currentGrid), _currentEnumerator.Current, _currentThrowForce, _currentDamage, diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 2ddf314fa1..fb8494c680 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -50,6 +50,7 @@ public sealed partial class ExplosionSystem : EntitySystem [Dependency] private readonly ThrowingSystem _throwingSystem = default!; [Dependency] private readonly PvsOverrideSystem _pvsSys = default!; [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly SharedMapSystem _map = default!; private EntityQuery _transformQuery; private EntityQuery _containersQuery;