]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
AddMolsToMixture atmos helper (#42033)
authorArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Wed, 24 Dec 2025 08:15:10 +0000 (00:15 -0800)
committerGitHub <noreply@github.com>
Wed, 24 Dec 2025 08:15:10 +0000 (00:15 -0800)
Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs
Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs [new file with mode: 0644]

index 0c6a3a7daa5254e94b5effc6334aee5b543d9134..95d56c9ca63205725d73f9385a883cba1f1a3597 100644 (file)
@@ -3,6 +3,7 @@ using System.Runtime.CompilerServices;
 using Content.Server.Atmos.Reactions;
 using Content.Shared.Atmos;
 using Content.Shared.Atmos.Reactions;
+using JetBrains.Annotations;
 using Robust.Shared.Prototypes;
 using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
 
@@ -477,6 +478,26 @@ namespace Content.Server.Atmos.EntitySystems
             return reaction;
         }
 
+        /// <summary>
+        /// Adds an array of moles to a <see cref="GasMixture"/>.
+        /// Guards against negative moles by clamping to zero.
+        /// </summary>
+        /// <param name="mixture">The <see cref="GasMixture"/> to add moles to.</param>
+        /// <param name="molsToAdd">The <see cref="ReadOnlySpan{T}"/> of moles to add.</param>
+        /// <exception cref="ArgumentOutOfRangeException">Thrown when the length of the <see cref="ReadOnlySpan{T}"/>
+        /// is not the same as the length of the <see cref="GasMixture"/> gas array.</exception>
+        [PublicAPI]
+        public static void AddMolsToMixture(GasMixture mixture, ReadOnlySpan<float> molsToAdd)
+        {
+            // Span length should be as long as the length of the gas array.
+            // Technically this is a redundant check because NumericsHelpers will do the same thing,
+            // but eh.
+            ArgumentOutOfRangeException.ThrowIfNotEqual(mixture.Moles.Length, molsToAdd.Length, nameof(mixture.Moles.Length));
+
+            NumericsHelpers.Add(mixture.Moles, molsToAdd);
+            NumericsHelpers.Max(mixture.Moles, 0f);
+        }
+
         public enum GasCompareResult
         {
             NoExchange = -2,
diff --git a/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs b/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs
new file mode 100644 (file)
index 0000000..07b45bf
--- /dev/null
@@ -0,0 +1,75 @@
+using System;
+using Content.Server.Atmos.EntitySystems;
+using Content.Shared.Atmos;
+using NUnit.Framework;
+
+namespace Content.Tests.Server.Atmos;
+
+[TestFixture, TestOf(typeof(AtmosphereSystem))]
+[Parallelizable(ParallelScope.All)]
+public sealed class AddMolsToMixtureTest
+{
+    /// <summary>
+    /// Assert that an exception is thrown if the length of the array passed in
+    /// does not match the number of gases.
+    /// </summary>
+    [Test]
+    [TestCase(-1)]
+    [TestCase(1)]
+    public void AddMolsToMixture_Throws_OnLengthMismatch(int num)
+    {
+        var mixture = new GasMixture();
+        var wrongLength = new float[Atmospherics.AdjustedNumberOfGases + num];
+
+        var ex = Assert.Throws<ArgumentOutOfRangeException>(() =>
+            AtmosphereSystem.AddMolsToMixture(mixture, wrongLength));
+
+        Assert.That(ex!.ParamName, Is.EqualTo("Length"));
+    }
+
+    /// <summary>
+    /// Assert that the added mols are correctly added.
+    /// </summary>
+    [Test]
+    public void AddMolsToMixture_Adds_CheckElementwise()
+    {
+        var mixture = new GasMixture();
+        mixture.SetMoles(Gas.Oxygen, 1f);
+        mixture.SetMoles(Gas.Nitrogen, 2f);
+
+        var add = new float[Atmospherics.AdjustedNumberOfGases];
+        add[(int)Gas.Oxygen] = 3f;
+        add[(int)Gas.Nitrogen] = 4f;
+
+        AtmosphereSystem.AddMolsToMixture(mixture, add);
+
+        using (Assert.EnterMultipleScope())
+        {
+            Assert.That(mixture.GetMoles(Gas.Oxygen), Is.EqualTo(4f));
+            Assert.That(mixture.GetMoles(Gas.Nitrogen), Is.EqualTo(6f));
+        }
+    }
+
+    /// <summary>
+    /// Assert that the added mols are correctly clamped at zero.
+    /// </summary>
+    [Test]
+    public void AddMolsToMixture_EnsureClamp()
+    {
+        var mixture = new GasMixture();
+        mixture.SetMoles(Gas.Oxygen, 1f);
+        mixture.SetMoles(Gas.Nitrogen, 2f);
+
+        var add = new float[Atmospherics.AdjustedNumberOfGases];
+        add[(int)Gas.Oxygen] = -2f; // would go to -1 without clamping
+        add[(int)Gas.Nitrogen] = -1f; // should become 1
+
+        AtmosphereSystem.AddMolsToMixture(mixture, add);
+
+        using (Assert.EnterMultipleScope())
+        {
+            Assert.That(mixture.GetMoles(Gas.Oxygen), Is.Zero);
+            Assert.That(mixture.GetMoles(Gas.Nitrogen), Is.EqualTo(1f));
+        }
+    }
+}