using System; using System.IO; using System.Linq; using RGB.NET.Core; namespace Artemis.Core.DeviceProviders; /// /// /// Allows you to implement and register your own device provider /// public abstract class DeviceProvider : PluginFeature { /// /// The RGB.NET device provider backing this Artemis device provider /// public abstract IRGBDeviceProvider RgbDeviceProvider { get; } /// /// A boolean indicating whether this device provider detects the physical layout of connected keyboards. /// /// Note: is only called when this or /// is . /// /// public bool CanDetectPhysicalLayout { get; protected set; } /// /// A boolean indicating whether this device provider detects the logical layout of connected keyboards /// /// Note: is only called when this or /// is . /// /// public bool CanDetectLogicalLayout { get; protected set; } /// /// Gets or sets a boolean indicating whether adding missing LEDs defined in a layout but missing on the device is /// supported /// Note: Defaults to . /// public bool CreateMissingLedsSupported { get; protected set; } = true; /// /// Gets or sets a boolean indicating whether removing excess LEDs present in the device but missing in the layout is /// supported /// Note: Defaults to . /// public bool RemoveExcessiveLedsSupported { get; protected set; } = true; /// /// Loads a layout for the specified device and wraps it in an /// /// The device to load the layout for /// The resulting Artemis layout public virtual ArtemisLayout LoadLayout(ArtemisDevice device) { string layoutDir = Path.Combine(Plugin.Directory.FullName, "Layouts"); string filePath = Path.Combine( layoutDir, device.RgbDevice.DeviceInfo.Manufacturer, device.DeviceType.ToString(), GetDeviceLayoutName(device) ); return new ArtemisLayout(filePath); } /// /// Loads a layout from the user layout folder for the specified device and wraps it in an /// /// The device to load the layout for /// The resulting Artemis layout public virtual ArtemisLayout LoadUserLayout(ArtemisDevice device) { string layoutDir = Constants.LayoutsFolder; string filePath = Path.Combine( layoutDir, device.RgbDevice.DeviceInfo.Manufacturer, device.DeviceType.ToString(), GetDeviceLayoutName(device) ); return new ArtemisLayout(filePath); } /// /// Called when a specific RGB device's logical and physical layout must be detected /// /// Note: Only called when is . /// /// /// The device to detect the layout for, always a keyboard public virtual string GetLogicalLayout(IKeyboard keyboard) { throw new NotImplementedException("Device provider does not support detecting logical layouts (don't call base.GetLogicalLayout())"); } /// /// Called when determining which file name to use when loading the layout of the specified /// . /// /// The device to determine the layout file name for. /// A file name, including an extension public virtual string GetDeviceLayoutName(ArtemisDevice device) { // Take out invalid file name chars, may not be perfect but neither are you string fileName = Path.GetInvalidFileNameChars().Aggregate(device.RgbDevice.DeviceInfo.Model, (current, c) => current.Replace(c, '-')); if (device.RgbDevice.DeviceInfo.DeviceType == RGBDeviceType.Keyboard) fileName = $"{fileName}-{device.PhysicalLayout.ToString().ToUpper()}"; return fileName + ".xml"; } }