Flatten Instance out of existence

This commit is contained in:
Matt Nadareski
2026-04-09 21:34:00 -04:00
parent 27a93fa86a
commit 967d9ffe87
17 changed files with 58 additions and 283 deletions

View File

@@ -2763,7 +2763,6 @@ namespace SabreTools.Data.Extensions.Test
[InlineData("file", ItemType.File)]
[InlineData("info", ItemType.Info)]
[InlineData("input", ItemType.Input)]
[InlineData("instance", ItemType.Instance)]
[InlineData("media", ItemType.Media)]
[InlineData("part", ItemType.Part)]
[InlineData("partfeature", ItemType.PartFeature)]
@@ -3164,7 +3163,6 @@ namespace SabreTools.Data.Extensions.Test
[InlineData(ItemType.File, "file")]
[InlineData(ItemType.Info, "info")]
[InlineData(ItemType.Input, "input")]
[InlineData(ItemType.Instance, "instance")]
[InlineData(ItemType.Media, "media")]
[InlineData(ItemType.Part, "part")]
[InlineData(ItemType.PartFeature, "part_feature")]

View File

@@ -927,7 +927,6 @@ namespace SabreTools.Data.Extensions
"feature" => ItemType.Feature,
"info" => ItemType.Info,
"input" => ItemType.Input,
"instance" => ItemType.Instance,
"original" => ItemType.Original,
"part" => ItemType.Part,
"part_feature" or "partfeature" => ItemType.PartFeature,
@@ -1410,7 +1409,6 @@ namespace SabreTools.Data.Extensions
ItemType.Feature => "feature",
ItemType.Info => "info",
ItemType.Input => "input",
ItemType.Instance => "instance",
ItemType.Original => "original",
ItemType.Part => "part",
ItemType.PartFeature => "part_feature",

View File

@@ -16,7 +16,9 @@ namespace SabreTools.Data.Models.Metadata
public string? FixedImage { get; set; }
public Instance? Instance { get; set; }
public string? InstanceBriefName { get; set; }
public string? InstanceName { get; set; }
public string? Interface { get; set; }
@@ -38,7 +40,8 @@ namespace SabreTools.Data.Models.Metadata
if (Extension is not null)
obj.Extension = Array.ConvertAll(Extension, i => (Extension)i.Clone());
obj.FixedImage = FixedImage;
obj.Instance = Instance?.Clone() as Instance;
obj.InstanceBriefName = InstanceBriefName;
obj.InstanceName = InstanceName;
obj.Interface = Interface;
obj.Mandatory = Mandatory;
obj.Tag = Tag;
@@ -62,6 +65,16 @@ namespace SabreTools.Data.Models.Metadata
else if (FixedImage is not null && !FixedImage.Equals(other.FixedImage, StringComparison.OrdinalIgnoreCase))
return false;
if ((InstanceBriefName is null) ^ (other.InstanceBriefName is null))
return false;
else if (InstanceBriefName is not null && !InstanceBriefName.Equals(other.InstanceBriefName, StringComparison.OrdinalIgnoreCase))
return false;
if ((InstanceName is null) ^ (other.InstanceName is null))
return false;
else if (InstanceName is not null && !InstanceName.Equals(other.InstanceName, StringComparison.OrdinalIgnoreCase))
return false;
if ((Interface is null) ^ (other.Interface is null))
return false;
else if (Interface is not null && !Interface.Equals(other.Interface, StringComparison.OrdinalIgnoreCase))
@@ -75,12 +88,6 @@ namespace SabreTools.Data.Models.Metadata
else if (Tag is not null && !Tag.Equals(other.Tag, StringComparison.OrdinalIgnoreCase))
return false;
// Sub-items
if ((Instance is null) ^ (other.Instance is null))
return false;
else if (Instance is not null && other.Instance is not null && Instance.Equals(other.Instance))
return false;
// TODO: Figure out how to properly check arrays
return true;

View File

@@ -296,7 +296,6 @@ namespace SabreTools.Data.Models.Metadata
File, // TODO: This should be merged with Rom?
Info,
Input,
Instance,
Media,
Original,
Part,

View File

@@ -1,52 +0,0 @@
using System;
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Data.Models.Metadata
{
[JsonObject("instance"), XmlRoot("instance")]
public class Instance : DatItem, ICloneable, IEquatable<Instance>
{
#region Properties
public string? BriefName { get; set; }
public string? Name { get; set; }
#endregion
public Instance() => ItemType = ItemType.Instance;
/// <inheritdoc/>
public object Clone()
{
var obj = new Instance();
obj.BriefName = BriefName;
obj.Name = Name;
return obj;
}
/// <inheritdoc/>
public bool Equals(Instance? other)
{
// Null never matches
if (other is null)
return false;
// Properties
if ((BriefName is null) ^ (other.BriefName is null))
return false;
else if (BriefName is not null && !BriefName.Equals(other.BriefName, StringComparison.OrdinalIgnoreCase))
return false;
if ((Name is null) ^ (other.Name is null))
return false;
else if (Name is not null && !Name.Equals(other.Name, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
}
}

View File

@@ -491,7 +491,8 @@ namespace SabreTools.Metadata.DatFiles.Test
{
Extension = [CreateMetadataExtension()],
FixedImage = "fixedimage",
Instance = CreateMetadataInstance(),
InstanceBriefName = "briefname",
InstanceName = "name",
Interface = "interface",
Mandatory = true,
Tag = "tag",
@@ -686,15 +687,6 @@ namespace SabreTools.Metadata.DatFiles.Test
};
}
private static Data.Models.Metadata.Instance CreateMetadataInstance()
{
return new Data.Models.Metadata.Instance
{
BriefName = "briefname",
Name = "name",
};
}
private static Data.Models.Metadata.Media CreateMetadataMedia()
{
return new Data.Models.Metadata.Media
@@ -1247,6 +1239,8 @@ namespace SabreTools.Metadata.DatFiles.Test
{
Assert.NotNull(device);
Assert.Equal("fixedimage", device.FixedImage);
Assert.Equal("briefname", device.InstanceBriefName);
Assert.Equal("name", device.InstanceName);
Assert.Equal("interface", device.Interface);
Assert.Equal(true, device.Mandatory);
Assert.Equal("tag", device.Tag);
@@ -1256,8 +1250,6 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.NotNull(extensions);
Extension? extension = Assert.Single(extensions);
ValidateExtension(extension);
ValidateInstance(device.Instance);
}
private static void ValidateDeviceRef(DeviceRef? deviceRef)
@@ -1411,13 +1403,6 @@ namespace SabreTools.Metadata.DatFiles.Test
ValidateControl(control);
}
private static void ValidateInstance(Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("briefname", instance.BriefName);
Assert.Equal("name", instance.Name);
}
private static void ValidateMedia(Media? media)
{
Assert.NotNull(media);

View File

@@ -760,6 +760,8 @@ namespace SabreTools.Metadata.DatFiles.Test
{
Assert.NotNull(device);
Assert.Equal("fixedimage", device.FixedImage);
Assert.Equal("briefname", device.InstanceBriefName);
Assert.Equal("name", device.InstanceName);
Assert.Equal("interface", device.Interface);
Assert.Equal(true, device.Mandatory);
Assert.Equal("tag", device.Tag);
@@ -769,8 +771,6 @@ namespace SabreTools.Metadata.DatFiles.Test
Assert.NotNull(extensions);
Data.Models.Metadata.Extension? extension = Assert.Single(extensions);
ValidateMetadataExtension(extension);
ValidateMetadataInstance(device.Instance);
}
private static void ValidateMetadataDeviceRef(Data.Models.Metadata.DeviceRef? deviceRef)
@@ -929,13 +929,6 @@ namespace SabreTools.Metadata.DatFiles.Test
ValidateMetadataControl(control);
}
private static void ValidateMetadataInstance(Data.Models.Metadata.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("briefname", instance.BriefName);
Assert.Equal("name", instance.Name);
}
private static void ValidateMetadataMedia(Data.Models.Metadata.Media? media)
{
Assert.NotNull(media);

View File

@@ -330,9 +330,6 @@ namespace SabreTools.Metadata.DatFiles.Formats
case Data.Models.Metadata.ItemType.Input:
datItem = datItemObj.ToObject<Input>();
break;
case Data.Models.Metadata.ItemType.Instance:
datItem = datItemObj.ToObject<Instance>();
break;
case Data.Models.Metadata.ItemType.Media:
datItem = datItemObj.ToObject<Media>();
break;

View File

@@ -35,7 +35,6 @@ namespace SabreTools.Metadata.DatItems
[XmlInclude(typeof(Feature))]
[XmlInclude(typeof(Info))]
[XmlInclude(typeof(Input))]
[XmlInclude(typeof(Instance))]
[XmlInclude(typeof(Media))]
[XmlInclude(typeof(Part))]
[XmlInclude(typeof(PartFeature))]

View File

@@ -30,10 +30,17 @@ namespace SabreTools.Metadata.DatItems.Formats
set => _internal.FixedImage = value;
}
public Instance? Instance { get; set; }
public string? InstanceBriefName
{
get => _internal.InstanceBriefName;
set => _internal.InstanceBriefName = value;
}
[JsonIgnore]
public bool InstanceSpecified => Instance is not null;
public string? InstanceName
{
get => _internal.InstanceName;
set => _internal.InstanceName = value;
}
public string? Interface
{
@@ -67,10 +74,7 @@ namespace SabreTools.Metadata.DatItems.Formats
{
// Handle subitems
if (item.Extension is not null)
Extension = Array.ConvertAll(item.Extension, extension => new Extension(extension)); ;
if (item.Instance is not null)
Instance = new Instance(item.Instance);
Extension = Array.ConvertAll(item.Extension, extension => new Extension(extension));
}
public Device(Data.Models.Metadata.Device item, Machine machine, Source source) : this(item)
@@ -101,9 +105,6 @@ namespace SabreTools.Metadata.DatItems.Formats
{
var deviceItem = _internal.Clone() as Data.Models.Metadata.Device ?? new();
if (Instance is not null)
deviceItem.Instance = Instance.GetInternalClone();
if (Extension is not null)
deviceItem.Extension = Array.ConvertAll(Extension, extension => extension.GetInternalClone()); ;
@@ -139,7 +140,6 @@ namespace SabreTools.Metadata.DatItems.Formats
if (Machine is not null && !Machine.PassesFilter(filterRunner))
return false;
// TODO: Instance
// TODO: Extension
return filterRunner.Run(_internal);
@@ -148,7 +148,6 @@ namespace SabreTools.Metadata.DatItems.Formats
/// <inheritdoc/>
public override bool PassesFilterDB(FilterRunner filterRunner)
{
// TODO: Instance
// TODO: Extension
return filterRunner.Run(_internal);

View File

@@ -1,86 +0,0 @@
using System.Xml.Serialization;
using Newtonsoft.Json;
namespace SabreTools.Metadata.DatItems.Formats
{
/// <summary>
/// Represents a single instance of another item
/// </summary>
[JsonObject("instance"), XmlRoot("instance")]
public sealed class Instance : DatItem<Data.Models.Metadata.Instance>
{
#region Properties
public string? BriefName
{
get => _internal.BriefName;
set => _internal.BriefName = value;
}
/// <inheritdoc>/>
public override Data.Models.Metadata.ItemType ItemType
=> Data.Models.Metadata.ItemType.Instance;
public string? Name
{
get => _internal.Name;
set => _internal.Name = value;
}
#endregion
#region Constructors
public Instance() : base() { }
public Instance(Data.Models.Metadata.Instance item) : base(item) { }
public Instance(Data.Models.Metadata.Instance item, Machine machine, Source source) : this(item)
{
Source = source;
CopyMachineInformation(machine);
}
#endregion
#region Accessors
/// <inheritdoc/>
public override string? GetName() => Name;
/// <inheritdoc/>
public override void SetName(string? name) => Name = name;
#endregion
#region Cloning Methods
/// <inheritdoc/>
public override object Clone() => new Instance(GetInternalClone());
/// <inheritdoc/>
public override Data.Models.Metadata.Instance GetInternalClone()
=> _internal.Clone() as Data.Models.Metadata.Instance ?? new();
#endregion
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{
// If the other item is null
if (other is null)
return false;
// If the type matches
if (other is Instance otherInstance)
return _internal.Equals(otherInstance._internal);
// Everything else fails
return false;
}
#endregion
}
}

View File

@@ -804,6 +804,8 @@ namespace SabreTools.Metadata.Filter.Test
[Theory]
[InlineData("device.devicetype", "punchcard")]
[InlineData("device.fixedimage", "fixedimage")]
[InlineData("device.instance.briefname", "briefname")]
[InlineData("device.instance.name", "name")]
[InlineData("device.interface", "interface")]
[InlineData("device.mandatory", "yes")]
[InlineData("device.tag", "tag")]
@@ -814,6 +816,8 @@ namespace SabreTools.Metadata.Filter.Test
{
DeviceType = DeviceType.PunchCard,
FixedImage = "fixedimage",
InstanceBriefName = "briefname",
InstanceName = "name",
Interface = "interface",
Mandatory = true,
Tag = "tag",
@@ -825,7 +829,7 @@ namespace SabreTools.Metadata.Filter.Test
#endregion
#region Device
#region DeviceRef
[Theory]
[InlineData("deviceref.name", "name")]
@@ -1265,24 +1269,6 @@ namespace SabreTools.Metadata.Filter.Test
#endregion
#region Instance
[Theory]
[InlineData("instance.name", "name")]
public void Matches_Instance(string itemField, string value)
{
var filter = new FilterObject(itemField, value, Operation.Equals);
Instance obj = new Instance
{
Name = "name",
};
bool actual = filter.Matches(obj);
Assert.True(actual);
}
#endregion
#region Machine
[Theory]

View File

@@ -195,6 +195,8 @@ namespace SabreTools.Metadata.Filter
[
"devicetype",
"fixedimage",
"instance.briefname",
"instance.name",
"interface",
"mandatory",
"tag",
@@ -411,14 +413,6 @@ namespace SabreTools.Metadata.Filter
"tilt",
];
/// <summary>
/// Known keys for Instance
/// </summary>
private static readonly string[] _instanceKeys =
[
"name",
];
/// <summary>
/// Known keys for Machine
/// </summary>
@@ -1043,7 +1037,6 @@ namespace SabreTools.Metadata.Filter
"header" => _headerKeys,
"info" => _infoKeys,
"input" => _inputKeys,
"instance" => _instanceKeys,
"media" => _mediaKeys,
"original" => _originalKeys,
"part" => _partKeys,

View File

@@ -402,7 +402,6 @@ namespace SabreTools.Metadata.Filter
case Header item: return GetCheckValue(item, fieldName, out checkValue);
case Info item: return GetCheckValue(item, fieldName, out checkValue);
case Input item: return GetCheckValue(item, fieldName, out checkValue);
case Instance item: return GetCheckValue(item, fieldName, out checkValue);
case Machine item: return GetCheckValue(item, fieldName, out checkValue);
case Media item: return GetCheckValue(item, fieldName, out checkValue);
case Original item: return GetCheckValue(item, fieldName, out checkValue);
@@ -910,6 +909,12 @@ namespace SabreTools.Metadata.Filter
case "fixedimage":
checkValue = obj.FixedImage;
return true;
case "instance.briefname":
checkValue = obj.InstanceBriefName;
return true;
case "instance.name":
checkValue = obj.InstanceName;
return true;
case "interface":
checkValue = obj.Interface;
return true;
@@ -1472,24 +1477,6 @@ namespace SabreTools.Metadata.Filter
}
}
/// <summary>
/// Get the check value for a field
/// </summary>
private static bool GetCheckValue(Instance obj, string fieldName, out string? checkValue)
{
switch (fieldName)
{
case "name":
checkValue = obj.Name;
return true;
// If the key doesn't exist, we count it as null
default:
checkValue = null;
return false;
}
}
/// <summary>
/// Get the check value for a field
/// </summary>

View File

@@ -328,9 +328,15 @@ namespace SabreTools.Serialization.CrossModel
Interface = item.Interface,
};
var instance = item.Instance;
if (instance is not null)
device.Instance = ConvertFromInternalModel(instance);
if (item.InstanceBriefName is not null
|| item.InstanceName is not null)
{
device.Instance = new Instance
{
Name = item.InstanceName,
BriefName = item.InstanceBriefName,
};
}
var extensions = item.Extension;
if (extensions is not null && extensions.Length > 0)
@@ -546,19 +552,6 @@ namespace SabreTools.Serialization.CrossModel
return input;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Instance"/> to <see cref="Instance"/>
/// </summary>
private static Instance ConvertFromInternalModel(Data.Models.Metadata.Instance item)
{
var instance = new Instance
{
Name = item.Name,
BriefName = item.BriefName,
};
return instance;
}
/// <summary>
/// Convert from <see cref="Models.Metadata.Port"/> to <see cref="Port"/>
/// </summary>

View File

@@ -270,15 +270,14 @@ namespace SabreTools.Serialization.CrossModel
var device = new Data.Models.Metadata.Device
{
DeviceType = item.Type,
Tag = item.Tag,
FixedImage = item.FixedImage,
Mandatory = item.Mandatory,
InstanceBriefName = item.Instance?.BriefName,
InstanceName = item.Instance?.Name,
Interface = item.Interface,
Mandatory = item.Mandatory,
Tag = item.Tag,
};
if (item.Instance is not null)
device.Instance = ConvertToInternalModel(item.Instance);
if (item.Extension is not null && item.Extension.Length > 0)
device.Extension = Array.ConvertAll(item.Extension, ConvertToInternalModel);
@@ -469,19 +468,6 @@ namespace SabreTools.Serialization.CrossModel
return input;
}
/// <summary>
/// Convert from <see cref="Instance"/> to <see cref="Models.Metadata.Instance"/>
/// </summary>
private static Data.Models.Metadata.Instance ConvertToInternalModel(Instance item)
{
var instance = new Data.Models.Metadata.Instance
{
Name = item.Name,
BriefName = item.BriefName,
};
return instance;
}
/// <summary>
/// Convert from <see cref="Port"/> to <see cref="Models.Metadata.Port"/>
/// </summary>

View File

@@ -83,13 +83,6 @@ namespace SabreTools.Serialization.Readers.Test
Stream? actual = serializer.SerializeStream(sl);
Assert.NotNull(actual);
if (actual is MemoryStream ms)
{
byte[] bytes = ms.ToArray();
string str = System.Text.Encoding.UTF8.GetString(bytes);
System.Console.WriteLine(str);
}
// Serialize back to original model
Data.Models.SoftwareList.SoftwareList? newSl = deserializer.Deserialize(actual);