189 lines
5.6 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|