ECS Atmos Part 1: Move GridAtmosphere updating and processing to AtmosphereSystem.Processing (#4206)
This commit is contained in:
committed by
GitHub
parent
f2816e8081
commit
3f28a4d784
@@ -40,16 +40,10 @@ namespace Content.Server.Atmos.Components
|
|||||||
internal GasTileOverlaySystem GasTileOverlaySystem { get; private set; } = default!;
|
internal GasTileOverlaySystem GasTileOverlaySystem { get; private set; } = default!;
|
||||||
public AtmosphereSystem AtmosphereSystem { get; private set; } = default!;
|
public AtmosphereSystem AtmosphereSystem { get; private set; } = default!;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check current execution time every n instances processed.
|
|
||||||
/// </summary>
|
|
||||||
private const int LagCheckIterations = 30;
|
|
||||||
|
|
||||||
public override string Name => "GridAtmosphere";
|
public override string Name => "GridAtmosphere";
|
||||||
|
|
||||||
private bool _paused;
|
public bool ProcessingPaused { get; set; } = false;
|
||||||
private float _timer;
|
public float Timer { get; set; }
|
||||||
private Stopwatch _stopwatch = new();
|
|
||||||
private GridId _gridId;
|
private GridId _gridId;
|
||||||
|
|
||||||
[ComponentDependency] private IMapGridComponent? _mapGridComponent;
|
[ComponentDependency] private IMapGridComponent? _mapGridComponent;
|
||||||
@@ -57,113 +51,74 @@ namespace Content.Server.Atmos.Components
|
|||||||
public virtual bool Simulated => true;
|
public virtual bool Simulated => true;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int UpdateCounter { get; private set; } = 0;
|
public int UpdateCounter { get; set; } = 0;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private double _tileEqualizeLastProcess;
|
public readonly HashSet<ExcitedGroup> ExcitedGroups = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<ExcitedGroup> _excitedGroups = new(1000);
|
public int ExcitedGroupCount => ExcitedGroups.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private int ExcitedGroupCount => _excitedGroups.Count;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private double _excitedGroupLastProcess;
|
|
||||||
|
|
||||||
[DataField("uniqueMixes")]
|
[DataField("uniqueMixes")]
|
||||||
private List<GasMixture>? _uniqueMixes;
|
public List<GasMixture>? UniqueMixes;
|
||||||
|
|
||||||
[DataField("tiles")]
|
[DataField("tiles")]
|
||||||
private Dictionary<Vector2i, int>? _tiles;
|
public Dictionary<Vector2i, int>? TilesUniqueMixes;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
protected readonly Dictionary<Vector2i, TileAtmosphere> Tiles = new(1000);
|
public readonly Dictionary<Vector2i, TileAtmosphere> Tiles = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<TileAtmosphere> _activeTiles = new(1000);
|
public readonly HashSet<TileAtmosphere> ActiveTiles = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int ActiveTilesCount => _activeTiles.Count;
|
public int ActiveTilesCount => ActiveTiles.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private double _activeTilesLastProcess;
|
public readonly HashSet<TileAtmosphere> HotspotTiles = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<TileAtmosphere> _hotspotTiles = new(1000);
|
public int HotspotTilesCount => HotspotTiles.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int HotspotTilesCount => _hotspotTiles.Count;
|
public readonly HashSet<TileAtmosphere> SuperconductivityTiles = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private double _hotspotsLastProcess;
|
public int SuperconductivityTilesCount => SuperconductivityTiles.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<TileAtmosphere> _superconductivityTiles = new(1000);
|
public readonly HashSet<Vector2i> InvalidatedCoords = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int SuperconductivityTilesCount => _superconductivityTiles.Count;
|
public HashSet<TileAtmosphere> HighPressureDelta = new(1000);
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private double _superconductivityLastProcess;
|
public int HighPressureDeltaCount => HighPressureDelta.Count;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<Vector2i> _invalidatedCoords = new(1000);
|
public readonly HashSet<IPipeNet> PipeNets = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int InvalidatedCoordsCount => _invalidatedCoords.Count;
|
public readonly HashSet<AtmosDeviceComponent> AtmosDevices = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private HashSet<TileAtmosphere> _highPressureDelta = new(1000);
|
public Queue<TileAtmosphere> CurrentRunTiles = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private int HighPressureDeltaCount => _highPressureDelta.Count;
|
public Queue<ExcitedGroup> CurrentRunExcitedGroups = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private double _highPressureDeltaLastProcess;
|
public Queue<IPipeNet> CurrentRunPipeNet = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private readonly HashSet<IPipeNet> _pipeNets = new();
|
public Queue<AtmosDeviceComponent> CurrentRunAtmosDevices = new();
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
private double _pipeNetLastProcess;
|
public AtmosphereProcessingState State { get; set; } = AtmosphereProcessingState.TileEqualize;
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private readonly HashSet<AtmosDeviceComponent> _atmosDevices = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private double _atmosDevicesLastProcess;
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private Queue<TileAtmosphere> _currentRunTiles = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private Queue<ExcitedGroup> _currentRunExcitedGroups = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private Queue<IPipeNet> _currentRunPipeNet = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private Queue<AtmosDeviceComponent> _currentRunAtmosDevices = new();
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
private ProcessState _state = ProcessState.TileEqualize;
|
|
||||||
|
|
||||||
public GridAtmosphereComponent()
|
public GridAtmosphereComponent()
|
||||||
{
|
{
|
||||||
_paused = false;
|
ProcessingPaused = false;
|
||||||
}
|
|
||||||
|
|
||||||
private enum ProcessState
|
|
||||||
{
|
|
||||||
TileEqualize,
|
|
||||||
ActiveTiles,
|
|
||||||
ExcitedGroups,
|
|
||||||
HighPressureDelta,
|
|
||||||
Hotspots,
|
|
||||||
Superconductivity,
|
|
||||||
PipeNet,
|
|
||||||
AtmosDevices,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -199,8 +154,8 @@ namespace Content.Server.Atmos.Components
|
|||||||
if (uniqueMixes.Count == 0) uniqueMixes = null;
|
if (uniqueMixes.Count == 0) uniqueMixes = null;
|
||||||
if (tiles.Count == 0) tiles = null;
|
if (tiles.Count == 0) tiles = null;
|
||||||
|
|
||||||
_uniqueMixes = uniqueMixes;
|
UniqueMixes = uniqueMixes;
|
||||||
_tiles = tiles;
|
TilesUniqueMixes = tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
@@ -209,13 +164,13 @@ namespace Content.Server.Atmos.Components
|
|||||||
|
|
||||||
Tiles.Clear();
|
Tiles.Clear();
|
||||||
|
|
||||||
if (_tiles != null && Owner.TryGetComponent(out IMapGridComponent? mapGrid))
|
if (TilesUniqueMixes != null && Owner.TryGetComponent(out IMapGridComponent? mapGrid))
|
||||||
{
|
{
|
||||||
foreach (var (indices, mix) in _tiles)
|
foreach (var (indices, mix) in TilesUniqueMixes)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Tiles.Add(indices, new TileAtmosphere(this, mapGrid.GridIndex, indices, (GasMixture) _uniqueMixes![mix].Clone()));
|
Tiles.Add(indices, new TileAtmosphere(this, mapGrid.GridIndex, indices, (GasMixture) UniqueMixes![mix].Clone()));
|
||||||
}
|
}
|
||||||
catch (ArgumentOutOfRangeException)
|
catch (ArgumentOutOfRangeException)
|
||||||
{
|
{
|
||||||
@@ -264,12 +219,12 @@ namespace Content.Server.Atmos.Components
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void Invalidate(Vector2i indices)
|
public virtual void Invalidate(Vector2i indices)
|
||||||
{
|
{
|
||||||
_invalidatedCoords.Add(indices);
|
InvalidatedCoords.Add(indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Revalidate()
|
public virtual void Revalidate()
|
||||||
{
|
{
|
||||||
foreach (var indices in _invalidatedCoords)
|
foreach (var indices in InvalidatedCoords)
|
||||||
{
|
{
|
||||||
var tile = GetTile(indices);
|
var tile = GetTile(indices);
|
||||||
|
|
||||||
@@ -341,7 +296,7 @@ namespace Content.Server.Atmos.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_invalidatedCoords.Clear();
|
InvalidatedCoords.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -376,14 +331,14 @@ namespace Content.Server.Atmos.Components
|
|||||||
{
|
{
|
||||||
if (tile?.GridIndex != _gridId || tile.Air == null) return;
|
if (tile?.GridIndex != _gridId || tile.Air == null) return;
|
||||||
tile.Excited = true;
|
tile.Excited = true;
|
||||||
_activeTiles.Add(tile);
|
ActiveTiles.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public virtual void RemoveActiveTile(TileAtmosphere tile, bool disposeGroup = true)
|
public virtual void RemoveActiveTile(TileAtmosphere tile, bool disposeGroup = true)
|
||||||
{
|
{
|
||||||
_activeTiles.Remove(tile);
|
ActiveTiles.Remove(tile);
|
||||||
tile.Excited = false;
|
tile.Excited = false;
|
||||||
if(disposeGroup)
|
if(disposeGroup)
|
||||||
tile.ExcitedGroup?.Dispose();
|
tile.ExcitedGroup?.Dispose();
|
||||||
@@ -396,25 +351,25 @@ namespace Content.Server.Atmos.Components
|
|||||||
public virtual void AddHotspotTile(TileAtmosphere tile)
|
public virtual void AddHotspotTile(TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
if (tile?.GridIndex != _gridId || tile?.Air == null) return;
|
if (tile?.GridIndex != _gridId || tile?.Air == null) return;
|
||||||
_hotspotTiles.Add(tile);
|
HotspotTiles.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public virtual void RemoveHotspotTile(TileAtmosphere tile)
|
public virtual void RemoveHotspotTile(TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
_hotspotTiles.Remove(tile);
|
HotspotTiles.Remove(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void AddSuperconductivityTile(TileAtmosphere tile)
|
public virtual void AddSuperconductivityTile(TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
if (tile?.GridIndex != _gridId || !AtmosphereSystem.Superconduction) return;
|
if (tile?.GridIndex != _gridId || !AtmosphereSystem.Superconduction) return;
|
||||||
_superconductivityTiles.Add(tile);
|
SuperconductivityTiles.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RemoveSuperconductivityTile(TileAtmosphere tile)
|
public virtual void RemoveSuperconductivityTile(TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
_superconductivityTiles.Remove(tile);
|
SuperconductivityTiles.Remove(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -422,48 +377,48 @@ namespace Content.Server.Atmos.Components
|
|||||||
public virtual void AddHighPressureDelta(TileAtmosphere tile)
|
public virtual void AddHighPressureDelta(TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
if (tile.GridIndex != _gridId) return;
|
if (tile.GridIndex != _gridId) return;
|
||||||
_highPressureDelta.Add(tile);
|
HighPressureDelta.Add(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public virtual bool HasHighPressureDelta(TileAtmosphere tile)
|
public virtual bool HasHighPressureDelta(TileAtmosphere tile)
|
||||||
{
|
{
|
||||||
return _highPressureDelta.Contains(tile);
|
return HighPressureDelta.Contains(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public virtual void AddExcitedGroup(ExcitedGroup excitedGroup)
|
public virtual void AddExcitedGroup(ExcitedGroup excitedGroup)
|
||||||
{
|
{
|
||||||
_excitedGroups.Add(excitedGroup);
|
ExcitedGroups.Add(excitedGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public virtual void RemoveExcitedGroup(ExcitedGroup excitedGroup)
|
public virtual void RemoveExcitedGroup(ExcitedGroup excitedGroup)
|
||||||
{
|
{
|
||||||
_excitedGroups.Remove(excitedGroup);
|
ExcitedGroups.Remove(excitedGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void AddPipeNet(IPipeNet pipeNet)
|
public virtual void AddPipeNet(IPipeNet pipeNet)
|
||||||
{
|
{
|
||||||
_pipeNets.Add(pipeNet);
|
PipeNets.Add(pipeNet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RemovePipeNet(IPipeNet pipeNet)
|
public virtual void RemovePipeNet(IPipeNet pipeNet)
|
||||||
{
|
{
|
||||||
_pipeNets.Remove(pipeNet);
|
PipeNets.Remove(pipeNet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void AddAtmosDevice(AtmosDeviceComponent atmosDevice)
|
public virtual void AddAtmosDevice(AtmosDeviceComponent atmosDevice)
|
||||||
{
|
{
|
||||||
_atmosDevices.Add(atmosDevice);
|
AtmosDevices.Add(atmosDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice)
|
public virtual void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice)
|
||||||
{
|
{
|
||||||
_atmosDevices.Remove(atmosDevice);
|
AtmosDevices.Remove(atmosDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -545,349 +500,6 @@ namespace Content.Server.Atmos.Components
|
|||||||
return _mapGridComponent.Grid.TileSize * cellCount * Atmospherics.CellVolume;
|
return _mapGridComponent.Grid.TileSize * cellCount * Atmospherics.CellVolume;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public virtual void Update(float frameTime)
|
|
||||||
{
|
|
||||||
_timer += frameTime;
|
|
||||||
var atmosTime = 1f/AtmosphereSystem.AtmosTickRate;
|
|
||||||
|
|
||||||
if (_invalidatedCoords.Count != 0)
|
|
||||||
Revalidate();
|
|
||||||
|
|
||||||
if (_timer < atmosTime)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// We subtract it so it takes lost time into account.
|
|
||||||
_timer -= atmosTime;
|
|
||||||
|
|
||||||
var maxProcessTime = AtmosphereSystem.AtmosMaxProcessTime;
|
|
||||||
|
|
||||||
switch (_state)
|
|
||||||
{
|
|
||||||
case ProcessState.TileEqualize:
|
|
||||||
if (!ProcessTileEqualize(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
_state = ProcessState.ActiveTiles;
|
|
||||||
return;
|
|
||||||
case ProcessState.ActiveTiles:
|
|
||||||
if (!ProcessActiveTiles(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
_state = ProcessState.ExcitedGroups;
|
|
||||||
return;
|
|
||||||
case ProcessState.ExcitedGroups:
|
|
||||||
if (!ProcessExcitedGroups(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
_state = ProcessState.HighPressureDelta;
|
|
||||||
return;
|
|
||||||
case ProcessState.HighPressureDelta:
|
|
||||||
if (!ProcessHighPressureDelta(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
_state = ProcessState.Hotspots;
|
|
||||||
break;
|
|
||||||
case ProcessState.Hotspots:
|
|
||||||
if (!ProcessHotspots(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
// Next state depends on whether superconduction 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.
|
|
||||||
_state = AtmosphereSystem.Superconduction ? ProcessState.Superconductivity : ProcessState.PipeNet;
|
|
||||||
break;
|
|
||||||
case ProcessState.Superconductivity:
|
|
||||||
if (!ProcessSuperconductivity(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
_state = ProcessState.PipeNet;
|
|
||||||
break;
|
|
||||||
case ProcessState.PipeNet:
|
|
||||||
if (!ProcessPipeNets(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = false;
|
|
||||||
_state = ProcessState.AtmosDevices;
|
|
||||||
break;
|
|
||||||
case ProcessState.AtmosDevices:
|
|
||||||
if (!ProcessAtmosDevices(_paused, maxProcessTime))
|
|
||||||
{
|
|
||||||
_paused = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_paused = 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.
|
|
||||||
_state = AtmosphereSystem.MonstermosEqualization ? ProcessState.TileEqualize : ProcessState.ActiveTiles;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool ProcessTileEqualize(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunTiles = new Queue<TileAtmosphere>(_activeTiles);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunTiles.Count > 0)
|
|
||||||
{
|
|
||||||
var tile = _currentRunTiles.Dequeue();
|
|
||||||
tile.EqualizePressureInZone(UpdateCounter);
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_tileEqualizeLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_tileEqualizeLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool ProcessActiveTiles(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
var spaceWind = AtmosphereSystem.SpaceWind;
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunTiles = new Queue<TileAtmosphere>(_activeTiles);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunTiles.Count > 0)
|
|
||||||
{
|
|
||||||
var tile = _currentRunTiles.Dequeue();
|
|
||||||
tile.ProcessCell(UpdateCounter, spaceWind);
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_activeTilesLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_activeTilesLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool ProcessExcitedGroups(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
var spaceIsAllConsuming = AtmosphereSystem.ExcitedGroupsSpaceIsAllConsuming;
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunExcitedGroups = new Queue<ExcitedGroup>(_excitedGroups);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunExcitedGroups.Count > 0)
|
|
||||||
{
|
|
||||||
var excitedGroup = _currentRunExcitedGroups.Dequeue();
|
|
||||||
excitedGroup.BreakdownCooldown++;
|
|
||||||
excitedGroup.DismantleCooldown++;
|
|
||||||
|
|
||||||
if(excitedGroup.BreakdownCooldown > Atmospherics.ExcitedGroupBreakdownCycles)
|
|
||||||
excitedGroup.SelfBreakdown(spaceIsAllConsuming);
|
|
||||||
|
|
||||||
else if(excitedGroup.DismantleCooldown > Atmospherics.ExcitedGroupsDismantleCycles)
|
|
||||||
excitedGroup.Dismantle();
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_excitedGroupLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_excitedGroupLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool ProcessHighPressureDelta(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunTiles = new Queue<TileAtmosphere>(_highPressureDelta);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunTiles.Count > 0)
|
|
||||||
{
|
|
||||||
var tile = _currentRunTiles.Dequeue();
|
|
||||||
tile.HighPressureMovements();
|
|
||||||
tile.PressureDifference = 0f;
|
|
||||||
tile.PressureSpecificTarget = null;
|
|
||||||
_highPressureDelta.Remove(tile);
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_highPressureDeltaLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_highPressureDeltaLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool ProcessHotspots(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunTiles = new Queue<TileAtmosphere>(_hotspotTiles);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunTiles.Count > 0)
|
|
||||||
{
|
|
||||||
var hotspot = _currentRunTiles.Dequeue();
|
|
||||||
hotspot.ProcessHotspot();
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_hotspotsLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_hotspotsLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool ProcessSuperconductivity(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunTiles = new Queue<TileAtmosphere>(_superconductivityTiles);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunTiles.Count > 0)
|
|
||||||
{
|
|
||||||
var superconductivity = _currentRunTiles.Dequeue();
|
|
||||||
superconductivity.Superconduct();
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_superconductivityLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_superconductivityLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool ProcessPipeNets(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunPipeNet = new Queue<IPipeNet>(_pipeNets);
|
|
||||||
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunPipeNet.Count > 0)
|
|
||||||
{
|
|
||||||
var pipenet = _currentRunPipeNet.Dequeue();
|
|
||||||
pipenet.Update();
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_pipeNetLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_pipeNetLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual bool ProcessAtmosDevices(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
_stopwatch.Restart();
|
|
||||||
|
|
||||||
if(!resumed)
|
|
||||||
_currentRunAtmosDevices = new Queue<AtmosDeviceComponent>(_atmosDevices);
|
|
||||||
|
|
||||||
var time = _gameTiming.CurTime;
|
|
||||||
var updateEvent = new AtmosDeviceUpdateEvent(this);
|
|
||||||
var number = 0;
|
|
||||||
while (_currentRunAtmosDevices.Count > 0)
|
|
||||||
{
|
|
||||||
var device = _currentRunAtmosDevices.Dequeue();
|
|
||||||
Owner.EntityManager.EventBus.RaiseLocalEvent(device.Owner.Uid, updateEvent, false);
|
|
||||||
device.LastProcess = time;
|
|
||||||
|
|
||||||
if (number++ < LagCheckIterations) continue;
|
|
||||||
number = 0;
|
|
||||||
// Process the rest next time.
|
|
||||||
if (_stopwatch.Elapsed.TotalMilliseconds >= lagCheck)
|
|
||||||
{
|
|
||||||
_atmosDevicesLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_atmosDevicesLastProcess = _stopwatch.Elapsed.TotalMilliseconds;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual IEnumerable<AirtightComponent> GetObstructingComponents(Vector2i indices)
|
protected virtual IEnumerable<AirtightComponent> GetObstructingComponents(Vector2i indices)
|
||||||
{
|
{
|
||||||
var gridLookup = EntitySystem.Get<GridTileLookupSystem>();
|
var gridLookup = EntitySystem.Get<GridTileLookupSystem>();
|
||||||
|
|||||||
@@ -171,8 +171,6 @@ namespace Content.Server.Atmos.Components
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
Dictionary<AtmosDirection, TileAtmosphere> GetAdjacentTiles(Vector2i indices, bool includeAirBlocked = false);
|
Dictionary<AtmosDirection, TileAtmosphere> GetAdjacentTiles(Vector2i indices, bool includeAirBlocked = false);
|
||||||
|
|
||||||
void Update(float frameTime);
|
|
||||||
|
|
||||||
void AddPipeNet(IPipeNet pipeNet);
|
void AddPipeNet(IPipeNet pipeNet);
|
||||||
|
|
||||||
void RemovePipeNet(IPipeNet pipeNet);
|
void RemovePipeNet(IPipeNet pipeNet);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Content.Server.Atmos.Components
|
|||||||
|
|
||||||
public override void Invalidate(Vector2i indices) { }
|
public override void Invalidate(Vector2i indices) { }
|
||||||
|
|
||||||
protected override void Revalidate() { }
|
public override void Revalidate() { }
|
||||||
|
|
||||||
public override void FixVacuum(Vector2i indices) { }
|
public override void FixVacuum(Vector2i indices) { }
|
||||||
|
|
||||||
@@ -67,47 +67,5 @@ namespace Content.Server.Atmos.Components
|
|||||||
public override void AddAtmosDevice(AtmosDeviceComponent atmosDevice) { }
|
public override void AddAtmosDevice(AtmosDeviceComponent atmosDevice) { }
|
||||||
|
|
||||||
public override void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice) { }
|
public override void RemoveAtmosDevice(AtmosDeviceComponent atmosDevice) { }
|
||||||
|
|
||||||
public override void Update(float frameTime) { }
|
|
||||||
|
|
||||||
public override bool ProcessTileEqualize(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ProcessActiveTiles(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ProcessExcitedGroups(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ProcessHighPressureDelta(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool ProcessHotspots(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool ProcessSuperconductivity(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool ProcessPipeNets(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override bool ProcessAtmosDevices(bool resumed = false, float lagCheck = 5f)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
public bool ExcitedGroupsSpaceIsAllConsuming { get; private set; }
|
public bool ExcitedGroupsSpaceIsAllConsuming { get; private set; }
|
||||||
public float AtmosMaxProcessTime { get; private set; }
|
public float AtmosMaxProcessTime { get; private set; }
|
||||||
public float AtmosTickRate { get; private set; }
|
public float AtmosTickRate { get; private set; }
|
||||||
|
public float AtmosTime => 1f / AtmosTickRate;
|
||||||
|
|
||||||
private void InitializeCVars()
|
private void InitializeCVars()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,365 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Content.Server.Atmos.Components;
|
||||||
|
using Content.Server.Atmos.Piping.Components;
|
||||||
|
using Content.Server.NodeContainer.NodeGroups;
|
||||||
|
using Content.Shared.Atmos;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Server.Atmos.EntitySystems
|
||||||
|
{
|
||||||
|
public partial class AtmosphereSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||||
|
|
||||||
|
private readonly Stopwatch _simulationStopwatch = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check current execution time every n instances processed.
|
||||||
|
/// </summary>
|
||||||
|
private const int LagCheckIterations = 30;
|
||||||
|
|
||||||
|
private int _currentRunAtmosphereIndex = 0;
|
||||||
|
private bool _simulationPaused = false;
|
||||||
|
|
||||||
|
private readonly List<GridAtmosphereComponent> _currentRunAtmosphere = new();
|
||||||
|
|
||||||
|
private bool ProcessTileEqualize(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.ActiveTiles);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||||
|
{
|
||||||
|
tile.EqualizePressureInZone(atmosphere.UpdateCounter);
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessActiveTiles(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.ActiveTiles);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||||
|
{
|
||||||
|
tile.ProcessCell(atmosphere.UpdateCounter, SpaceWind);
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessExcitedGroups(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunExcitedGroups = new Queue<ExcitedGroup>(atmosphere.ExcitedGroups);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunExcitedGroups.TryDequeue(out var excitedGroup))
|
||||||
|
{
|
||||||
|
excitedGroup.BreakdownCooldown++;
|
||||||
|
excitedGroup.DismantleCooldown++;
|
||||||
|
|
||||||
|
if(excitedGroup.BreakdownCooldown > Atmospherics.ExcitedGroupBreakdownCycles)
|
||||||
|
excitedGroup.SelfBreakdown(ExcitedGroupsSpaceIsAllConsuming);
|
||||||
|
|
||||||
|
else if(excitedGroup.DismantleCooldown > Atmospherics.ExcitedGroupsDismantleCycles)
|
||||||
|
excitedGroup.Dismantle();
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessHighPressureDelta(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.HighPressureDelta);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var tile))
|
||||||
|
{
|
||||||
|
tile.HighPressureMovements();
|
||||||
|
tile.PressureDifference = 0f;
|
||||||
|
tile.PressureSpecificTarget = null;
|
||||||
|
atmosphere.HighPressureDelta.Remove(tile);
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessHotspots(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.HotspotTiles);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var hotspot))
|
||||||
|
{
|
||||||
|
hotspot.ProcessHotspot();
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessSuperconductivity(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunTiles = new Queue<TileAtmosphere>(atmosphere.SuperconductivityTiles);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunTiles.TryDequeue(out var superconductivity))
|
||||||
|
{
|
||||||
|
superconductivity.Superconduct();
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessPipeNets(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunPipeNet = new Queue<IPipeNet>(atmosphere.PipeNets);
|
||||||
|
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunPipeNet.TryDequeue(out var pipenet))
|
||||||
|
{
|
||||||
|
pipenet.Update();
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ProcessAtmosDevices(GridAtmosphereComponent atmosphere)
|
||||||
|
{
|
||||||
|
if(!atmosphere.ProcessingPaused)
|
||||||
|
atmosphere.CurrentRunAtmosDevices = new Queue<AtmosDeviceComponent>(atmosphere.AtmosDevices);
|
||||||
|
|
||||||
|
var time = _gameTiming.CurTime;
|
||||||
|
var updateEvent = new AtmosDeviceUpdateEvent(atmosphere);
|
||||||
|
var number = 0;
|
||||||
|
while (atmosphere.CurrentRunAtmosDevices.TryDequeue(out var device))
|
||||||
|
{
|
||||||
|
EntityManager.EventBus.RaiseLocalEvent(device.Owner.Uid, updateEvent, false);
|
||||||
|
device.LastProcess = time;
|
||||||
|
|
||||||
|
if (number++ < LagCheckIterations) continue;
|
||||||
|
number = 0;
|
||||||
|
// Process the rest next time.
|
||||||
|
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateProcessing(float frameTime)
|
||||||
|
{
|
||||||
|
_simulationStopwatch.Restart();
|
||||||
|
|
||||||
|
if (!_simulationPaused)
|
||||||
|
{
|
||||||
|
_currentRunAtmosphereIndex = 0;
|
||||||
|
_currentRunAtmosphere.Clear();
|
||||||
|
_currentRunAtmosphere.AddRange(ComponentManager.EntityQuery<GridAtmosphereComponent>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// We set this to true just in case we have to stop processing due to time constraints.
|
||||||
|
_simulationPaused = true;
|
||||||
|
|
||||||
|
for (; _currentRunAtmosphereIndex < _currentRunAtmosphere.Count; _currentRunAtmosphereIndex++)
|
||||||
|
{
|
||||||
|
var atmosphere = _currentRunAtmosphere[_currentRunAtmosphereIndex];
|
||||||
|
|
||||||
|
if (atmosphere.Paused || atmosphere.LifeStage >= ComponentLifeStage.Stopping)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
atmosphere.Timer += frameTime;
|
||||||
|
|
||||||
|
if (atmosphere.InvalidatedCoords.Count != 0)
|
||||||
|
atmosphere.Revalidate();
|
||||||
|
|
||||||
|
if (atmosphere.Timer < AtmosTime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We subtract it so it takes lost time into account.
|
||||||
|
atmosphere.Timer -= AtmosTime;
|
||||||
|
|
||||||
|
switch (atmosphere.State)
|
||||||
|
{
|
||||||
|
case AtmosphereProcessingState.TileEqualize:
|
||||||
|
if (!ProcessTileEqualize(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
atmosphere.State = AtmosphereProcessingState.ActiveTiles;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.ActiveTiles:
|
||||||
|
if (!ProcessActiveTiles(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
atmosphere.State = AtmosphereProcessingState.ExcitedGroups;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.ExcitedGroups:
|
||||||
|
if (!ProcessExcitedGroups(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
atmosphere.State = AtmosphereProcessingState.HighPressureDelta;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.HighPressureDelta:
|
||||||
|
if (!ProcessHighPressureDelta(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
atmosphere.State = AtmosphereProcessingState.Hotspots;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.Hotspots:
|
||||||
|
if (!ProcessHotspots(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
// Next state depends on whether superconduction 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 = Superconduction
|
||||||
|
? AtmosphereProcessingState.Superconductivity
|
||||||
|
: AtmosphereProcessingState.PipeNet;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.Superconductivity:
|
||||||
|
if (!ProcessSuperconductivity(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
atmosphere.State = AtmosphereProcessingState.PipeNet;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.PipeNet:
|
||||||
|
if (!ProcessPipeNets(atmosphere))
|
||||||
|
{
|
||||||
|
atmosphere.ProcessingPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
atmosphere.ProcessingPaused = false;
|
||||||
|
atmosphere.State = AtmosphereProcessingState.AtmosDevices;
|
||||||
|
continue;
|
||||||
|
case AtmosphereProcessingState.AtmosDevices:
|
||||||
|
if (!ProcessAtmosDevices(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;
|
||||||
|
|
||||||
|
// We reached the end of this atmosphere's update tick. Break out of the switch.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And increase the update counter.
|
||||||
|
atmosphere.UpdateCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We finished processing all atmospheres successfully, therefore we won't be paused next tick.
|
||||||
|
_simulationPaused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AtmosphereProcessingState : byte
|
||||||
|
{
|
||||||
|
TileEqualize,
|
||||||
|
ActiveTiles,
|
||||||
|
ExcitedGroups,
|
||||||
|
HighPressureDelta,
|
||||||
|
Hotspots,
|
||||||
|
Superconductivity,
|
||||||
|
PipeNet,
|
||||||
|
AtmosDevices,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -149,15 +149,10 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
{
|
{
|
||||||
base.Update(frameTime);
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
UpdateProcessing(frameTime);
|
||||||
|
|
||||||
_exposedTimer += frameTime;
|
_exposedTimer += frameTime;
|
||||||
|
|
||||||
foreach (var (mapGridComponent, gridAtmosphereComponent) in EntityManager.ComponentManager.EntityQuery<IMapGridComponent, IGridAtmosphereComponent>(true))
|
|
||||||
{
|
|
||||||
if (_pauseManager.IsGridPaused(mapGridComponent.GridIndex)) continue;
|
|
||||||
|
|
||||||
gridAtmosphereComponent.Update(frameTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_exposedTimer >= ExposedUpdateDelay)
|
if (_exposedTimer >= ExposedUpdateDelay)
|
||||||
{
|
{
|
||||||
foreach (var exposed in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>(true))
|
foreach (var exposed in EntityManager.ComponentManager.EntityQuery<AtmosExposedComponent>(true))
|
||||||
@@ -167,7 +162,7 @@ namespace Content.Server.Atmos.EntitySystems
|
|||||||
exposed.Update(tile, _exposedTimer);
|
exposed.Update(tile, _exposedTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_exposedTimer = 0;
|
_exposedTimer -= ExposedUpdateDelay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user