Make GasMixture enumerable
I noticed that enumerating gases is frequently done in an annoying way with Enum.GetValues. So I made it better. Now GasMixture is IEnumerable<(Gas gas, float moles)> and it just works.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Collections;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Content.Shared.Atmos.EntitySystems;
|
using Content.Shared.Atmos.EntitySystems;
|
||||||
@@ -13,12 +14,12 @@ namespace Content.Shared.Atmos
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[DataDefinition]
|
[DataDefinition]
|
||||||
public sealed partial class GasMixture : IEquatable<GasMixture>, ISerializationHooks
|
public sealed partial class GasMixture : IEquatable<GasMixture>, ISerializationHooks, IEnumerable<(Gas gas, float moles)>
|
||||||
{
|
{
|
||||||
public static GasMixture SpaceGas => new() {Volume = Atmospherics.CellVolume, Temperature = Atmospherics.TCMB, Immutable = true};
|
public static GasMixture SpaceGas => new() {Volume = Atmospherics.CellVolume, Temperature = Atmospherics.TCMB, Immutable = true};
|
||||||
|
|
||||||
// No access, to ensure immutable mixtures are never accidentally mutated.
|
// No access, to ensure immutable mixtures are never accidentally mutated.
|
||||||
[Access(typeof(SharedAtmosphereSystem), typeof(SharedAtmosDebugOverlaySystem), Other = AccessPermissions.None)]
|
[Access(typeof(SharedAtmosphereSystem), typeof(SharedAtmosDebugOverlaySystem), typeof(GasEnumerator), Other = AccessPermissions.None)]
|
||||||
[DataField]
|
[DataField]
|
||||||
public float[] Moles = new float[Atmospherics.AdjustedNumberOfGases];
|
public float[] Moles = new float[Atmospherics.AdjustedNumberOfGases];
|
||||||
|
|
||||||
@@ -249,6 +250,16 @@ namespace Content.Shared.Atmos
|
|||||||
return new GasMixtureStringRepresentation(TotalMoles, Temperature, Pressure, molesPerGas);
|
return new GasMixtureStringRepresentation(TotalMoles, Temperature, Pressure, molesPerGas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GasEnumerator GetEnumerator()
|
||||||
|
{
|
||||||
|
return new GasEnumerator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator<(Gas gas, float moles)> IEnumerable<(Gas gas, float moles)>.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
if (obj is GasMixture mix)
|
if (obj is GasMixture mix)
|
||||||
@@ -289,6 +300,11 @@ namespace Content.Shared.Atmos
|
|||||||
return hashCode.ToHashCode();
|
return hashCode.ToHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
public GasMixture Clone()
|
public GasMixture Clone()
|
||||||
{
|
{
|
||||||
if (Immutable)
|
if (Immutable)
|
||||||
@@ -302,5 +318,28 @@ namespace Content.Shared.Atmos
|
|||||||
};
|
};
|
||||||
return newMixture;
|
return newMixture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct GasEnumerator(GasMixture mixture) : IEnumerator<(Gas gas, float moles)>
|
||||||
|
{
|
||||||
|
private int _idx = -1;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
// Nada.
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool MoveNext()
|
||||||
|
{
|
||||||
|
return ++_idx < Atmospherics.TotalNumberOfGases;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_idx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (Gas gas, float moles) Current => ((Gas)_idx, mixture.Moles[_idx]);
|
||||||
|
object? IEnumerator.Current => Current;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
30
Content.Tests/Shared/Atmos/GasMixtureTest.cs
Normal file
30
Content.Tests/Shared/Atmos/GasMixtureTest.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using Content.Shared.Atmos;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace Content.Tests.Shared.Atmos;
|
||||||
|
|
||||||
|
[TestFixture, TestOf(typeof(GasMixture))]
|
||||||
|
[Parallelizable(ParallelScope.All)]
|
||||||
|
public sealed class GasMixtureTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestEnumerate()
|
||||||
|
{
|
||||||
|
var mixture = new GasMixture();
|
||||||
|
mixture.SetMoles(Gas.Oxygen, 20);
|
||||||
|
mixture.SetMoles(Gas.Nitrogen, 10);
|
||||||
|
mixture.SetMoles(Gas.Plasma, 80);
|
||||||
|
|
||||||
|
var expectedList = new (Gas, float)[Atmospherics.TotalNumberOfGases];
|
||||||
|
for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++)
|
||||||
|
{
|
||||||
|
expectedList[i].Item1 = (Gas)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedList[(int)Gas.Oxygen].Item2 = 20f;
|
||||||
|
expectedList[(int)Gas.Nitrogen].Item2 = 10f;
|
||||||
|
expectedList[(int)Gas.Plasma].Item2 = 80f;
|
||||||
|
|
||||||
|
Assert.That(mixture, Is.EquivalentTo(expectedList));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user