Properly dispose of stale pipedata chunks for the atmos monitor (#38974)

This commit is contained in:
Perry Fraser
2025-07-23 11:18:19 -04:00
committed by GitHub
parent c95bbfaf93
commit 002afe8056
4 changed files with 43 additions and 5 deletions

View File

@@ -162,10 +162,10 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl
{ {
var list = new List<AtmosMonitoringConsoleLine>(); var list = new List<AtmosMonitoringConsoleLine>();
foreach (var ((netId, layer, hexColor), atmosPipeData) in chunk.AtmosPipeData) foreach (var ((netId, layer, pipeColor), atmosPipeData) in chunk.AtmosPipeData)
{ {
// Determine the correct coloration for the pipe // Determine the correct coloration for the pipe
var color = Color.FromHex(hexColor) * _basePipeNetColor; var color = pipeColor * _basePipeNetColor;
if (FocusNetId != null && FocusNetId != netId) if (FocusNetId != null && FocusNetId != netId)
color *= _unfocusedPipeNetColor; color *= _unfocusedPipeNetColor;

View File

@@ -17,6 +17,7 @@ using Robust.Shared.Map.Components;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Server.Atmos.EntitySystems;
using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Components;
using Content.Shared.NodeContainer; using Content.Shared.NodeContainer;
@@ -53,6 +54,7 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS
// Grid events // Grid events
SubscribeLocalEvent<GridSplitEvent>(OnGridSplit); SubscribeLocalEvent<GridSplitEvent>(OnGridSplit);
SubscribeLocalEvent<PipeNodeGroupRemovedEvent>(OnPipeNodeGroupRemoved);
} }
#region Event handling #region Event handling
@@ -295,6 +297,25 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS
#region Pipe net functions #region Pipe net functions
private void OnPipeNodeGroupRemoved(ref PipeNodeGroupRemovedEvent args)
{
// When a pipe node group is removed, we need to iterate over all of
// our pipe chunks and remove any entries with a matching net id.
// (We only need to check the chunks for the affected grid, though.)
if (!_gridAtmosPipeChunks.TryGetValue(args.Grid, out var chunkData))
return;
foreach (var chunk in chunkData.Values)
{
foreach (var key in chunk.AtmosPipeData.Keys)
{
if (key.NetId == args.NetId)
chunk.AtmosPipeData.Remove(key);
}
}
}
private void RebuildAtmosPipeGrid(EntityUid gridUid, MapGridComponent grid) private void RebuildAtmosPipeGrid(EntityUid gridUid, MapGridComponent grid)
{ {
var allChunks = new Dictionary<Vector2i, AtmosPipeChunk>(); var allChunks = new Dictionary<Vector2i, AtmosPipeChunk>();
@@ -411,7 +432,7 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS
continue; continue;
var netId = GetPipeNodeNetId(pipeNode); var netId = GetPipeNodeNetId(pipeNode);
var subnet = new AtmosMonitoringConsoleSubnet(netId, pipeNode.CurrentPipeLayer, pipeColor.Color.ToHex()); var subnet = new AtmosMonitoringConsoleSubnet(netId, pipeNode.CurrentPipeLayer, pipeColor.Color);
var pipeDirection = pipeNode.CurrentPipeDirection; var pipeDirection = pipeNode.CurrentPipeDirection;
chunk.AtmosPipeData.TryGetValue(subnet, out var atmosPipeData); chunk.AtmosPipeData.TryGetValue(subnet, out var atmosPipeData);

View File

@@ -279,6 +279,14 @@ public partial class AtmosphereSystem
public bool RemovePipeNet(Entity<GridAtmosphereComponent?> grid, PipeNet pipeNet) public bool RemovePipeNet(Entity<GridAtmosphereComponent?> grid, PipeNet pipeNet)
{ {
// Technically this event can be fired even on grids that don't
// actually have grid atmospheres.
if (pipeNet.Grid is not null)
{
var ev = new PipeNodeGroupRemovedEvent(grid, pipeNet.NetId);
RaiseLocalEvent(ref ev);
}
return _atmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Remove(pipeNet); return _atmosQuery.Resolve(grid, ref grid.Comp, false) && grid.Comp.PipeNets.Remove(pipeNet);
} }
@@ -329,3 +337,12 @@ public partial class AtmosphereSystem
[ByRefEvent] private record struct IsHotspotActiveMethodEvent [ByRefEvent] private record struct IsHotspotActiveMethodEvent
(EntityUid Grid, Vector2i Tile, bool Result = false, bool Handled = false); (EntityUid Grid, Vector2i Tile, bool Result = false, bool Handled = false);
} }
/// <summary>
/// Raised broadcasted when a pipe node group within a grid has been removed.
/// </summary>
/// <param name="Grid">The grid with the removed node group.</param>
/// <param name="NetId">The net id of the removed node group.</param>
[ByRefEvent]
public record struct PipeNodeGroupRemovedEvent(EntityUid Grid, int NetId);

View File

@@ -234,9 +234,9 @@ public struct AtmosMonitoringConsoleEntry
/// </summary> /// </summary>
/// <param name="NetId">The associated network ID.</param> /// <param name="NetId">The associated network ID.</param>
/// <param name="PipeLayer">The associated pipe layer.</param> /// <param name="PipeLayer">The associated pipe layer.</param>
/// <param name="HexCode">The color of the pipe.</param> /// <param name="Color">The color of the pipe.</param>
[Serializable, NetSerializable] [Serializable, NetSerializable]
public record AtmosMonitoringConsoleSubnet(int NetId, AtmosPipeLayer PipeLayer, string HexCode); public record AtmosMonitoringConsoleSubnet(int NetId, AtmosPipeLayer PipeLayer, Color Color);
public enum AtmosPipeChunkDataFacing : byte public enum AtmosPipeChunkDataFacing : byte
{ {