From adfc2cde842a3a8034d5231cedecd501114b1d92 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 6 Apr 2026 14:46:34 -0400 Subject: [PATCH] Checkpoint reflection replacement --- .../FilterObjectTests.cs | 200 ++++++++++++++++++ SabreTools.Metadata.Filter/FilterKey.cs | 101 +++++++++ SabreTools.Metadata.Filter/FilterObject.cs | 2 + 3 files changed, 303 insertions(+) diff --git a/SabreTools.Metadata.Filter.Test/FilterObjectTests.cs b/SabreTools.Metadata.Filter.Test/FilterObjectTests.cs index 5a679f5d..f803661d 100644 --- a/SabreTools.Metadata.Filter.Test/FilterObjectTests.cs +++ b/SabreTools.Metadata.Filter.Test/FilterObjectTests.cs @@ -690,5 +690,205 @@ namespace SabreTools.Metadata.Filter.Test } #endregion + + #region ConfLocation + + [Theory] + [InlineData("conflocation.inverted", "yes")] + [InlineData("conflocation.name", "name")] + [InlineData("conflocation.number", "12345")] + public void Matches_ConfLocation(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + ConfLocation obj = new ConfLocation + { + Inverted = true, + Name = "name", + Number = 12345, + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region ConfSetting + + [Theory] + [InlineData("confsetting.default", "yes")] + [InlineData("confsetting.name", "name")] + [InlineData("confsetting.value", "value")] + public void Matches_ConfSetting(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + ConfSetting obj = new ConfSetting + { + Default = true, + Name = "name", + Value = "value", + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region Control + + [Theory] + [InlineData("control.buttons", "12345")] + [InlineData("control.type", "lightgun")] + [InlineData("control.controltype", "lightgun")] + [InlineData("control.keydelta", "12345")] + [InlineData("control.maximum", "12345")] + [InlineData("control.minimum", "12345")] + [InlineData("control.player", "12345")] + [InlineData("control.reqbuttons", "12345")] + [InlineData("control.reverse", "yes")] + [InlineData("control.sensitivity", "12345")] + [InlineData("control.ways", "ways")] + [InlineData("control.ways2", "ways2")] + [InlineData("control.ways3", "ways3")] + public void Matches_Control(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + Control obj = new Control + { + Buttons = 12345, + ControlType = ControlType.Lightgun, + KeyDelta = 12345, + Maximum = 12345, + Minimum = 12345, + Player = 12345, + ReqButtons = 12345, + Reverse = true, + Sensitivity = 12345, + Ways = "ways", + Ways2 = "ways2", + Ways3 = "ways3", + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region DataArea + + [Theory] + [InlineData("dataarea.endianness", "big")] + [InlineData("dataarea.name", "name")] + [InlineData("dataarea.size", "12345")] + [InlineData("dataarea.width", "16")] + public void Matches_DataArea(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + DataArea obj = new DataArea + { + Endianness = Endianness.Big, + Name = "name", + Size = 12345, + Width = Width.Short, + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region Device + + [Theory] + [InlineData("device.devicetype", "punchcard")] + [InlineData("device.type", "punchcard")] + [InlineData("device.fixedimage", "fixedimage")] + [InlineData("device.interface", "interface")] + [InlineData("device.mandatory", "yes")] + [InlineData("device.tag", "tag")] + public void Matches_Device(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + Device obj = new Device + { + DeviceType = DeviceType.PunchCard, + FixedImage = "fixedimage", + Interface = "interface", + Mandatory = true, + Tag = "tag", + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region Device + + [Theory] + [InlineData("deviceref.name", "name")] + public void Matches_DeviceRef(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + DeviceRef obj = new DeviceRef + { + Name = "name", + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region DipLocation + + [Theory] + [InlineData("diplocation.inverted", "yes")] + [InlineData("diplocation.name", "name")] + [InlineData("diplocation.number", "12345")] + public void Matches_DipLocation(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + DipLocation obj = new DipLocation + { + Inverted = true, + Name = "name", + Number = 12345, + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion + + #region DipSwitch + + [Theory] + [InlineData("dipswitch.default", "yes")] + [InlineData("dipswitch.mask", "mask")] + [InlineData("dipswitch.name", "name")] + [InlineData("dipswitch.tag", "tag")] + public void Matches_DipSwitch(string itemField, string value) + { + var filter = new FilterObject(itemField, value, Operation.Equals); + DipSwitch obj = new DipSwitch + { + Default = true, + Mask = "mask", + Name = "name", + Tag = "tag", + }; + + bool actual = filter.Matches(obj); + Assert.True(actual); + } + + #endregion } } diff --git a/SabreTools.Metadata.Filter/FilterKey.cs b/SabreTools.Metadata.Filter/FilterKey.cs index 64442a27..244d5ea4 100644 --- a/SabreTools.Metadata.Filter/FilterKey.cs +++ b/SabreTools.Metadata.Filter/FilterKey.cs @@ -138,6 +138,99 @@ namespace SabreTools.Metadata.Filter "tag", ]; + /// + /// Known keys for ConfLocation + /// + private static readonly string[] _confLocationKeys = + [ + "inverted", + "name", + "number", + ]; + + /// + /// Known keys for ConfSetting + /// + private static readonly string[] _confSettingKeys = + [ + "default", + "name", + "value", + ]; + + /// + /// Known keys for Control + /// + private static readonly string[] _controlKeys = + [ + "buttons", + "controltype", + "keydelta", + "maximum", + "minimum", + "player", + "reqbuttons", + "reverse", + "sensitivity", + "type", + "ways", + "ways2", + "ways3", + ]; + + /// + /// Known keys for DataArea + /// + private static readonly string[] _dataAreaKeys = + [ + "endianness", + "name", + "size", + "width", + ]; + + /// + /// Known keys for Device + /// + private static readonly string[] _deviceKeys = + [ + "devicetype", + "fixedimage", + "interface", + "mandatory", + "tag", + "type", + ]; + + /// + /// Known keys for DeviceRef + /// + private static readonly string[] _deviceRefKeys = + [ + "name", + ]; + + /// + /// Known keys for DipLocation + /// + private static readonly string[] _dipLocationKeys = + [ + "inverted", + "name", + "number", + ]; + + /// + /// Known keys for DipSwitch + /// + private static readonly string[] _dipSwitchKeys = + [ + "default", + "mask", + "name", + "tag", + ]; + #endregion /// @@ -323,6 +416,14 @@ namespace SabreTools.Metadata.Filter "chip" => _chipKeys, "condition" => _conditionKeys, "configuration" => _configurationKeys, + "conflocation" => _confLocationKeys, + "confsetting" => _confSettingKeys, + "control" => _controlKeys, + "dataarea" => _dataAreaKeys, + "device" => _deviceKeys, + "deviceref" => _deviceRefKeys, + "diplocation" => _dipLocationKeys, + "dipswitch" => _dipSwitchKeys, _ => null, }; diff --git a/SabreTools.Metadata.Filter/FilterObject.cs b/SabreTools.Metadata.Filter/FilterObject.cs index def15fcf..4bef1d2b 100644 --- a/SabreTools.Metadata.Filter/FilterObject.cs +++ b/SabreTools.Metadata.Filter/FilterObject.cs @@ -714,6 +714,7 @@ namespace SabreTools.Metadata.Filter case "buttons": checkValue = obj.Buttons?.ToString(); return true; + case "controltype": case "type": checkValue = obj.ControlType?.AsStringValue(); return true; @@ -789,6 +790,7 @@ namespace SabreTools.Metadata.Filter { switch (fieldName) { + case "devicetype": case "type": checkValue = obj.DeviceType?.AsStringValue(); return true;