#nullable enable
using System.Collections.Generic;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Content.Shared.Alert
{
///
/// Defines the order of alerts so they show up in a consistent order.
///
[Prototype("alertOrder")]
public class AlertOrderPrototype : IPrototype, IComparer
{
public string ID { get; private set; } = string.Empty;
private readonly Dictionary _typeToIdx = new();
private readonly Dictionary _categoryToIdx = new();
public void LoadFrom(YamlMappingNode mapping)
{
var serializer = YamlObjectSerializer.NewReader(mapping);
serializer.DataField(this, x => x.ID, "id", string.Empty);
if (!mapping.TryGetNode("order", out YamlSequenceNode? orderMapping)) return;
var i = 0;
foreach (var entryYaml in orderMapping)
{
var orderEntry = (YamlMappingNode) entryYaml;
var orderSerializer = YamlObjectSerializer.NewReader(orderEntry);
if (orderSerializer.TryReadDataField("category", out AlertCategory alertCategory))
{
_categoryToIdx[alertCategory] = i++;
}
else if (orderSerializer.TryReadDataField("alertType", out AlertType alertType))
{
_typeToIdx[alertType] = i++;
}
}
}
private int GetOrderIndex(AlertPrototype alert)
{
if (_typeToIdx.TryGetValue(alert.AlertType, out var idx))
{
return idx;
}
if (alert.Category != null &&
_categoryToIdx.TryGetValue((AlertCategory) alert.Category, out idx))
{
return idx;
}
return -1;
}
public int Compare(AlertPrototype? x, AlertPrototype? y)
{
if ((x == null) && (y == null)) return 0;
if (x == null) return 1;
if (y == null) return -1;
var idx = GetOrderIndex(x);
var idy = GetOrderIndex(y);
if (idx == -1 && idy == -1)
{
// break ties by type value
return x.AlertType - y.AlertType;
}
if (idx == -1) return 1;
if (idy == -1) return -1;
var result = idx - idy;
// not strictly necessary (we don't care about ones that go at the same index)
// but it makes the sort stable
if (result == 0)
{
// break ties by type value
return x.AlertType - y.AlertType;
}
return result;
}
}
}