Skip to content

Commit

Permalink
Add LocalizedDatasetPrototype (space-wizards#28310)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tayrtahn authored May 28, 2024
1 parent 7b93b0c commit 0bca934
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
94 changes: 94 additions & 0 deletions Content.Shared/Dataset/LocalizedDatasetPrototype.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
5 changes: 5 additions & 0 deletions Content.Shared/Random/Helpers/SharedRandomExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public static string Pick(this IRobustRandom random, DatasetPrototype prototype)
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;
Expand Down
59 changes: 59 additions & 0 deletions Content.Tests/Shared/LocalizedDatasetPrototypeTest.cs
Original file line number Diff line number Diff line change
@@ -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"));
}
}

0 comments on commit 0bca934

Please sign in to comment.