]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add LocalizedDatasetPrototype (#28310)
authorTayrtahn <tayrtahn@gmail.com>
Tue, 28 May 2024 18:41:41 +0000 (14:41 -0400)
committerGitHub <noreply@github.com>
Tue, 28 May 2024 18:41:41 +0000 (14:41 -0400)
Content.Shared/Dataset/LocalizedDatasetPrototype.cs [new file with mode: 0644]
Content.Shared/Random/Helpers/SharedRandomExtensions.cs
Content.Tests/Shared/LocalizedDatasetPrototypeTest.cs [new file with mode: 0644]

diff --git a/Content.Shared/Dataset/LocalizedDatasetPrototype.cs b/Content.Shared/Dataset/LocalizedDatasetPrototype.cs
new file mode 100644 (file)
index 0000000..8be9967
--- /dev/null
@@ -0,0 +1,94 @@
+using System.Collections;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Dataset;
+
+/// <summary>
+/// A variant of <see cref="DatasetPrototype"/> intended to specify a sequence of LocId strings
+/// without having to copy-paste a ton of LocId strings into the YAML.
+/// </summary>
+[Prototype]
+public sealed partial class LocalizedDatasetPrototype : IPrototype
+{
+    /// <summary>
+    /// Identifier for this prototype.
+    /// </summary>
+    [ViewVariables]
+    [IdDataField]
+    public string ID { get; private set; } = default!;
+
+    /// <summary>
+    /// Collection of LocId strings.
+    /// </summary>
+    [DataField]
+    public LocalizedDatasetValues Values { get; private set; } = [];
+}
+
+[Serializable, NetSerializable]
+[DataDefinition]
+public sealed partial class LocalizedDatasetValues : IReadOnlyList<string>
+{
+    /// <summary>
+    /// String prepended to the index number to generate each LocId string.
+    /// For example, a prefix of <c>tips-dataset-</c> will generate <c>tips-dataset-1</c>,
+    /// <c>tips-dataset-2</c>, etc.
+    /// </summary>
+    [DataField(required: true)]
+    public string Prefix { get; private set; } = default!;
+
+    /// <summary>
+    /// How many values are in the dataset.
+    /// </summary>
+    [DataField(required: true)]
+    public int Count { get; private set; }
+
+    public string this[int index]
+    {
+        get
+        {
+            if (index > Count || index < 0)
+                throw new IndexOutOfRangeException();
+            return Prefix + index;
+        }
+    }
+
+    public IEnumerator<string> GetEnumerator()
+    {
+        return new Enumerator(this);
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+        return GetEnumerator();
+    }
+
+    public sealed class Enumerator : IEnumerator<string>
+    {
+        private int _index = 0; // Whee, 1-indexing
+
+        private readonly LocalizedDatasetValues _values;
+
+        public Enumerator(LocalizedDatasetValues values)
+        {
+            _values = values;
+        }
+
+        public string Current => _values.Prefix + _index;
+
+        object IEnumerator.Current => Current;
+
+        public void Dispose() { }
+
+        public bool MoveNext()
+        {
+            _index++;
+            return _index <= _values.Count;
+        }
+
+        public void Reset()
+        {
+            _index = 0;
+        }
+    }
+}
index 20e57e94212803603b7a74d019f947dcd38e49fe..f5fbc1bd24e830147bddc25b1290b8580041d9a2 100644 (file)
@@ -12,6 +12,11 @@ namespace Content.Shared.Random.Helpers
             return random.Pick(prototype.Values);
         }
 
+        public static string Pick(this IRobustRandom random, LocalizedDatasetPrototype prototype)
+        {
+            return random.Pick(prototype.Values);
+        }
+
         public static string Pick(this IWeightedRandomPrototype prototype, System.Random random)
         {
             var picks = prototype.Weights;
diff --git a/Content.Tests/Shared/LocalizedDatasetPrototypeTest.cs b/Content.Tests/Shared/LocalizedDatasetPrototypeTest.cs
new file mode 100644 (file)
index 0000000..0ec4c07
--- /dev/null
@@ -0,0 +1,59 @@
+using System;
+using Content.Shared.Dataset;
+using NUnit.Framework;
+using Robust.Shared.Collections;
+using Robust.Shared.IoC;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.Manager;
+
+namespace Content.Tests.Shared;
+
+[TestFixture]
+[TestOf(typeof(LocalizedDatasetPrototype))]
+public sealed class LocalizedDatasetPrototypeTest : ContentUnitTest
+{
+    private IPrototypeManager _prototypeManager;
+
+    [OneTimeSetUp]
+    public void OneTimeSetup()
+    {
+        IoCManager.Resolve<ISerializationManager>().Initialize();
+        _prototypeManager = IoCManager.Resolve<IPrototypeManager>();
+        _prototypeManager.Initialize();
+        _prototypeManager.LoadString(TestPrototypes);
+        _prototypeManager.ResolveResults();
+    }
+
+    private const string TestPrototypes = @"
+- type: localizedDataset
+  id: Test
+  values:
+    prefix: test-dataset-
+    count: 4
+";
+
+    [Test]
+    public void LocalizedDatasetTest()
+    {
+        var testPrototype = _prototypeManager.Index<LocalizedDatasetPrototype>("Test");
+        var values = new ValueList<string>();
+        foreach (var value in testPrototype.Values)
+        {
+            values.Add(value);
+        }
+
+        // Make sure we get the right number of values
+        Assert.That(values, Has.Count.EqualTo(4));
+
+        // Make sure indexing works as expected
+        Assert.That(values[0], Is.EqualTo("test-dataset-1"));
+        Assert.That(values[1], Is.EqualTo("test-dataset-2"));
+        Assert.That(values[2], Is.EqualTo("test-dataset-3"));
+        Assert.That(values[3], Is.EqualTo("test-dataset-4"));
+        Assert.Throws<IndexOutOfRangeException>(() => { var x = values[4]; });
+        Assert.Throws<IndexOutOfRangeException>(() => { var x = values[-1]; });
+
+        // Make sure that the enumerator gets all of the values
+        Assert.That(testPrototype.Values[testPrototype.Values.Count], Is.EqualTo("test-dataset-4"));
+    }
+}