Fixed comments
ReagentUnit now implements IComparable and IEquateable. ReagentUnit now uses double internally. Added multiplication without shifting for ints. InvariantCulture for some string things. Added units tests for Equals and CompareTo. Added unit tests to Solution that deals with nasty fractionals.
This commit is contained in:
@@ -1,21 +1,23 @@
|
|||||||
using Robust.Shared.Interfaces.Serialization;
|
using Robust.Shared.Interfaces.Serialization;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Content.Shared.Chemistry
|
namespace Content.Shared.Chemistry
|
||||||
{
|
{
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public struct ReagentUnit : ISelfSerialize
|
public struct ReagentUnit : ISelfSerialize, IComparable<ReagentUnit>, IEquatable<ReagentUnit>
|
||||||
{
|
{
|
||||||
private int _value;
|
private int _value;
|
||||||
private static readonly int Shift = 2;
|
private static readonly int Shift = 2;
|
||||||
|
|
||||||
public static ReagentUnit MaxValue => new ReagentUnit(int.MaxValue);
|
public static ReagentUnit MaxValue => new ReagentUnit(int.MaxValue);
|
||||||
|
|
||||||
private decimal ShiftDown()
|
private double ShiftDown()
|
||||||
{
|
{
|
||||||
return _value / (decimal)Math.Pow(10, Shift);
|
return _value / Math.Pow(10, Shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReagentUnit(int value)
|
private ReagentUnit(int value)
|
||||||
@@ -55,7 +57,7 @@ namespace Content.Shared.Chemistry
|
|||||||
|
|
||||||
private static float FloatFromString(string value)
|
private static float FloatFromString(string value)
|
||||||
{
|
{
|
||||||
return float.Parse(value);
|
return float.Parse(value, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReagentUnit operator +(ReagentUnit a) => a;
|
public static ReagentUnit operator +(ReagentUnit a) => a;
|
||||||
@@ -82,11 +84,22 @@ namespace Content.Shared.Chemistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ReagentUnit operator *(ReagentUnit a, decimal b)
|
public static ReagentUnit operator *(ReagentUnit a, decimal b)
|
||||||
|
{
|
||||||
|
var aD = (decimal) a.ShiftDown();
|
||||||
|
return New(aD * b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReagentUnit operator *(ReagentUnit a, double b)
|
||||||
{
|
{
|
||||||
var aD = a.ShiftDown();
|
var aD = a.ShiftDown();
|
||||||
return New(aD * b);
|
return New(aD * b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ReagentUnit operator *(ReagentUnit a, int b)
|
||||||
|
{
|
||||||
|
return new ReagentUnit(a._value * b);
|
||||||
|
}
|
||||||
|
|
||||||
public static ReagentUnit operator /(ReagentUnit a, ReagentUnit b)
|
public static ReagentUnit operator /(ReagentUnit a, ReagentUnit b)
|
||||||
{
|
{
|
||||||
if (b._value == 0)
|
if (b._value == 0)
|
||||||
@@ -138,14 +151,17 @@ namespace Content.Shared.Chemistry
|
|||||||
return a._value > b._value;
|
return a._value > b._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => $"{ShiftDown()}";
|
|
||||||
|
|
||||||
public float Float()
|
public float Float()
|
||||||
{
|
{
|
||||||
return (float) ShiftDown();
|
return (float) ShiftDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public decimal Decimal()
|
public decimal Decimal()
|
||||||
|
{
|
||||||
|
return (decimal) ShiftDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double Double()
|
||||||
{
|
{
|
||||||
return ShiftDown();
|
return ShiftDown();
|
||||||
}
|
}
|
||||||
@@ -157,7 +173,12 @@ namespace Content.Shared.Chemistry
|
|||||||
|
|
||||||
public static ReagentUnit Min(params ReagentUnit[] reagentUnits)
|
public static ReagentUnit Min(params ReagentUnit[] reagentUnits)
|
||||||
{
|
{
|
||||||
return reagentUnits.OrderBy(x => x._value).First();
|
return reagentUnits.Min();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ReagentUnit Min(ReagentUnit a, ReagentUnit b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
@@ -176,9 +197,29 @@ namespace Content.Shared.Chemistry
|
|||||||
_value = FromFloat(FloatFromString(value));
|
_value = FromFloat(FloatFromString(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString() => $"{ShiftDown().ToString(CultureInfo.InvariantCulture)}";
|
||||||
|
|
||||||
public string Serialize()
|
public string Serialize()
|
||||||
{
|
{
|
||||||
return ToString();
|
return ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool Equals([AllowNull] ReagentUnit other)
|
||||||
|
{
|
||||||
|
return _value == other._value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareTo([AllowNull] ReagentUnit other)
|
||||||
|
{
|
||||||
|
if(other._value > _value)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(other._value < _value)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,5 +118,37 @@ namespace Content.Tests.Shared.Chemistry
|
|||||||
var result = (int) Math.Round(a * (float) Math.Pow(10, 2));
|
var result = (int) Math.Round(a * (float) Math.Pow(10, 2));
|
||||||
Assert.AreEqual(expected, result);
|
Assert.AreEqual(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void ReagentUnitMin()
|
||||||
|
{
|
||||||
|
var unorderedList = new[]
|
||||||
|
{
|
||||||
|
ReagentUnit.New(5),
|
||||||
|
ReagentUnit.New(3),
|
||||||
|
ReagentUnit.New(1),
|
||||||
|
ReagentUnit.New(2),
|
||||||
|
ReagentUnit.New(4),
|
||||||
|
};
|
||||||
|
var min = ReagentUnit.Min(unorderedList);
|
||||||
|
Assert.AreEqual(ReagentUnit.New(1), min);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[TestCase(1, 0, false)]
|
||||||
|
[TestCase(0, 0, true)]
|
||||||
|
[TestCase(-1, 0, false)]
|
||||||
|
[TestCase(null, 0, true)]
|
||||||
|
[TestCase(1, 1, true)]
|
||||||
|
[TestCase(0, 1, false)]
|
||||||
|
[TestCase(-1, 1, false)]
|
||||||
|
[TestCase(null, 1, false)]
|
||||||
|
public void ReagentUnitEquals(int a, int b, bool expected)
|
||||||
|
{
|
||||||
|
var parameter = ReagentUnit.New(a);
|
||||||
|
var comparison = ReagentUnit.New(b);
|
||||||
|
Assert.AreEqual(comparison.Equals(parameter), parameter.Equals(comparison));
|
||||||
|
Assert.AreEqual(expected, comparison.Equals(parameter));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,6 +203,41 @@ namespace Content.Tests.Shared.Chemistry
|
|||||||
Assert.That(splitSolution.TotalVolume.Int(), Is.EqualTo(750));
|
Assert.That(splitSolution.TotalVolume.Int(), Is.EqualTo(750));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void SplitSolutionFractional()
|
||||||
|
{
|
||||||
|
var solution = new Solution();
|
||||||
|
solution.AddReagent("water", ReagentUnit.New(1));
|
||||||
|
solution.AddReagent("fire", ReagentUnit.New(2));
|
||||||
|
|
||||||
|
var splitSolution = solution.SplitSolution(ReagentUnit.New(1));
|
||||||
|
|
||||||
|
Assert.That(solution.GetReagentQuantity("water").Float(), Is.EqualTo(0.67f));
|
||||||
|
Assert.That(solution.GetReagentQuantity("fire").Float(), Is.EqualTo(1.33f));
|
||||||
|
Assert.That(solution.TotalVolume.Int(), Is.EqualTo(2));
|
||||||
|
|
||||||
|
Assert.That(splitSolution.GetReagentQuantity("water").Float(), Is.EqualTo(0.33f));
|
||||||
|
Assert.That(splitSolution.GetReagentQuantity("fire").Float(), Is.EqualTo(0.67f));
|
||||||
|
Assert.That(splitSolution.TotalVolume.Int(), Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[TestCase(0.03f, 0.01f, 0.02f)]
|
||||||
|
[TestCase(0.03f, 0.02f, 0.01f)]
|
||||||
|
public void SplitSolutionTinyFractionalBigSmall(float initial, float reduce, float remainder)
|
||||||
|
{
|
||||||
|
var solution = new Solution();
|
||||||
|
solution.AddReagent("water", ReagentUnit.New(initial));
|
||||||
|
|
||||||
|
var splitSolution = solution.SplitSolution(ReagentUnit.New(reduce));
|
||||||
|
|
||||||
|
Assert.That(solution.GetReagentQuantity("water").Float(), Is.EqualTo(remainder));
|
||||||
|
Assert.That(solution.TotalVolume.Float(), Is.EqualTo(remainder));
|
||||||
|
|
||||||
|
Assert.That(splitSolution.GetReagentQuantity("water").Float(), Is.EqualTo(reduce));
|
||||||
|
Assert.That(splitSolution.TotalVolume.Float(), Is.EqualTo(reduce));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SplitSolutionMoreThanTotalRemovesAll()
|
public void SplitSolutionMoreThanTotalRemovesAll()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user