Makes Grid Revalidation a step in the atmos update stages.

Fixes some atmos debug assert exceptions.
This commit is contained in:
Vera Aguilera Puerto
2021-11-09 16:50:15 +01:00
parent 1f07ee1109
commit d370142b80
3 changed files with 125 additions and 125 deletions

View File

@@ -24,9 +24,6 @@ namespace Content.Server.Atmos.Components
public virtual bool Simulated => true;
[ViewVariables]
public bool RevalidatePaused { get; set; } = false;
[ViewVariables]
public bool ProcessingPaused { get; set; } = false;

View File

@@ -217,113 +217,6 @@ namespace Content.Server.Atmos.EntitySystems
#endregion
#region Grid Revalidate
/// <summary>
/// Revalidates all invalid coordinates in a grid atmosphere.
/// </summary>
/// <param name="mapGrid">The grid in question.</param>
/// <param name="gridAtmosphere">The grid atmosphere in question.</param>
/// <returns>Whether the process succeeded or got paused due to time constrains.</returns>
private bool GridRevalidate(IMapGrid mapGrid, GridAtmosphereComponent gridAtmosphere)
{
var volume = GetVolumeForTiles(mapGrid, 1);
if (!gridAtmosphere.RevalidatePaused)
gridAtmosphere.CurrentRunInvalidatedCoordinates = new Queue<Vector2i>(gridAtmosphere.InvalidatedCoords);
gridAtmosphere.InvalidatedCoords.Clear();
var number = 0;
while (gridAtmosphere.CurrentRunInvalidatedCoordinates.TryDequeue(out var indices))
{
var tile = GetTileAtmosphere(gridAtmosphere, indices);
if (tile == null)
{
tile = new TileAtmosphere(mapGrid.Index, indices, new GasMixture(volume){Temperature = Atmospherics.T20C});
gridAtmosphere.Tiles[indices] = tile;
}
var isAirBlocked = IsTileAirBlocked(mapGrid, indices);
tile.BlockedAirflow = GetBlockedDirections(mapGrid, indices);
UpdateAdjacent(mapGrid, gridAtmosphere, tile);
if (IsTileSpace(mapGrid, indices) && !isAirBlocked)
{
tile.Air = new GasMixture(volume);
tile.Air.MarkImmutable();
gridAtmosphere.Tiles[indices] = tile;
} else if (isAirBlocked)
{
var nullAir = false;
foreach (var airtight in GetObstructingComponents(mapGrid, indices))
{
if (!airtight.NoAirWhenFullyAirBlocked)
continue;
nullAir = true;
break;
}
if (nullAir)
{
tile.Air = null;
tile.Hotspot = new Hotspot();
}
}
else
{
if (tile.Air == null && NeedsVacuumFixing(mapGrid, indices))
{
FixVacuum(gridAtmosphere, tile.GridIndices);
}
// Tile used to be space, but isn't anymore.
if (tile.Air?.Immutable ?? false)
{
tile.Air = null;
}
tile.Air ??= new GasMixture(volume){Temperature = Atmospherics.T20C};
}
// By removing the active tile, we effectively remove its excited group, if any.
RemoveActiveTile(gridAtmosphere, tile);
// Then we activate the tile again.
AddActiveTile(gridAtmosphere, tile);
// TODO ATMOS: Query all the contents of this tile (like walls) and calculate the correct thermal conductivity
tile.ThermalConductivity = tile.Tile?.Tile.GetContentTileDefinition().ThermalConductivity ?? 0.5f;
InvalidateVisuals(mapGrid.Index, indices);
for (var i = 0; i < Atmospherics.Directions; i++)
{
var direction = (AtmosDirection) (1 << i);
var otherIndices = indices.Offset(direction);
var otherTile = GetTileAtmosphere(gridAtmosphere, otherIndices);
if (otherTile != null)
AddActiveTile(gridAtmosphere, otherTile);
}
if (number++ < InvalidCoordinatesLagCheckIterations) continue;
number = 0;
// Process the rest next time.
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
{
return false;
}
}
return true;
}
#endregion
#region Grid Repopulate
/// <summary>

View File

@@ -4,8 +4,10 @@ using Content.Server.Atmos.Components;
using Content.Server.Atmos.Piping.Components;
using Content.Server.NodeContainer.NodeGroups;
using Content.Shared.Atmos;
using Content.Shared.Maps;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
namespace Content.Server.Atmos.EntitySystems
@@ -32,6 +34,112 @@ namespace Content.Server.Atmos.EntitySystems
private readonly List<GridAtmosphereComponent> _currentRunAtmosphere = new();
/// <summary>
/// Revalidates all invalid coordinates in a grid atmosphere.
/// </summary>
/// <param name="atmosphere">The grid atmosphere in question.</param>
/// <returns>Whether the process succeeded or got paused due to time constrains.</returns>
private bool ProcessRevalidate(GridAtmosphereComponent atmosphere)
{
if (!atmosphere.ProcessingPaused)
{
atmosphere.CurrentRunInvalidatedCoordinates = new Queue<Vector2i>(atmosphere.InvalidatedCoords);
atmosphere.InvalidatedCoords.Clear();
}
if (!TryGetMapGrid(atmosphere, out var mapGrid))
return true;
var volume = GetVolumeForTiles(mapGrid, 1);
var number = 0;
while (atmosphere.CurrentRunInvalidatedCoordinates.TryDequeue(out var indices))
{
var tile = GetTileAtmosphere(atmosphere, indices);
if (tile == null)
{
tile = new TileAtmosphere(mapGrid.Index, indices, new GasMixture(volume){Temperature = Atmospherics.T20C});
atmosphere.Tiles[indices] = tile;
}
var isAirBlocked = IsTileAirBlocked(mapGrid, indices);
tile.BlockedAirflow = GetBlockedDirections(mapGrid, indices);
UpdateAdjacent(mapGrid, atmosphere, tile);
if (IsTileSpace(mapGrid, indices) && !isAirBlocked)
{
tile.Air = new GasMixture(volume);
tile.Air.MarkImmutable();
atmosphere.Tiles[indices] = tile;
} else if (isAirBlocked)
{
var nullAir = false;
foreach (var airtight in GetObstructingComponents(mapGrid, indices))
{
if (!airtight.NoAirWhenFullyAirBlocked)
continue;
nullAir = true;
break;
}
if (nullAir)
{
tile.Air = null;
tile.Hotspot = new Hotspot();
}
}
else
{
if (tile.Air == null && NeedsVacuumFixing(mapGrid, indices))
{
FixVacuum(atmosphere, tile.GridIndices);
}
// Tile used to be space, but isn't anymore.
if (tile.Air?.Immutable ?? false)
{
tile.Air = null;
}
tile.Air ??= new GasMixture(volume){Temperature = Atmospherics.T20C};
}
// By removing the active tile, we effectively remove its excited group, if any.
RemoveActiveTile(atmosphere, tile);
// Then we activate the tile again.
AddActiveTile(atmosphere, tile);
// TODO ATMOS: Query all the contents of this tile (like walls) and calculate the correct thermal conductivity
tile.ThermalConductivity = tile.Tile?.Tile.GetContentTileDefinition().ThermalConductivity ?? 0.5f;
InvalidateVisuals(mapGrid.Index, indices);
for (var i = 0; i < Atmospherics.Directions; i++)
{
var direction = (AtmosDirection) (1 << i);
var otherIndices = indices.Offset(direction);
var otherTile = GetTileAtmosphere(atmosphere, otherIndices);
if (otherTile != null)
AddActiveTile(atmosphere, otherTile);
}
if (number++ < InvalidCoordinatesLagCheckIterations) continue;
number = 0;
// Process the rest next time.
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
{
return false;
}
}
return true;
}
private bool ProcessTileEqualize(GridAtmosphereComponent atmosphere)
{
if(!atmosphere.ProcessingPaused)
@@ -246,15 +354,6 @@ namespace Content.Server.Atmos.EntitySystems
atmosphere.Timer += frameTime;
if ((atmosphere.InvalidatedCoords.Count != 0 || atmosphere.RevalidatePaused) && TryGetMapGrid(atmosphere, out var mapGrid))
if (!GridRevalidate(mapGrid, atmosphere))
{
atmosphere.RevalidatePaused = true;
return;
}
atmosphere.RevalidatePaused = false;
if (atmosphere.Timer < AtmosTime)
continue;
@@ -263,6 +362,21 @@ namespace Content.Server.Atmos.EntitySystems
switch (atmosphere.State)
{
case AtmosphereProcessingState.Revalidate:
if (!ProcessRevalidate(atmosphere))
{
atmosphere.ProcessingPaused = true;
return;
}
atmosphere.ProcessingPaused = false;
// Next state depends on whether monstermos equalization is enabled or not.
// Note: We do this here instead of on the tile equalization step to prevent ending it early.
// Therefore, a change to this CVar might only be applied after that step is over.
atmosphere.State = MonstermosEqualization
? AtmosphereProcessingState.TileEqualize
: AtmosphereProcessingState.ActiveTiles;
continue;
case AtmosphereProcessingState.TileEqualize:
if (!ProcessTileEqualize(atmosphere))
{
@@ -347,12 +461,7 @@ namespace Content.Server.Atmos.EntitySystems
}
atmosphere.ProcessingPaused = false;
// Next state depends on whether monstermos equalization is enabled or not.
// Note: We do this here instead of on the tile equalization step to prevent ending it early.
// Therefore, a change to this CVar might only be applied after that step is over.
atmosphere.State = MonstermosEqualization
? AtmosphereProcessingState.TileEqualize
: AtmosphereProcessingState.ActiveTiles;
atmosphere.State = AtmosphereProcessingState.Revalidate;
// We reached the end of this atmosphere's update tick. Break out of the switch.
break;
@@ -369,6 +478,7 @@ namespace Content.Server.Atmos.EntitySystems
public enum AtmosphereProcessingState : byte
{
Revalidate,
TileEqualize,
ActiveTiles,
ExcitedGroups,