HashCalculator.GUI/AssetEntry.cs
2022-01-25 14:08:39 +01:00

189 lines
5.6 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using TechnologyAssembler.Core.Assets;
namespace HashCalculator.GUI
{
public class AssetEntry : IEquatable<AssetEntry>, IComparable<AssetEntry>
{
public string Type { get; }
public string Name { get; }
public string NameString { get; }
public IReadOnlyList<string> DisplayLabels { get; }
public uint InstanceId { get; }
public uint TypeId { get; }
public string InstanceIdString { get; }
public string TypeIdString { get; }
public string LocalizedNames
{
get
{
if (!Translator.HasProvider)
{
return string.Empty;
}
if (!DisplayLabels.Any())
{
return "N/A";
}
return DisplayLabels.Select(Translator.Translate).Aggregate((x, y) => $"{x} {y}");
}
}
public static AssetEntry? TryParse(XElement element)
{
if (element == null)
{
return null;
}
if (element.Name.Namespace != ModXml.EalaAsset)
{
TracerListener.WriteLine($"Unknown namespace: {element.Name.Namespace}");
}
try
{
return new AssetEntry(element);
}
catch (Exception e)
{
TracerListener.WriteLine($"Failed to parse element: {e}");
}
return null;
}
public AssetEntry(XElement element)
{
if (element == null)
{
throw new ArgumentNullException(nameof(element));
}
if (element.Name.Namespace != ModXml.EalaAsset)
{
throw new NotSupportedException();
}
Type = element.Name.LocalName;
var id = element.Attribute("id")?.Value;
Name = id ?? throw new NotSupportedException();
NameString = $"{Type}:{Name}";
var labels = from name in element.Elements(ModXml.EalaAsset + "DisplayName")
select name.Value;
var transformLabels = from name in element.Elements(ModXml.EalaAsset + "DisplayNameTransformed")
select name.Value;
DisplayLabels = labels.Concat(transformLabels).ToArray();
InstanceId = SageHash.CalculateLowercaseHash(Name);
TypeId = SageHash.CalculateBinaryHash(Type);
InstanceIdString = $"{InstanceId:x8} ({InstanceId,10})";
TypeIdString = $"{TypeId:x8} ({TypeId,10})";
}
public AssetEntry(Asset asset)
{
if (asset is null)
{
throw new ArgumentNullException(nameof(asset));
}
Type = asset.TypeName;
Name = asset.InstanceName;
NameString = $"{Type}:{Name}";
DisplayLabels = Array.Empty<string>();
InstanceId = SageHash.CalculateLowercaseHash(Name);
TypeId = SageHash.CalculateBinaryHash(Type);
if (InstanceId != asset.InstanceId || TypeId != asset.TypeId)
{
throw new InvalidDataException();
}
InstanceIdString = $"{InstanceId:x8} ({InstanceId,10})";
TypeIdString = $"{TypeId:x8} ({TypeId,10})";
}
public bool Equals(AssetEntry? entry)
{
return this == entry;
}
// override object.Equals
public override bool Equals(object? obj)
{
//
// See the full list of guidelines at
// http://go.microsoft.com/fwlink/?LinkID=85237
// and also the guidance for operator== at
// http://go.microsoft.com/fwlink/?LinkId=85238
//
if (!(obj is AssetEntry entry))
{
return false;
}
return this == entry;
}
public static bool operator ==(AssetEntry? a, AssetEntry? b)
{
if (a is null || b is null)
{
return a is null == b is null;
}
if (ReferenceEquals(a, b))
{
return true;
}
return a.Type == b.Type && a.InstanceId == b.InstanceId;
}
public static bool operator !=(AssetEntry? a, AssetEntry? b)
{
return !(a == b);
}
// override object.GetHashCode
public override int GetHashCode()
{
return HashCode.Combine(Type, InstanceId);
}
public int CompareTo(AssetEntry? other)
{
if (other is null)
{
throw new ArgumentNullException(nameof(other));
}
return string.CompareOrdinal(NameString, other.NameString);
}
public static bool operator <(AssetEntry? left, AssetEntry? right)
{
return left is null ? right is object : left.CompareTo(right) < 0;
}
public static bool operator <=(AssetEntry? left, AssetEntry? right)
{
return left is null || left.CompareTo(right) <= 0;
}
public static bool operator >(AssetEntry? left, AssetEntry? right)
{
return left is object && left.CompareTo(right) > 0;
}
public static bool operator >=(AssetEntry? left, AssetEntry? right)
{
return left is null ? right is null : left.CompareTo(right) >= 0;
}
}
}