using System; using System.Xml.Serialization; using Newtonsoft.Json; using SabreTools.Core; using SabreTools.Core.Filter; using SabreTools.Core.Tools; namespace SabreTools.DatItems { /// /// Represents the information specific to a set/game/machine /// [JsonObject("machine"), XmlRoot("machine")] public sealed class Machine : ModelBackedItem, ICloneable { #region Constants /// /// Trurip/EmuArc Machine developer /// public const string DeveloperKey = "DEVELOPER"; /// /// Trurip/EmuArc Game genre /// public const string GenreKey = "GENRE"; /// /// Trurip/EmuArc Title ID /// public const string TitleIDKey = "TITLEID"; #endregion #region Constructors public Machine() { _internal = new Models.Metadata.Machine(); } public Machine(Models.Metadata.Machine machine) { // Get all fields to automatically copy without processing var nonItemFields = TypeHelper.GetConstants(typeof(Models.Metadata.Machine)); if (nonItemFields == null) return; // Populate the internal machine from non-filter fields _internal = new Models.Metadata.Machine(); foreach (string fieldName in nonItemFields) { if (machine.ContainsKey(fieldName)) _internal[fieldName] = machine[fieldName]; } } #endregion #region Accessors /// /// Get a clone of the current internal model /// public Models.Metadata.Machine GetInternalClone() => (_internal.Clone() as Models.Metadata.Machine)!; #endregion #region Cloning methods /// /// Create a clone of the current machine /// /// New machine with the same values as the current one public object Clone() { return new Machine() { _internal = this._internal.Clone() as Models.Metadata.Machine ?? [], }; } #endregion #region Manipulation /// /// Runs a filter and determines if it passes or not /// /// Filter runner to use for checking /// True if the Machine passes the filter, false otherwise public bool PassesFilter(FilterRunner filterRunner) => filterRunner.Run(_internal); /// /// Remove a field from the Machine /// /// Field to remove /// True if the removal was successful, false otherwise public bool RemoveField(string? fieldName) => FieldManipulator.RemoveField(_internal, fieldName); /// /// Replace a field from another Machine /// /// Machine to replace field from /// Field to replace /// True if the replacement was successful, false otherwise public bool ReplaceField(Machine? other, string? fieldName) => FieldManipulator.ReplaceField(other?._internal, _internal, fieldName); /// /// Set a field in the Machine from a mapping string /// /// Field to set /// String representing the value to set /// True if the setting was successful, false otherwise /// This only performs minimal validation before setting public bool SetField(string? fieldName, string value) => FieldManipulator.SetField(_internal, fieldName, value); #endregion } }