From 2a9a43683c23daeb9ffd05abe8ecbd056719b74a Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Thu, 4 Mar 2021 23:33:00 +0100 Subject: [PATCH] Streamlined device loading/handling in device providers --- RGB.NET.Core/Devices/AbstractRGBDevice.cs | 31 ++- .../Devices/AbstractRGBDeviceProvider.cs | 119 ++++++++++ RGB.NET.Core/Devices/IRGBDevice.cs | 2 +- RGB.NET.Core/Devices/IRGBDeviceProvider.cs | 9 + RGB.NET.Core/Update/AbstractUpdateTrigger.cs | 3 + .../Update/Devices/DeviceUpdateTrigger.cs | 2 +- RGB.NET.Core/Update/Devices/IUpdateQueue.cs | 24 ++ RGB.NET.Core/Update/Devices/UpdateQueue.cs | 4 +- RGB.NET.Core/Update/IUpdateTrigger.cs | 2 + RGB.NET.Core/Update/ManualUpdateTrigger.cs | 2 +- RGB.NET.Core/Update/TimerUpdateTrigger.cs | 2 +- RGB.NET.Devices.Asus/AsusDeviceProvider.cs | 129 ++-------- .../Dram/AsusDramRGBDevice.cs | 11 +- RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs | 60 +---- .../Generic/AsusUnspecifiedRGBDevice.cs | 10 +- .../Generic/AsusUpdateQueue.cs | 19 +- .../Generic/IAsusRGBDevice.cs | 6 +- .../GraphicsCard/AsusGraphicsCardRGBDevice.cs | 11 +- .../Headset/AsusHeadsetRGBDevice.cs | 11 +- .../Keyboard/AsusKeyboardRGBDevice.cs | 11 +- .../Mainboard/AsusMainboardRGBDevice.cs | 13 +- .../Mouse/AsusMouseRGBDevice.cs | 11 +- .../CoolerMasterDeviceProvider.cs | 127 +++------- .../Generic/CoolerMasterRGBDevice.cs | 48 +--- .../Generic/ICoolerMasterRGBDevice.cs | 6 +- .../Keyboard/CoolerMasterKeyboardRGBDevice.cs | 13 +- .../Mouse/CoolerMasterMouseRGBDevice.cs | 9 +- .../CorsairDeviceProvider.cs | 224 ++++++------------ .../Custom/CorsairCustomRGBDevice.cs | 13 +- .../Generic/CorsairRGBDevice.cs | 84 +------ .../Generic/ICorsairRGBDevice.cs | 6 +- .../Headset/CorsairHeadsetRGBDevice.cs | 11 +- .../CorsairHeadsetStandRGBDevice.cs | 11 +- .../Keyboard/CorsairKeyboardRGBDevice.cs | 11 +- .../Memory/CorsairMemoryRGBDevice.cs | 11 +- .../Mouse/CorsairMouseRGBDevice.cs | 11 +- .../Mousepad/CorsairMousepadRGBDevice.cs | 11 +- RGB.NET.Devices.DMX/DMXDeviceProvider.cs | 78 ++---- RGB.NET.Devices.DMX/E131/E131Device.cs | 35 +-- RGB.NET.Devices.Debug/DebugDeviceProvider.cs | 52 +--- .../DebugDeviceUpdateQueue.cs | 22 ++ RGB.NET.Devices.Debug/DebugRGBDevice.cs | 6 +- .../Generic/ILogitechRGBDevice.cs | 6 +- .../Generic/LogitechRGBDevice.cs | 45 +--- .../LogitechDeviceProvider.cs | 151 +++--------- .../PerDevice/LogitechPerDeviceRGBDevice.cs | 15 +- .../PerKey/LogitechPerKeyRGBDevice.cs | 7 +- .../Zone/LogitechZoneRGBDevice.cs | 14 +- RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs | 6 +- RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs | 60 +---- .../GraphicsCard/MsiGraphicsCardRGBDevice.cs | 11 +- .../Mainboard/MsiMainboardRGBDevice.cs | 11 +- .../Mouse/MsiMouseRGBDevice.cs | 11 +- RGB.NET.Devices.Msi/MsiDeviceProvider.cs | 140 ++++------- .../Generic/INovationRGBDevice.cs | 6 +- .../Generic/NovationRGBDevice.cs | 52 +--- .../Launchpad/NovationLaunchpadRGBDevice.cs | 11 +- .../NovationDeviceProvider.cs | 84 ++----- .../ChromaLink/RazerChromaLinkRGBDevice.cs | 14 +- .../Generic/IRazerRGBDevice.cs | 7 +- .../Generic/RazerRGBDevice.cs | 51 +--- .../Headset/RazerHeadsetRGBDevice.cs | 14 +- .../Keyboard/RazerKeyboardRGBDevice.cs | 14 +- .../Keypad/RazerKeypadRGBDevice.cs | 14 +- .../Mouse/RazerMouseRGBDevice.cs | 14 +- .../Mousepad/RazerMousepadRGBDevice.cs | 15 +- RGB.NET.Devices.Razer/RazerDeviceProvider.cs | 196 +++++---------- .../Generic/ISteelSeriesRGBDevice.cs | 7 +- .../Generic/SteelSeriesRGBDevice.cs | 35 +-- .../SteelSeriesDeviceProvider.cs | 96 +++----- .../Arduino/ArduinoWS2812USBDevice.cs | 28 +-- .../Arduino/ArduinoWS281XDeviceDefinition.cs | 5 +- .../Bitwizard/BitwizardWS2812USBDevice.cs | 29 +-- .../BitwizardWS281XDeviceDefinition.cs | 31 ++- .../NodeMCU/NodeMCUWS2812USBDevice.cs | 26 +- .../NodeMCU/NodeMCUWS281XDeviceDefinition.cs | 4 +- .../WS281XDeviceProvider.cs | 67 +----- .../Generic/IWootingRGBDevice.cs | 6 +- .../Generic/WootingRGBDevice.cs | 51 +--- .../Keyboard/WootingKeyboardRGBDevice.cs | 14 +- .../WootingDeviceProvider.cs | 82 ++----- 81 files changed, 867 insertions(+), 1864 deletions(-) create mode 100644 RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs create mode 100644 RGB.NET.Core/Update/Devices/IUpdateQueue.cs create mode 100644 RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs index 7046139..cf47142 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs @@ -34,7 +34,7 @@ namespace RGB.NET.Core } /// - public abstract TDeviceInfo DeviceInfo { get; } + public TDeviceInfo DeviceInfo { get; } /// IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo; @@ -52,6 +52,8 @@ namespace RGB.NET.Core /// protected Dictionary LedMapping { get; } = new(); + protected IUpdateQueue UpdateQueue { get; } + #region Indexer /// @@ -68,6 +70,16 @@ namespace RGB.NET.Core #endregion + #region Constructors + + protected AbstractRGBDevice(TDeviceInfo deviceOnfo, IUpdateQueue updateQueue) + { + this.DeviceInfo = deviceOnfo; + this.UpdateQueue = updateQueue; + } + + #endregion + #region Methods /// @@ -112,14 +124,16 @@ namespace RGB.NET.Core } } + /// + /// Sends all the updated to the device. + /// + protected virtual void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); + /// public virtual void Dispose() { - try - { - LedMapping.Clear(); - } - catch { /* this really shouldn't happen */ } + try { UpdateQueue.Dispose(); } catch { /* :( */ } + try { LedMapping.Clear(); } catch { /* this really shouldn't happen */ } } /// @@ -128,11 +142,6 @@ namespace RGB.NET.Core protected virtual void DeviceUpdate() { } - /// - /// Sends all the updated to the device. - /// - protected abstract void UpdateLeds(IEnumerable ledsToUpdate); - /// /// Initializes the with the specified id. /// diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs new file mode 100644 index 0000000..7f0c4ef --- /dev/null +++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace RGB.NET.Core +{ + public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider + { + #region Properties & Fields + + private readonly double _defaultUpdateRateHardLimit; + + public bool IsInitialized { get; protected set; } + public bool ThrowsExceptions { get; protected set; } + + public virtual IEnumerable Devices { get; protected set; } = Enumerable.Empty(); + + protected Dictionary UpdateTriggers { get; } = new(); + + #endregion + + #region Events + + public event EventHandler? Exception; + + #endregion + + #region Constructors + + protected AbstractRGBDeviceProvider(double defaultUpdateRateHardLimit = 0) + { + this._defaultUpdateRateHardLimit = defaultUpdateRateHardLimit; + } + + #endregion + + #region Methods + + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + { + ThrowsExceptions = throwExceptions; + + try + { + Reset(); + + InitializeSDK(); + + Devices = new ReadOnlyCollection(GetLoadedDevices(loadFilter).ToList()); + + foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggers.Values) + updateTrigger.Start(); + + IsInitialized = true; + } + catch (Exception ex) + { + Reset(); + Throw(ex); + return false; + } + + return true; + } + + protected virtual IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + foreach (IRGBDevice device in LoadDevices()) + { + if (loadFilter.HasFlag(device.DeviceInfo.DeviceType)) + yield return device; + else + device.Dispose(); + } + } + + protected abstract void InitializeSDK(); + + protected abstract IEnumerable LoadDevices(); + + protected virtual IDeviceUpdateTrigger GetUpdateTrigger(int id = -1, double? updateRateHardLimit = null) + { + if (!UpdateTriggers.TryGetValue(id, out IDeviceUpdateTrigger? updaeTrigger)) + UpdateTriggers[id] = (updaeTrigger = new DeviceUpdateTrigger(updateRateHardLimit ?? _defaultUpdateRateHardLimit)); + + return updaeTrigger; + } + + protected virtual void Reset() + { + foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggers.Values) + updateTrigger.Dispose(); + + Devices = Enumerable.Empty(); + IsInitialized = false; + } + + protected virtual void Throw(Exception ex) + { + try { OnException(ex); } catch { /* we don't want to throw due to bad event handlers */ } + + if (ThrowsExceptions) + throw ex; + } + + protected virtual void OnException(Exception ex) => Exception?.Invoke(this, ex); + + public virtual void Dispose() + { + IEnumerable devices = Devices; + Reset(); + foreach (IRGBDevice device in devices) + device.Dispose(); + } + + #endregion + } +} diff --git a/RGB.NET.Core/Devices/IRGBDevice.cs b/RGB.NET.Core/Devices/IRGBDevice.cs index 0ad1dc7..983d54d 100644 --- a/RGB.NET.Core/Devices/IRGBDevice.cs +++ b/RGB.NET.Core/Devices/IRGBDevice.cs @@ -19,7 +19,7 @@ namespace RGB.NET.Core /// Gets generic information about the . /// IRGBDeviceInfo DeviceInfo { get; } - + IList ColorCorrections { get; } #endregion diff --git a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs index 6060feb..afa4ab0 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs @@ -22,6 +22,15 @@ namespace RGB.NET.Core #endregion + #region Events + + /// + /// Occurs when an exception is thrown in the device provider + /// + event EventHandler? Exception; + + #endregion + #region Methods bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false); diff --git a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs index 722c30e..3d754fd 100644 --- a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs +++ b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs @@ -30,6 +30,9 @@ namespace RGB.NET.Core /// Optional custom-data passed to the subscribers of the .event. protected virtual void OnUpdate(CustomUpdateData? updateData = null) => Update?.Invoke(this, updateData ?? new CustomUpdateData()); + /// + public abstract void Start(); + /// public abstract void Dispose(); diff --git a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs index 43caf4c..61e85a3 100644 --- a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs +++ b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs @@ -86,7 +86,7 @@ namespace RGB.NET.Core /// /// Starts the trigger. /// - public void Start() + public override void Start() { if (IsRunning) return; diff --git a/RGB.NET.Core/Update/Devices/IUpdateQueue.cs b/RGB.NET.Core/Update/Devices/IUpdateQueue.cs new file mode 100644 index 0000000..0fbcd7a --- /dev/null +++ b/RGB.NET.Core/Update/Devices/IUpdateQueue.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +namespace RGB.NET.Core +{ + public interface IUpdateQueue : IDisposable + where TIdentifier : notnull + { + /// + /// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available. + /// + /// The set of data. + // ReSharper disable once MemberCanBeProtected.Global + void SetData(IEnumerable<(TIdentifier, TData)> dataSet); + + /// + /// Resets the current data set. + /// + void Reset(); + } + + public interface IUpdateQueue : IUpdateQueue + { } +} diff --git a/RGB.NET.Core/Update/Devices/UpdateQueue.cs b/RGB.NET.Core/Update/Devices/UpdateQueue.cs index 4b48593..364ac6b 100644 --- a/RGB.NET.Core/Update/Devices/UpdateQueue.cs +++ b/RGB.NET.Core/Update/Devices/UpdateQueue.cs @@ -10,7 +10,7 @@ namespace RGB.NET.Core /// /// The type of the key used to identify some data. /// The type of the data. - public abstract class UpdateQueue : IDisposable + public abstract class UpdateQueue : IUpdateQueue where TIdentifier : notnull { #region Properties & Fields @@ -123,7 +123,7 @@ namespace RGB.NET.Core /// /// Represents a generic using an object as the key and a color as the value. /// - public abstract class UpdateQueue : UpdateQueue + public abstract class UpdateQueue : UpdateQueue, IUpdateQueue { #region Constructors diff --git a/RGB.NET.Core/Update/IUpdateTrigger.cs b/RGB.NET.Core/Update/IUpdateTrigger.cs index e80c3c0..4d75cae 100644 --- a/RGB.NET.Core/Update/IUpdateTrigger.cs +++ b/RGB.NET.Core/Update/IUpdateTrigger.cs @@ -16,5 +16,7 @@ namespace RGB.NET.Core /// Occurs when the trigger wants to cause an update. /// event EventHandler? Update; + + void Start(); } } diff --git a/RGB.NET.Core/Update/ManualUpdateTrigger.cs b/RGB.NET.Core/Update/ManualUpdateTrigger.cs index 27d18da..728f43e 100644 --- a/RGB.NET.Core/Update/ManualUpdateTrigger.cs +++ b/RGB.NET.Core/Update/ManualUpdateTrigger.cs @@ -44,7 +44,7 @@ namespace RGB.NET.Core /// /// Starts the trigger if needed, causing it to performing updates. /// - private void Start() + public override void Start() { if (UpdateTask == null) { diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs index 24321be..a63c29b 100644 --- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs +++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs @@ -56,7 +56,7 @@ namespace RGB.NET.Core /// /// Starts the trigger if needed, causing it to performing updates. /// - public void Start() + public override void Start() { lock (_lock) { diff --git a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs index 00f22f4..59a1351 100644 --- a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs +++ b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using AuraServiceLib; using RGB.NET.Core; @@ -14,7 +12,7 @@ namespace RGB.NET.Devices.Asus /// /// Represents a device provider responsible for Cooler Master devices. /// - public class AsusDeviceProvider : IRGBDeviceProvider + public class AsusDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -24,20 +22,6 @@ namespace RGB.NET.Devices.Asus /// public static AsusDeviceProvider Instance => _instance ?? new AsusDeviceProvider(); - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for asus devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - private IAuraSdk2? _sdk; #endregion @@ -52,107 +36,44 @@ namespace RGB.NET.Devices.Asus { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(AsusDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion - + #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - IsInitialized = false; + _sdk = (IAuraSdk2)new AuraSdk(); + _sdk.SwitchMode(); + } - try + protected override IEnumerable LoadDevices() + { + if (_sdk == null) yield break; + + foreach (IAuraSyncDevice device in _sdk.Enumerate(0)) { - UpdateTrigger.Stop(); - - // ReSharper disable once SuspiciousTypeConversion.Global - _sdk = (IAuraSdk2)new AuraSdk(); - _sdk.SwitchMode(); - - IList devices = new List(); - foreach (IAuraSyncDevice device in _sdk.Enumerate(0)) + yield return (AsusDeviceType)device.Type switch { - try - { - IAsusRGBDevice rgbDevice; - switch ((AsusDeviceType)device.Type) - { - case AsusDeviceType.MB_RGB: - rgbDevice = new AsusMainboardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mainboard, device, WMIHelper.GetMainboardInfo()?.model ?? device.Name)); - break; - - case AsusDeviceType.MB_ADDRESABLE: - rgbDevice = new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.LedStripe, device), LedId.LedStripe1); - break; - - case AsusDeviceType.VGA_RGB: - rgbDevice = new AsusGraphicsCardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.GraphicsCard, device)); - break; - - case AsusDeviceType.HEADSET_RGB: - rgbDevice = new AsusHeadsetRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Headset, device)); - break; - - case AsusDeviceType.DRAM_RGB: - rgbDevice = new AsusDramRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.DRAM, device)); - break; - - case AsusDeviceType.KEYBOARD_RGB: - case AsusDeviceType.NB_KB_RGB: - case AsusDeviceType.NB_KB_4ZONE_RGB: - rgbDevice = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device)); - break; - - case AsusDeviceType.MOUSE_RGB: - rgbDevice = new AsusMouseRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mouse, device)); - break; - - default: - rgbDevice = new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Unknown, device), LedId.Custom1); - break; - } - - if (loadFilter.HasFlag(rgbDevice.DeviceInfo.DeviceType)) - { - rgbDevice.Initialize(UpdateTrigger); - devices.Add(rgbDevice); - } - } - catch - { - if (throwExceptions) - throw; - } - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + AsusDeviceType.MB_RGB => new AsusMainboardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mainboard, device, WMIHelper.GetMainboardInfo()?.model ?? device.Name), GetUpdateTrigger()), + AsusDeviceType.MB_ADDRESABLE => new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.LedStripe, device), LedId.LedStripe1, GetUpdateTrigger()), + AsusDeviceType.VGA_RGB => new AsusGraphicsCardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.GraphicsCard, device), GetUpdateTrigger()), + AsusDeviceType.HEADSET_RGB => new AsusHeadsetRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Headset, device), GetUpdateTrigger()), + AsusDeviceType.DRAM_RGB => new AsusDramRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.DRAM, device), GetUpdateTrigger()), + AsusDeviceType.KEYBOARD_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), GetUpdateTrigger()), + AsusDeviceType.NB_KB_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), GetUpdateTrigger()), + AsusDeviceType.NB_KB_4ZONE_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), GetUpdateTrigger()), + AsusDeviceType.MOUSE_RGB => new AsusMouseRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mouse, device), GetUpdateTrigger()), + _ => new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Unknown, device), LedId.Custom1, GetUpdateTrigger()) + }; } - catch - { - if (throwExceptions) - throw; - return false; - } - return true; } /// - public void Dispose() + public override void Dispose() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + base.Dispose(); try { _sdk?.ReleaseControl(0); } catch { /* at least we tried */ } diff --git a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs index 6920a01..ef1b046 100644 --- a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs @@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the DRAM. - internal AsusDramRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } + internal AsusDramRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs index 3973048..f80056a 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs @@ -1,75 +1,23 @@ -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Asus { /// - /// /// /// Represents a generic Asus-device. (keyboard, mouse, headset, mousepad). /// public abstract class AsusRGBDevice : AbstractRGBDevice, IAsusRGBDevice where TDeviceInfo : AsusRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected AsusUpdateQueue? UpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by Asus for the device. - protected AsusRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - UpdateQueue = new AsusUpdateQueue(updateTrigger); - UpdateQueue.Initialize(DeviceInfo.Device); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); - - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } + protected AsusRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new AsusUpdateQueue(updateTrigger, info.Device)) + { } #endregion } diff --git a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs index c114b52..e0abfa5 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs @@ -21,18 +21,19 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the headset. - internal AsusUnspecifiedRGBDevice(AsusRGBDeviceInfo info, LedId baseLedId) - : base(info) + internal AsusUnspecifiedRGBDevice(AsusRGBDeviceInfo info, LedId baseLedId, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { this._baseLedId = baseLedId; + + InitializeLayout(); } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) @@ -41,6 +42,7 @@ namespace RGB.NET.Devices.Asus /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)_baseLedId; + #endregion } } diff --git a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs index 73cbc31..70b1a38 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs @@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Asus /// /// The device to be updated. /// - protected IAuraSyncDevice? Device { get; private set; } + protected IAuraSyncDevice Device { get; } #endregion @@ -25,28 +25,19 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The update trigger used by this queue. - public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger) + public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger, IAuraSyncDevice device) : base(updateTrigger) - { } + { + this.Device = device; + } #endregion #region Methods - /// - /// Initializes the queue. - /// - /// The device to be updated. - public void Initialize(IAuraSyncDevice device) - { - Device = device; - } - /// protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) { - if (Device == null) return; - try { if ((Device.Type == (uint)AsusDeviceType.KEYBOARD_RGB) || (Device.Type == (uint)AsusDeviceType.NB_KB_RGB)) diff --git a/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs index 720fd3c..74b0d08 100644 --- a/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Asus /// /// Represents a asus RGB-device. /// - internal interface IAsusRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } + public interface IAsusRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs index 8c0f98a..698b2c3 100644 --- a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs @@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the graphics card. - internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } + internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) diff --git a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs index 96c4c87..22d14d9 100644 --- a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs @@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the headset. - internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } + internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs index b10eb60..28cfbec 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs @@ -24,16 +24,17 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the keyboard. - internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info) - : base(info) - { } + internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { Dictionary reversedMapping = AsusKeyboardLedMapping.MAPPING.ToDictionary(x => x.Value, x => x.Key); diff --git a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs index e4b25a5..bde9f1b 100644 --- a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs @@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the mainboard. - internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } + internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) @@ -33,7 +34,7 @@ namespace RGB.NET.Devices.Asus /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; - + #endregion } } diff --git a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs index cd97e88..fdbd204 100644 --- a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs @@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus /// Initializes a new instance of the class. /// /// The specific information provided by Asus for the mouse. - internal AsusMouseRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } + internal AsusMouseRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs index f7e57dc..eb96ce0 100644 --- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs +++ b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Helper; using RGB.NET.Devices.CoolerMaster.Native; @@ -15,7 +13,7 @@ namespace RGB.NET.Devices.CoolerMaster /// /// Represents a device provider responsible for Cooler Master devices. /// - public class CoolerMasterDeviceProvider : IRGBDeviceProvider + public class CoolerMasterDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -37,20 +35,6 @@ namespace RGB.NET.Devices.CoolerMaster /// public static List PossibleX64NativePaths { get; } = new() { "x64/CMSDK.dll" }; - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for cooler master devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -63,97 +47,48 @@ namespace RGB.NET.Devices.CoolerMaster { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CoolerMasterDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - IsInitialized = false; - - try - { - UpdateTrigger.Stop(); - - _CoolerMasterSDK.Reload(); - if (_CoolerMasterSDK.GetSDKVersion() <= 0) return false; - - IList devices = new List(); - - foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes))) - { - try - { - RGBDeviceType deviceType = index.GetDeviceType(); - if (deviceType == RGBDeviceType.None) continue; - - if (_CoolerMasterSDK.IsDevicePlugged(index)) - { - if (!loadFilter.HasFlag(deviceType)) continue; - - ICoolerMasterRGBDevice device; - switch (deviceType) - { - case RGBDeviceType.Keyboard: - CoolerMasterPhysicalKeyboardLayout physicalLayout = _CoolerMasterSDK.GetDeviceLayout(index); - device = new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, physicalLayout)); - break; - - case RGBDeviceType.Mouse: - device = new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index)); - break; - - default: - if (throwExceptions) - throw new RGBDeviceException("Unknown Device-Type"); - else - continue; - } - - if (!_CoolerMasterSDK.EnableLedControl(true, index)) - throw new RGBDeviceException("Failed to enable LED control for device " + index); - - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; + _CoolerMasterSDK.Reload(); + if (_CoolerMasterSDK.GetSDKVersion() <= 0) Throw(new RGBDeviceException("Failed to initialize CoolerMaster-SDK")); } - /// - public void Dispose() + protected override IEnumerable LoadDevices() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } + foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes))) + { + RGBDeviceType deviceType = index.GetDeviceType(); + if (deviceType == RGBDeviceType.None) continue; - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + if (_CoolerMasterSDK.IsDevicePlugged(index)) + { + if (!_CoolerMasterSDK.EnableLedControl(true, index)) + Throw(new RGBDeviceException("Failed to enable LED control for device " + index)); + else + { + switch (deviceType) + { + case RGBDeviceType.Keyboard: + yield return new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, _CoolerMasterSDK.GetDeviceLayout(index)), GetUpdateTrigger()); + break; - // DarthAffe 03.03.2020: Should be done but isn't possible due to an weird winodws-hook inside the sdk which corrupts the stack when unloading the dll - //try { _CoolerMasterSDK.UnloadCMSDK(); } - //catch { /* at least we tried */ } + case RGBDeviceType.Mouse: + yield return new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index), GetUpdateTrigger()); + break; + + default: + Throw(new RGBDeviceException("Unknown Device-Type")); + break; + } + } + } + } } #endregion diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs index ac17daa..fdeaf39 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs @@ -1,76 +1,34 @@ using System; -using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Native; namespace RGB.NET.Devices.CoolerMaster { /// - /// /// /// Represents a generic CoolerMaster-device. (keyboard, mouse, headset, mousepad). /// public abstract class CoolerMasterRGBDevice : AbstractRGBDevice, ICoolerMasterRGBDevice where TDeviceInfo : CoolerMasterRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected CoolerMasterUpdateQueue? UpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by CoolerMaster for the device. - protected CoolerMasterRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } + protected CoolerMasterRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new CoolerMasterUpdateQueue(updateTrigger, info.DeviceIndex)) + { } #endregion #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - UpdateQueue = new CoolerMasterUpdateQueue(updateTrigger, DeviceInfo.DeviceIndex); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); - /// /// public override void Dispose() { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - _CoolerMasterSDK.EnableLedControl(false, DeviceInfo.DeviceIndex); base.Dispose(); diff --git a/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs index 8483843..4edd1e9 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.CoolerMaster /// /// Represents a CoolerMaster RGB-device. /// - internal interface ICoolerMasterRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } + public interface ICoolerMasterRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs index 29df3be..9007148 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs @@ -22,16 +22,17 @@ namespace RGB.NET.Devices.CoolerMaster /// Initializes a new instance of the class. /// /// The specific information provided by CoolerMaster for the keyboard - internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info) - : base(info) - { } + internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary>? deviceMappings)) throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex}"); @@ -44,7 +45,7 @@ namespace RGB.NET.Devices.CoolerMaster /// protected override object GetLedCustomData(LedId ledId) => CoolerMasterKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; - + #endregion } } diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs index e1efb77..aa4c3aa 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs @@ -16,16 +16,15 @@ namespace RGB.NET.Devices.CoolerMaster /// Initializes a new instance of the class. /// /// The specific information provided by CoolerMaster for the mouse - internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info) - : base(info) + internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { Dictionary mapping = CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex]; @@ -35,7 +34,7 @@ namespace RGB.NET.Devices.CoolerMaster /// protected override object GetLedCustomData(LedId ledId) => CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex][ledId]; - + #endregion } } diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index 4f7a57a..3e05167 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Corsair /// /// Represents a device provider responsible for corsair (CUE) devices. /// - public class CorsairDeviceProvider : IRGBDeviceProvider + public class CorsairDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -37,12 +37,6 @@ namespace RGB.NET.Devices.Corsair /// public static List PossibleX64NativePaths { get; } = new() { "x64/CUESDK.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" }; - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - /// /// Gets the protocol details for the current SDK-connection. /// @@ -53,14 +47,6 @@ namespace RGB.NET.Devices.Corsair /// public CorsairError LastError => _CUESDK.CorsairGetLastError(); - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for corsair devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -73,156 +59,108 @@ namespace RGB.NET.Devices.Corsair { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CorsairDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion #region Methods - /// - /// Thrown if the SDK is already initialized or if the SDK is not compatible to CUE. - /// Thrown if the CUE-SDK provides an error. - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - IsInitialized = false; + _CUESDK.Reload(); - try - { - UpdateTrigger.Stop(); + ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake()); - _CUESDK.Reload(); + CorsairError error = LastError; + if (error != CorsairError.Success) + Throw(new CUEException(error)); - ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake()); + if (ProtocolDetails.BreakingChanges) + Throw(new RGBDeviceException("The SDK currently used isn't compatible with the installed version of CUE.\r\n" + + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n" + + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})")); - CorsairError error = LastError; - if (error != CorsairError.Success) - throw new CUEException(error); - - if (ProtocolDetails.BreakingChanges) - throw new RGBDeviceException("The SDK currently used isn't compatible with the installed version of CUE.\r\n" - + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n" - + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})"); - - // DarthAffe 02.02.2021: 127 is iCUE - if (!_CUESDK.CorsairSetLayerPriority(128)) - throw new CUEException(LastError); - - Dictionary modelCounter = new(); - IList devices = new List(); - int deviceCount = _CUESDK.CorsairGetDeviceCount(); - for (int i = 0; i < deviceCount; i++) - { - try - { - _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo))!; - CorsairRGBDeviceInfo info = new(i, RGBDeviceType.Unknown, nativeDeviceInfo, modelCounter); - if (!info.CapsMask.HasFlag(CorsairDeviceCaps.Lighting)) - continue; // Everything that doesn't support lighting control is useless - - CorsairDeviceUpdateQueue? deviceUpdateQueue = null; - foreach (ICorsairRGBDevice device in GetRGBDevice(info, i, nativeDeviceInfo, modelCounter)) - { - if ((device == null) || !loadFilter.HasFlag(device.DeviceInfo.DeviceType)) continue; - - deviceUpdateQueue ??= new CorsairDeviceUpdateQueue(UpdateTrigger, info.CorsairDeviceIndex); - - device.Initialize(deviceUpdateQueue); - - error = LastError; - if (error != CorsairError.Success) - throw new CUEException(error); - - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - Reset(); - if (throwExceptions) throw; - return false; - } - - return true; + // DarthAffe 02.02.2021: 127 is iCUE + if (!_CUESDK.CorsairSetLayerPriority(128)) + Throw(new CUEException(LastError)); } - private static IEnumerable GetRGBDevice(CorsairRGBDeviceInfo info, int i, _CorsairDeviceInfo nativeDeviceInfo, Dictionary modelCounter) + protected override IEnumerable LoadDevices() { - switch (info.CorsairDeviceType) + Dictionary modelCounter = new(); + int deviceCount = _CUESDK.CorsairGetDeviceCount(); + for (int i = 0; i < deviceCount; i++) { - case CorsairDeviceType.Keyboard: - yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); - break; + _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo))!; + CorsairRGBDeviceInfo info = new(i, RGBDeviceType.Unknown, nativeDeviceInfo, modelCounter); + if (!info.CapsMask.HasFlag(CorsairDeviceCaps.Lighting)) + continue; // Everything that doesn't support lighting control is useless - case CorsairDeviceType.Mouse: - yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); - break; + CorsairDeviceUpdateQueue updateQueue = new(GetUpdateTrigger(), info.CorsairDeviceIndex); + switch (info.CorsairDeviceType) + { + case CorsairDeviceType.Keyboard: + yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue); + break; - case CorsairDeviceType.Headset: - yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); - break; + case CorsairDeviceType.Mouse: + yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue); + break; - case CorsairDeviceType.Mousepad: - yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); - break; + case CorsairDeviceType.Headset: + yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue); + break; - case CorsairDeviceType.HeadsetStand: - yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); - break; + case CorsairDeviceType.Mousepad: + yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue); + break; - case CorsairDeviceType.MemoryModule: - yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); - break; + case CorsairDeviceType.HeadsetStand: + yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue); + break; - case CorsairDeviceType.Cooler: - case CorsairDeviceType.CommanderPro: - case CorsairDeviceType.LightningNodePro: - _CorsairChannelsInfo? channelsInfo = nativeDeviceInfo.channels; - if (channelsInfo != null) - { - IntPtr channelInfoPtr = channelsInfo.channels; + case CorsairDeviceType.MemoryModule: + yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue); + break; - for (int channel = 0; channel < channelsInfo.channelsCount; channel++) + case CorsairDeviceType.Cooler: + case CorsairDeviceType.CommanderPro: + case CorsairDeviceType.LightningNodePro: + _CorsairChannelsInfo? channelsInfo = nativeDeviceInfo.channels; + if (channelsInfo != null) { - CorsairLedId referenceLed = GetChannelReferenceId(info.CorsairDeviceType, channel); - if (referenceLed == CorsairLedId.Invalid) continue; + IntPtr channelInfoPtr = channelsInfo.channels; - _CorsairChannelInfo channelInfo = (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo))!; - - int channelDeviceInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelDeviceInfo)); - IntPtr channelDeviceInfoPtr = channelInfo.devices; - - for (int device = 0; device < channelInfo.devicesCount; device++) + for (int channel = 0; channel < channelsInfo.channelsCount; channel++) { - _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!; + CorsairLedId referenceLed = GetChannelReferenceId(info.CorsairDeviceType, channel); + if (referenceLed == CorsairLedId.Invalid) continue; - yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter)); - referenceLed += channelDeviceInfo.deviceLedCount; + _CorsairChannelInfo channelInfo = (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo))!; - channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize); + int channelDeviceInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelDeviceInfo)); + IntPtr channelDeviceInfoPtr = channelInfo.devices; + + for (int device = 0; device < channelInfo.devicesCount; device++) + { + _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!; + + yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter), updateQueue); + referenceLed += channelDeviceInfo.deviceLedCount; + + channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize); + } + + int channelInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelInfo)); + channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize); } - - int channelInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelInfo)); - channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize); } - } + break; - break; - - - // ReSharper disable once RedundantCaseLabel - case CorsairDeviceType.Unknown: - default: - throw new RGBDeviceException("Unknown Device-Type"); + default: + Throw(new RGBDeviceException("Unknown Device-Type")); + break; + } } } @@ -240,23 +178,17 @@ namespace RGB.NET.Devices.Corsair }; } - private void Reset() + protected override void Reset() { ProtocolDetails = null; - Devices = Enumerable.Empty(); - IsInitialized = false; + + base.Reset(); } /// - public void Dispose() + public override void Dispose() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + base.Dispose(); try { _CUESDK.UnloadCUESDK(); } catch { /* at least we tried */ } diff --git a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs index 0ea52b4..fc67e5a 100644 --- a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs @@ -25,16 +25,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the custom-device. - internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info) - : base(info) - { } + internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { LedId referenceId = GetReferenceLed(DeviceInfo.DeviceType); @@ -45,7 +46,7 @@ namespace RGB.NET.Devices.Corsair AddLed(ledId, new Point(i * 10, 0), new Size(10, 10)); } } - + protected override object GetLedCustomData(LedId ledId) => _idMapping.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; protected virtual LedId GetReferenceLed(RGBDeviceType deviceType) diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs index ef2a854..c7e1864 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs @@ -1,99 +1,23 @@ -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Corsair { /// - /// /// /// Represents a generic CUE-device. (keyboard, mouse, headset, mousepad). /// public abstract class CorsairRGBDevice : AbstractRGBDevice, ICorsairRGBDevice where TDeviceInfo : CorsairRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets a dictionary containing all of the . - /// - // ReSharper disable once MemberCanBePrivate.Global - protected Dictionary InternalLedMapping { get; } = new(); - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected CorsairDeviceUpdateQueue? DeviceUpdateQueue { get; set; } - - #endregion - - #region Indexer - - /// - /// Gets the with the specified . - /// - /// The of the to get. - /// The with the specified or null if no is found. - // ReSharper disable once MemberCanBePrivate.Global - public Led? this[CorsairLedId ledId] => InternalLedMapping.TryGetValue(ledId, out Led? led) ? led : null; - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by CUE for the device. - protected CorsairRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue) - { - DeviceUpdateQueue = deviceUpdateQueue; - - InitializeLayout(); - - foreach (Led led in LedMapping.Values) - { - if (led.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid)) - InternalLedMapping.Add(ledId, led); - } - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) - => DeviceUpdateQueue?.SetData(GetUpdateData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid))))); - - /// - public override void Dispose() - { - try { DeviceUpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } + protected CorsairRGBDevice(TDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { } #endregion } diff --git a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs index 325c46c..9caca09 100644 --- a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Corsair /// /// Represents a corsair RGB-device. /// - internal interface ICorsairRGBDevice : IRGBDevice - { - void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue); - } + public interface ICorsairRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs index 7a39b28..92455d9 100644 --- a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs @@ -18,16 +18,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the headset - internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info) - : base(info) - { } + internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { AddLed(LedId.Headset1, new Point(0, 0), new Size(10, 10)); AddLed(LedId.Headset2, new Point(10, 0), new Size(10, 10)); diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs index 966fc77..ca17c0e 100644 --- a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs @@ -23,16 +23,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the headset stand - internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info) - : base(info) - { } + internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); if (nativeLedPositions == null) return; diff --git a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs index 1d950dd..268cd75 100644 --- a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs @@ -28,16 +28,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the keyboard - internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info) - : base(info) - { } + internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); if (nativeLedPositions == null) return; diff --git a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs index f174b8c..cdc42e7 100644 --- a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs @@ -22,16 +22,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the memory. - internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info) - : base(info) - { } + internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); if (nativeLedPositions == null) return; diff --git a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs index f9bfa42..a3d015f 100644 --- a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs @@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the mouse - internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info) - : base(info) - { } + internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { switch (DeviceInfo.PhysicalLayout) { diff --git a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs index 00b526d..1f74aee 100644 --- a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs @@ -23,16 +23,17 @@ namespace RGB.NET.Devices.Corsair /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the mousepad - internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info) - : base(info) - { } + internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); if (nativeLedPositions == null) return; diff --git a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs index 4720e1e..0d23fd5 100644 --- a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs +++ b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.DMX.E131; @@ -14,7 +12,7 @@ namespace RGB.NET.Devices.DMX /// /// Represents a device provider responsible for DMX devices. /// - public class DMXDeviceProvider : IRGBDeviceProvider + public class DMXDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -24,22 +22,11 @@ namespace RGB.NET.Devices.DMX /// public static DMXDeviceProvider Instance => _instance ?? new DMXDeviceProvider(); - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - /// /// Gets a list of all defined device-definitions. /// public List DeviceDefinitions { get; } = new(); - /// - /// The used to trigger the updates for dmx devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -52,8 +39,6 @@ namespace RGB.NET.Devices.DMX { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(DMXDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion @@ -66,58 +51,27 @@ namespace RGB.NET.Devices.DMX /// The to add. public void AddDeviceDefinition(IDMXDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { } + + protected override IEnumerable LoadDevices() { - IsInitialized = false; - - try + foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions) { - UpdateTrigger.Stop(); - - IList devices = new List(); - - foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions) + IRGBDevice? device = null; + try { - try - { - if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition) - { - if (e131DMXDeviceDefinition.Leds.Count > 0) - { - E131Device device = new(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - } - catch { if (throwExceptions) throw; } + if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition) + if (e131DMXDeviceDefinition.Leds.Count > 0) + device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds, GetUpdateTrigger(0)); + } + catch (Exception ex) + { + Throw(ex); } - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + if (device != null) + yield return device; } - catch - { - if (throwExceptions) throw; - return false; - } - - return true; - } - - /// - public void Dispose() - { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); } #endregion diff --git a/RGB.NET.Devices.DMX/E131/E131Device.cs b/RGB.NET.Devices.DMX/E131/E131Device.cs index 9b18d01..0c170c6 100644 --- a/RGB.NET.Devices.DMX/E131/E131Device.cs +++ b/RGB.NET.Devices.DMX/E131/E131Device.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.DMX.E131 @@ -12,55 +11,39 @@ namespace RGB.NET.Devices.DMX.E131 { #region Properties & Fields - /// - public override E131DeviceInfo DeviceInfo { get; } - private readonly Dictionary getValueFunc)>> _ledMappings; - private E131UpdateQueue? _updateQueue; - #endregion #region Constructors /// - internal E131Device(E131DeviceInfo deviceInfo, Dictionary getValueFunc)>> ledMappings) + internal E131Device(E131DeviceInfo deviceInfo, Dictionary getValueFunc)>> ledMappings, IDeviceUpdateTrigger updateTrigger) + : base(deviceInfo, new E131UpdateQueue(updateTrigger, deviceInfo.Hostname, deviceInfo.Port)) { - this.DeviceInfo = deviceInfo; this._ledMappings = ledMappings; + + InitializeLayout(); + + E131UpdateQueue updateQueue = (E131UpdateQueue)UpdateQueue; + updateQueue.DataPacket.SetCID(DeviceInfo.CID); + updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe); } #endregion #region Methods - internal void Initialize(IDeviceUpdateTrigger updateTrigger) + private void InitializeLayout() { int count = 0; foreach (LedId id in _ledMappings.Keys) AddLed(id, new Point((count++) * 10, 0), new Size(10, 10)); - - _updateQueue = new E131UpdateQueue(updateTrigger, DeviceInfo.Hostname, DeviceInfo.Port); - _updateQueue.DataPacket.SetCID(DeviceInfo.CID); - _updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe); } /// protected override object GetLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateQueue?.SetData(GetUpdateData(ledsToUpdate)); - - /// - public override void Dispose() - { - try { _updateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - #endregion } } diff --git a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs index 66ec439..5e9ab8b 100644 --- a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs +++ b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; using RGB.NET.Layout; @@ -14,7 +12,7 @@ namespace RGB.NET.Devices.Debug /// /// Represents a device provider responsible for debug devices. /// - public class DebugDeviceProvider : IRGBDeviceProvider + public class DebugDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -24,13 +22,7 @@ namespace RGB.NET.Devices.Debug /// public static DebugDeviceProvider Instance => _instance ?? new DebugDeviceProvider(); - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - private List<(IDeviceLayout layout, string imageLayout, Action>? updateLedsAction)> _fakeDeviceDefinitions = new(); + private List<(IDeviceLayout layout, Action>? updateLedsAction)> _fakeDeviceDefinitions = new(); #endregion @@ -54,48 +46,28 @@ namespace RGB.NET.Devices.Debug /// Adds a new fake device definition. /// /// The path of the layout file to be used. - /// The image-layout to load. /// A action emulating led-updates. - public void AddFakeDeviceDefinition(IDeviceLayout layout, string imageLayout, Action>? updateLedsAction = null) - => _fakeDeviceDefinitions.Add((layout, imageLayout, updateLedsAction)); + public void AddFakeDeviceDefinition(IDeviceLayout layout, Action>? updateLedsAction = null) + => _fakeDeviceDefinitions.Add((layout, updateLedsAction)); /// /// Removes all previously added fake device definitions. /// public void ClearFakeDeviceDefinitions() => _fakeDeviceDefinitions.Clear(); - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false) + protected override void InitializeSDK() { } + + protected override IEnumerable LoadDevices() { - IsInitialized = false; - try - { - List devices = new(); - foreach ((IDeviceLayout layout, string imageLayout, Action>? updateLedsAction) in _fakeDeviceDefinitions) - { - DebugRGBDevice device = new(layout, updateLedsAction); - devices.Add(device); - } - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - - return true; - } - catch - { - if (throwExceptions) throw; - return false; - } + foreach ((IDeviceLayout layout, Action>? updateLedsAction) in _fakeDeviceDefinitions) + yield return new DebugRGBDevice(layout, updateLedsAction); } /// - public void ResetDevices() - { } - - /// - public void Dispose() + public override void Dispose() { + base.Dispose(); + _fakeDeviceDefinitions.Clear(); } diff --git a/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs b/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs new file mode 100644 index 0000000..7fe823d --- /dev/null +++ b/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs @@ -0,0 +1,22 @@ +using System; +using RGB.NET.Core; + +namespace RGB.NET.Devices.Debug +{ + internal class DebugDeviceUpdateQueue : UpdateQueue + { + #region Constructors + + public DebugDeviceUpdateQueue() + : base(new DeviceUpdateTrigger()) + { } + + #endregion + + #region Methods + + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) { } + + #endregion + } +} diff --git a/RGB.NET.Devices.Debug/DebugRGBDevice.cs b/RGB.NET.Devices.Debug/DebugRGBDevice.cs index 052e870..fa11042 100644 --- a/RGB.NET.Devices.Debug/DebugRGBDevice.cs +++ b/RGB.NET.Devices.Debug/DebugRGBDevice.cs @@ -13,9 +13,6 @@ namespace RGB.NET.Devices.Debug { #region Properties & Fields - /// - public override DebugRGBDeviceInfo DeviceInfo { get; } - public IDeviceLayout Layout { get; } private Action>? _updateLedsAction; @@ -27,12 +24,11 @@ namespace RGB.NET.Devices.Debug /// Internal constructor of . /// internal DebugRGBDevice(IDeviceLayout layout, Action>? updateLedsAction = null) + : base(new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData), new DebugDeviceUpdateQueue()) { this.Layout = layout; this._updateLedsAction = updateLedsAction; - DeviceInfo = new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData); - Layout.ApplyTo(this, true); } diff --git a/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs index 4c8e260..7c3b2be 100644 --- a/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Logitech /// /// Represents a logitech RGB-device. /// - internal interface ILogitechRGBDevice : IRGBDevice - { - void Initialize(UpdateQueue updateQueue); - } + public interface ILogitechRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs index eacb6b6..f217795 100644 --- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs @@ -3,60 +3,21 @@ namespace RGB.NET.Devices.Logitech { /// - /// /// /// Represents a generic Logitech-device. (keyboard, mouse, headset, mousepad). /// public abstract class LogitechRGBDevice : AbstractRGBDevice, ILogitechRGBDevice where TDeviceInfo : LogitechRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue? UpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by Logitech for the device. - protected LogitechRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public virtual void Initialize(UpdateQueue updateQueue) - { - UpdateQueue = updateQueue; - } - - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } + protected LogitechRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) + { } #endregion } diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs index 8e57da6..aa75343 100644 --- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs +++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Logitech.HID; using RGB.NET.Devices.Logitech.Native; @@ -15,7 +13,7 @@ namespace RGB.NET.Devices.Logitech /// /// Represents a device provider responsible for logitech devices. /// - public class LogitechDeviceProvider : IRGBDeviceProvider + public class LogitechDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -37,21 +35,8 @@ namespace RGB.NET.Devices.Logitech /// public static List PossibleX64NativePaths { get; } = new() { "x64/LogitechLedEnginesWrapper.dll" }; - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for logitech devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - - // ReSharper disable once CollectionNeverQueried.Local - for now this is just to make sure they're never collected - private readonly Dictionary _zoneUpdateQueues = new(); - private LogitechPerDeviceUpdateQueue _perDeviceUpdateQueue; - private LogitechPerKeyUpdateQueue _perKeyUpdateQueue; + private LogitechPerDeviceUpdateQueue? _perDeviceUpdateQueue; + private LogitechPerKeyUpdateQueue? _perKeyUpdateQueue; #endregion @@ -65,116 +50,54 @@ namespace RGB.NET.Devices.Logitech { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(LogitechDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); - _perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(UpdateTrigger); - _perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(UpdateTrigger); } #endregion #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - try + _perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(GetUpdateTrigger()); + _perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(GetUpdateTrigger()); + + _LogitechGSDK.Reload(); + if (!_LogitechGSDK.LogiLedInit()) Throw(new RGBDeviceException("Failed to initialize Logitech-SDK.")); + + _LogitechGSDK.LogiLedSaveCurrentLighting(); + } + + //TODO DarthAffe 04.03.2021: Rework device selection and configuration for HID-based providers + protected override IEnumerable LoadDevices() + { + DeviceChecker.LoadDeviceList(); + + if (DeviceChecker.IsPerKeyDeviceConnected && (_perKeyUpdateQueue != null)) { - if (IsInitialized) - _LogitechGSDK.LogiLedRestoreLighting(); - } - catch { /* At least we tried ... */ } - - IsInitialized = false; - - try - { - UpdateTrigger.Stop(); - - _LogitechGSDK.Reload(); - if (!_LogitechGSDK.LogiLedInit()) return false; - - _LogitechGSDK.LogiLedSaveCurrentLighting(); - - IList devices = new List(); - DeviceChecker.LoadDeviceList(); - - try - { - if (DeviceChecker.IsPerKeyDeviceConnected) - { - (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerKeyDeviceData; - if (loadFilter.HasFlag(deviceType)) //TODO DarthAffe 07.12.2017: Check if it's worth to try another device if the one returned doesn't match the filter - { - ILogitechRGBDevice device = new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0)); - device.Initialize(_perKeyUpdateQueue); - devices.Add(device); - } - } - } - catch { if (throwExceptions) throw; } - - try - { - if (DeviceChecker.IsPerDeviceDeviceConnected) - { - (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerDeviceDeviceData; - if (loadFilter.HasFlag(deviceType)) //TODO DarthAffe 07.12.2017: Check if it's worth to try another device if the one returned doesn't match the filter - { - ILogitechRGBDevice device = new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0)); - device.Initialize(_perDeviceUpdateQueue); - devices.Add(device); - } - } - } - catch { if (throwExceptions) throw; } - - try - { - if (DeviceChecker.IsZoneDeviceConnected) - { - foreach ((string model, RGBDeviceType deviceType, int _, int zones) in DeviceChecker.ZoneDeviceData) - try - { - if (loadFilter.HasFlag(deviceType)) - { - LogitechZoneUpdateQueue updateQueue = new(UpdateTrigger, deviceType); - ILogitechRGBDevice device = new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones)); - device.Initialize(updateQueue); - devices.Add(device); - _zoneUpdateQueues.Add(deviceType, updateQueue); - } - } - catch { if (throwExceptions) throw; } - } - } - catch { if (throwExceptions) throw; } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; + (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerKeyDeviceData; + yield return new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0), _perKeyUpdateQueue); } - return true; + if (DeviceChecker.IsPerDeviceDeviceConnected && (_perDeviceUpdateQueue != null)) + { + (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerDeviceDeviceData; + yield return new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0), _perDeviceUpdateQueue); + } + + if (DeviceChecker.IsZoneDeviceConnected) + { + foreach ((string model, RGBDeviceType deviceType, int _, int zones) in DeviceChecker.ZoneDeviceData) + { + LogitechZoneUpdateQueue updateQueue = new(GetUpdateTrigger(), deviceType); + yield return new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones), updateQueue); + } + } } /// - public void Dispose() + public override void Dispose() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + base.Dispose(); try { _LogitechGSDK.LogiLedRestoreLighting(); } catch { /* at least we tried */ } diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs index 8855e6b..b65ba13 100644 --- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs @@ -17,26 +17,25 @@ namespace RGB.NET.Devices.Logitech /// Initializes a new instance of the class. /// /// The specific information provided by logitech for the per-device-lightable device - internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info) - : base(info) - { } + internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } #endregion #region Methods - /// - public override void Initialize(UpdateQueue updateQueue) + private void InitializeLayout() { - base.Initialize(updateQueue); - AddLed(LedId.Custom1, new Point(0, 0), new Size(10, 10)); } /// protected override object GetLedCustomData(LedId ledId) => (ledId, LogitechLedId.DEVICE); /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate.Take(1))); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate.Take(1))); #endregion } diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs index 1fbec2d..29660c3 100644 --- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.Logitech @@ -17,8 +16,8 @@ namespace RGB.NET.Devices.Logitech /// Initializes a new instance of the class. /// /// The specific information provided by logitech for the per-key-lightable device - internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info) - : base(info) + internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) { } #endregion @@ -29,7 +28,7 @@ namespace RGB.NET.Devices.Logitech protected override object GetLedCustomData(LedId ledId) => (ledId, PerKeyIdMapping.DEFAULT.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : LogitechLedId.Invalid); /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); #endregion } diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs index 5e7b8c9..120dbf1 100644 --- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.Logitech @@ -36,21 +35,20 @@ namespace RGB.NET.Devices.Logitech /// Initializes a new instance of the class. /// /// The specific information provided by logitech for the zone-lightable device - internal LogitechZoneRGBDevice(LogitechRGBDeviceInfo info) - : base(info) + internal LogitechZoneRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) { _baseLedId = BASE_LED_MAPPING.TryGetValue(info.DeviceType, out LedId id) ? id : LedId.Custom1; + + InitializeLayout(); } #endregion #region Methods - /// - public override void Initialize(UpdateQueue updateQueue) + private void InitializeLayout() { - base.Initialize(updateQueue); - for (int i = 0; i < DeviceInfo.Zones; i++) AddLed(_baseLedId + i, new Point(i * 10, 0), new Size(10, 10)); } @@ -59,7 +57,7 @@ namespace RGB.NET.Devices.Logitech protected override object? GetLedCustomData(LedId ledId) => (int)(ledId - _baseLedId); /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); #endregion } diff --git a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs index cd09af0..c30d4a2 100644 --- a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Msi /// /// Represents a MSI RGB-device. /// - internal interface IMsiRGBDevice : IRGBDevice - { - void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount); - } + public interface IMsiRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index 44b52eb..888155b 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -1,75 +1,23 @@ -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Msi { /// - /// /// /// Represents a generic MSI-device. (keyboard, mouse, headset, mousepad). /// public abstract class MsiRGBDevice : AbstractRGBDevice, IMsiRGBDevice where TDeviceInfo : MsiRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected MsiDeviceUpdateQueue? DeviceUpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by MSI for the device. - protected MsiRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount) - { - DeviceUpdateQueue = updateQueue; - - InitializeLayout(ledCount); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(int ledCount); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) - => DeviceUpdateQueue?.SetData(GetUpdateData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int)))); - - /// - public override void Dispose() - { - try { DeviceUpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } + protected MsiRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new MsiDeviceUpdateQueue(updateTrigger, info.MsiDeviceType)) + { } #endregion } diff --git a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs index 8a41f90..629212c 100644 --- a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs @@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi /// Initializes a new instance of the class. /// /// The specific information provided by MSI for graphics cards. - internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info) - : base(info) - { } + internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(ledCount); + } #endregion #region Methods - /// - protected override void InitializeLayout(int ledCount) + private void InitializeLayout(int ledCount) { for (int i = 0; i < ledCount; i++) { diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs index 5cf8b00..01f25ad 100644 --- a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs @@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi /// Initializes a new instance of the class. /// /// The specific information provided by MSI for the mainboard. - internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info) - : base(info) - { } + internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(ledCount); + } #endregion #region Methods - /// - protected override void InitializeLayout(int ledCount) + private void InitializeLayout(int ledCount) { for (int i = 0; i < ledCount; i++) { diff --git a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs index dd4b702..79ad777 100644 --- a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs @@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi /// Initializes a new instance of the class. /// /// The specific information provided by MSI for the mouse. - internal MsiMouseRGBDevice(MsiRGBDeviceInfo info) - : base(info) - { } + internal MsiMouseRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(ledCount); + } #endregion #region Methods - /// - protected override void InitializeLayout(int ledCount) + private void InitializeLayout(int ledCount) { for (int i = 0; i < ledCount; i++) { diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index a5b718f..00abd7b 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Msi.Exceptions; using RGB.NET.Devices.Msi.Native; @@ -15,7 +13,7 @@ namespace RGB.NET.Devices.Msi /// /// Represents a device provider responsible for MSI devices. /// - public class MsiDeviceProvider : IRGBDeviceProvider + public class MsiDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -37,20 +35,6 @@ namespace RGB.NET.Devices.Msi /// public static List PossibleX64NativePaths { get; } = new() { "x64/MysticLight_SDK.dll" }; - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for corsair devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -63,102 +47,58 @@ namespace RGB.NET.Devices.Msi { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(MsiDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - IsInitialized = false; + _MsiSDK.Reload(); - try - { - UpdateTrigger.Stop(); - - _MsiSDK.Reload(); - - IList devices = new List(); - - int errorCode; - if ((errorCode = _MsiSDK.Initialize()) != 0) - ThrowMsiError(errorCode); - - if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0) - ThrowMsiError(errorCode); - - for (int i = 0; i < deviceTypes.Length; i++) - { - try - { - string deviceType = deviceTypes[i]; - int ledCount = ledCounts[i]; - - //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) - if (deviceType.Equals("MSI_MB")) - { - MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType); - IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard")); - motherboard.Initialize(updateQueue, ledCount); - devices.Add(motherboard); - } - else if (deviceType.Equals("MSI_VGA")) - { - //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds - //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. - - MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType); - IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard")); - graphicscard.Initialize(updateQueue, ledCount); - devices.Add(graphicscard); - } - else if (deviceType.Equals("MSI_MOUSE")) - { - //Hex3l: Every led under MSI_MOUSE should be a different mouse. Handling all the mouses together seems a good way to avoid overlapping of leds - //Hex3l: The led name is the name of the mouse (e.g. msi CLUTCH GM11) we could provide it in device info. - - MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType); - IMsiRGBDevice mouses = new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse")); - mouses.Initialize(updateQueue, ledCount); - devices.Add(mouses); - } - - //TODO DarthAffe 22.02.2020: Add other devices - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; + int errorCode; + if ((errorCode = _MsiSDK.Initialize()) != 0) + ThrowMsiError(errorCode); } - private void ThrowMsiError(int errorCode) => throw new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)); + protected override IEnumerable LoadDevices() + { + int errorCode; + if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0) + ThrowMsiError(errorCode); + + for (int i = 0; i < deviceTypes.Length; i++) + { + string deviceType = deviceTypes[i]; + int ledCount = ledCounts[i]; + + if (deviceType.Equals("MSI_MB")) + { + //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) + yield return new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard"), ledCount, GetUpdateTrigger()); + } + else if (deviceType.Equals("MSI_VGA")) + { + //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds + //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. + yield return new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard"), ledCount, GetUpdateTrigger()); + } + else if (deviceType.Equals("MSI_MOUSE")) + { + //Hex3l: Every led under MSI_MOUSE should be a different mouse. Handling all the mouses together seems a good way to avoid overlapping of leds + //Hex3l: The led name is the name of the mouse (e.g. msi CLUTCH GM11) we could provide it in device info. + yield return new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse"), ledCount, GetUpdateTrigger()); + } + } + } + + private void ThrowMsiError(int errorCode) => Throw(new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode))); /// - public void Dispose() + public override void Dispose() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + base.Dispose(); try { _MsiSDK.UnloadMsiSDK(); } catch { /* at least we tried */ } diff --git a/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs index 544df33..d717599 100644 --- a/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Novation /// /// Represents a novation RGB-device. /// - internal interface INovationRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } + public interface INovationRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs index d6669ce..ffa5d9c 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs @@ -1,76 +1,45 @@ using System; using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.Novation { /// - /// /// /// Represents a generic Novation-device. (launchpad). /// public abstract class NovationRGBDevice : AbstractRGBDevice, INovationRGBDevice where TDeviceInfo : NovationRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// The used to update this . - /// - // ReSharper disable once MemberCanBePrivate.Global - protected MidiUpdateQueue? UpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by Novation for the device. - protected NovationRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } + protected NovationRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, GetUpdateQueue(updateTrigger, info)) + { } #endregion #region Methods - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - UpdateQueue = DeviceInfo.ColorCapabilities switch + private static UpdateQueue GetUpdateQueue(IDeviceUpdateTrigger updateTrigger, TDeviceInfo info) => + info.ColorCapabilities switch { - NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId), - NovationColorCapabilities.RGB => new RGBColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId), + NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, info.DeviceId), + NovationColorCapabilities.RGB => new RGBColorUpdateQueue(updateTrigger, info.DeviceId), _ => throw new ArgumentOutOfRangeException() }; - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); /// /// Resets the back to default. /// - public virtual void Reset() => UpdateQueue?.Reset(); + public virtual void Reset() => UpdateQueue.Reset(); /// /// @@ -78,9 +47,6 @@ namespace RGB.NET.Devices.Novation { Reset(); - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - base.Dispose(); } diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs index 39271aa..6be8738 100644 --- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs @@ -17,16 +17,17 @@ namespace RGB.NET.Devices.Novation /// Initializes a new instance of the class. /// /// The specific information provided by Novation for the launchpad - internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info) - : base(info) - { } + internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { Dictionary mapping = GetDeviceMapping(); diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs index 89ef95d..e0af6f2 100644 --- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs +++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using RGB.NET.Core; using Sanford.Multimedia.Midi; @@ -14,7 +13,7 @@ namespace RGB.NET.Devices.Novation /// /// Represents a device provider responsible for Novation devices. /// - public class NovationDeviceProvider : IRGBDeviceProvider + public class NovationDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -24,20 +23,6 @@ namespace RGB.NET.Devices.Novation /// public static NovationDeviceProvider Instance => _instance ?? new NovationDeviceProvider(); - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for novation devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -50,73 +35,32 @@ namespace RGB.NET.Devices.Novation { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(NovationDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { } + + protected override IEnumerable LoadDevices() { - IsInitialized = false; - - try + for (int index = 0; index < OutputDeviceBase.DeviceCount; index++) { - UpdateTrigger.Stop(); + MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index); + if (outCaps.name == null) continue; - IList devices = new List(); + NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices)) + .Cast() + .FirstOrDefault(x => x.GetDeviceId()?.ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant()) ?? false); - if (loadFilter.HasFlag(RGBDeviceType.LedMatrix)) - for (int index = 0; index < OutputDeviceBase.DeviceCount; index++) - { - try - { - MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index); - if (outCaps.name == null) continue; + if (deviceId == null) continue; - NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices)) - .Cast() - .FirstOrDefault(x => x.GetDeviceId()?.ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant()) ?? false); + NovationColorCapabilities colorCapability = deviceId.GetColorCapability(); + if (colorCapability == NovationColorCapabilities.None) continue; - if (deviceId == null) continue; - - NovationColorCapabilities colorCapability = deviceId.GetColorCapability(); - if (colorCapability == NovationColorCapabilities.None) continue; - - INovationRGBDevice device = new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping())); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger.Start(); - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + yield return new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping()), GetUpdateTrigger()); } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; - } - - /// - public void Dispose() - { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); } #endregion diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs index 79165d3..eca3fd1 100644 --- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs +++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs @@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the chroma link. - internal RazerChromaLinkRGBDevice(RazerChromaLinkRGBDeviceInfo info) - : base(info) - { } + internal RazerChromaLinkRGBDevice(RazerChromaLinkRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerChromaLinkUpdateQueue(updateTrigger, info.DeviceId)) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { for (int i = 0; i < _Defines.CHROMALINK_MAX_LEDS; i++) AddLed(LedId.Custom1 + i, new Point(i * 11, 0), new Size(10, 10)); @@ -37,9 +38,6 @@ namespace RGB.NET.Devices.Razer /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1; - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerChromaLinkUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - #endregion } } diff --git a/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs index 9cf89ad..e04f35a 100644 --- a/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs @@ -5,9 +5,6 @@ namespace RGB.NET.Devices.Razer /// /// Represents a razer RGB-device. /// - internal interface IRazerRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - void Reset(); - } + public interface IRazerRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs index 6e7c61a..d9dd0ae 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.Razer @@ -12,32 +11,15 @@ namespace RGB.NET.Devices.Razer public abstract class RazerRGBDevice : AbstractRGBDevice, IRazerRGBDevice where TDeviceInfo : RazerRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected RazerUpdateQueue? UpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by razer for the device. - protected RazerRGBDevice(TDeviceInfo info) + protected RazerRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) { - this.DeviceInfo = info; - RequiresFlush = true; } @@ -45,35 +27,8 @@ namespace RGB.NET.Devices.Razer #region Methods - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - UpdateQueue = CreateUpdateQueue(updateTrigger); - } - - /// - /// Creates a specific for this device. - /// - /// The trigger used to update the queue. - /// The for this device. - protected abstract RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger); - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); - - /// - /// Resets the device. - /// - public void Reset() => UpdateQueue?.Reset(); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); /// public override void Dispose() diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs index 27ebbb0..e3fcf52 100644 --- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs @@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the headset. - internal RazerHeadsetRGBDevice(RazerHeadsetRGBDeviceInfo info) - : base(info) - { } + internal RazerHeadsetRGBDevice(RazerHeadsetRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerHeadsetUpdateQueue(updateTrigger, info.DeviceId)) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { for (int i = 0; i < _Defines.HEADSET_MAX_LEDS; i++) AddLed(LedId.Headset1 + i, new Point(i * 11, 0), new Size(10, 10)); @@ -37,9 +38,6 @@ namespace RGB.NET.Devices.Razer /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerHeadsetUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - #endregion } } diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs index f55ea9a..9a674d9 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs @@ -25,16 +25,17 @@ namespace RGB.NET.Devices.Razer /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the keyboard. - internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info) - : base(info) - { } + internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerKeyboardUpdateQueue(updateTrigger, info.DeviceId)) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { for (int i = 0; i < _Defines.KEYBOARD_MAX_ROW; i++) for (int j = 0; j < _Defines.KEYBOARD_MAX_COLUMN; j++) @@ -44,9 +45,6 @@ namespace RGB.NET.Devices.Razer /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape; - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeyboardUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - #endregion } } diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs index 2fac949..365ad6d 100644 --- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs @@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the keypad. - internal RazerKeypadRGBDevice(RazerKeypadRGBDeviceInfo info) - : base(info) - { } + internal RazerKeypadRGBDevice(RazerKeypadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerKeypadUpdateQueue(updateTrigger, info.DeviceId)) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { for (int i = 0; i < _Defines.KEYPAD_MAX_ROW; i++) for (int j = 0; j < _Defines.KEYPAD_MAX_COLUMN; j++) @@ -38,9 +39,6 @@ namespace RGB.NET.Devices.Razer /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1; - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeypadUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - #endregion } } diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs index 983d90f..b3fe8f6 100644 --- a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs @@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the mouse. - internal RazerMouseRGBDevice(RazerMouseRGBDeviceInfo info) - : base(info) - { } + internal RazerMouseRGBDevice(RazerMouseRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerMouseUpdateQueue(updateTrigger, info.DeviceId)) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { for (int i = 0; i < _Defines.MOUSE_MAX_ROW; i++) for (int j = 0; j < _Defines.MOUSE_MAX_COLUMN; j++) @@ -38,9 +39,6 @@ namespace RGB.NET.Devices.Razer /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMouseUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - #endregion } } diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs index 285e211..2b5734c 100644 --- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs @@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer /// Initializes a new instance of the class. /// /// The specific information provided by CUE for the mousepad. - internal RazerMousepadRGBDevice(RazerMousepadRGBDeviceInfo info) - : base(info) - { } + internal RazerMousepadRGBDevice(RazerMousepadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerMousepadUpdateQueue(updateTrigger, info.DeviceId)) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { for (int i = 0; i < _Defines.MOUSEPAD_MAX_LEDS; i++) AddLed(LedId.Mousepad1 + i, new Point(i * 11, 0), new Size(10, 10)); @@ -36,10 +37,6 @@ namespace RGB.NET.Devices.Razer /// protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1; - - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMousepadUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - #endregion } } diff --git a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs index a44c4e2..752e224 100644 --- a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs +++ b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs @@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Razer /// /// Represents a device provider responsible for razer devices. /// - public class RazerDeviceProvider : IRGBDeviceProvider + public class RazerDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -37,25 +37,11 @@ namespace RGB.NET.Devices.Razer /// public static List PossibleX64NativePaths { get; } = new() { @"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll" }; - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - /// /// Forces to load the devices represented by the emulator even if they aren't reported to exist. /// public bool LoadEmulatorDevices { get; set; } = false; - /// - /// The used to trigger the updates for razer devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -68,127 +54,75 @@ namespace RGB.NET.Devices.Razer { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(RazerDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - if (IsInitialized) - TryUnInit(); + TryUnInit(); - IsInitialized = false; + _RazerSDK.Reload(); - try - { - UpdateTrigger.Stop(); - - _RazerSDK.Reload(); - - RazerError error; - if (((error = _RazerSDK.Init()) != RazerError.Success) - && Enum.IsDefined(typeof(RazerError), error)) //HACK DarthAffe 08.02.2018: The x86-SDK seems to have a problem here ... - ThrowRazerError(error); - - IList devices = new List(); - - if (loadFilter.HasFlag(RGBDeviceType.Keyboard)) - foreach ((Guid guid, string model) in Razer.Devices.KEYBOARDS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.KEYBOARDS.FirstOrDefault().guid != guid))) continue; - - RazerKeyboardRGBDevice device = new(new RazerKeyboardRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Mouse)) - foreach ((Guid guid, string model) in Razer.Devices.MICE) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.MICE.FirstOrDefault().guid != guid))) continue; - - RazerMouseRGBDevice device = new(new RazerMouseRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Headset)) - foreach ((Guid guid, string model) in Razer.Devices.HEADSETS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.HEADSETS.FirstOrDefault().guid != guid))) continue; - - RazerHeadsetRGBDevice device = new(new RazerHeadsetRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Mousepad)) - foreach ((Guid guid, string model) in Razer.Devices.MOUSEMATS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.MOUSEMATS.FirstOrDefault().guid != guid))) continue; - - RazerMousepadRGBDevice device = new(new RazerMousepadRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Keypad)) - foreach ((Guid guid, string model) in Razer.Devices.KEYPADS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.KEYPADS.FirstOrDefault().guid != guid))) continue; - - RazerKeypadRGBDevice device = new(new RazerKeypadRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Keyboard)) - foreach ((Guid guid, string model) in Razer.Devices.CHROMALINKS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.CHROMALINKS.FirstOrDefault().guid != guid))) continue; - - RazerChromaLinkRGBDevice device = new(new RazerChromaLinkRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - UpdateTrigger.Start(); - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - TryUnInit(); - if (throwExceptions) throw; - return false; - } - - return true; + RazerError error; + if (((error = _RazerSDK.Init()) != RazerError.Success) + && Enum.IsDefined(typeof(RazerError), error)) //HACK DarthAffe 08.02.2018: The x86-SDK seems to have a problem here ... + ThrowRazerError(error); } - + + protected override IEnumerable LoadDevices() + { + foreach ((Guid guid, string model) in Razer.Devices.KEYBOARDS) + { + if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) + && (!LoadEmulatorDevices || (Razer.Devices.KEYBOARDS.FirstOrDefault().guid != guid))) continue; + + yield return new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(guid, model), GetUpdateTrigger()); + } + + foreach ((Guid guid, string model) in Razer.Devices.MICE) + { + if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) + && (!LoadEmulatorDevices || (Razer.Devices.MICE.FirstOrDefault().guid != guid))) continue; + + yield return new RazerMouseRGBDevice(new RazerMouseRGBDeviceInfo(guid, model), GetUpdateTrigger()); + } + + foreach ((Guid guid, string model) in Razer.Devices.HEADSETS) + { + if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) + && (!LoadEmulatorDevices || (Razer.Devices.HEADSETS.FirstOrDefault().guid != guid))) continue; + + yield return new RazerHeadsetRGBDevice(new RazerHeadsetRGBDeviceInfo(guid, model), GetUpdateTrigger()); + } + + foreach ((Guid guid, string model) in Razer.Devices.MOUSEMATS) + { + if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) + && (!LoadEmulatorDevices || (Razer.Devices.MOUSEMATS.FirstOrDefault().guid != guid))) continue; + + yield return new RazerMousepadRGBDevice(new RazerMousepadRGBDeviceInfo(guid, model), GetUpdateTrigger()); + } + + foreach ((Guid guid, string model) in Razer.Devices.KEYPADS) + { + if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) + && (!LoadEmulatorDevices || (Razer.Devices.KEYPADS.FirstOrDefault().guid != guid))) continue; + + yield return new RazerKeypadRGBDevice(new RazerKeypadRGBDeviceInfo(guid, model), GetUpdateTrigger()); + } + + foreach ((Guid guid, string model) in Razer.Devices.CHROMALINKS) + { + if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) + && (!LoadEmulatorDevices || (Razer.Devices.CHROMALINKS.FirstOrDefault().guid != guid))) continue; + + yield return new RazerChromaLinkRGBDevice(new RazerChromaLinkRGBDeviceInfo(guid, model), GetUpdateTrigger()); + } + } + private void ThrowRazerError(RazerError errorCode) => throw new RazerException(errorCode); private void TryUnInit() @@ -198,15 +132,9 @@ namespace RGB.NET.Devices.Razer } /// - public void Dispose() + public override void Dispose() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + base.Dispose(); TryUnInit(); diff --git a/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs index 57364d9..0270a27 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.SteelSeries { @@ -7,7 +6,5 @@ namespace RGB.NET.Devices.SteelSeries /// Represents a steelseries RGB-device. /// internal interface ISteelSeriesRGBDevice : IRGBDevice - { - void Initialize(UpdateQueue updateQueue, Dictionary ledMapping); - } + { } } diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs index 9cc5f39..d97bb12 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.SteelSeries @@ -13,19 +12,7 @@ namespace RGB.NET.Devices.SteelSeries { #region Properties & Fields - private Dictionary _ledMapping = new(); - - /// - /// - /// Gets information about the . - /// - public override SteelSeriesRGBDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue? UpdateQueue { get; set; } + private readonly Dictionary _ledMapping; #endregion @@ -35,34 +22,30 @@ namespace RGB.NET.Devices.SteelSeries /// Initializes a new instance of the class. /// /// The generic information provided by SteelSeries for the device. - internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info) + internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info, string apiName, Dictionary ledMapping, IDeviceUpdateTrigger updateTrigger) + : base(info, new SteelSeriesDeviceUpdateQueue(updateTrigger, apiName)) { - this.DeviceInfo = info; + this._ledMapping = ledMapping; + + InitializeLayout(); } #endregion #region Methods - /// - /// Initializes the device. - /// - void ISteelSeriesRGBDevice.Initialize(UpdateQueue updateQueue, Dictionary ledMapping) + private void InitializeLayout() { - _ledMapping = ledMapping; - int counter = 0; - foreach (KeyValuePair mapping in ledMapping) + foreach (KeyValuePair mapping in _ledMapping) AddLed(mapping.Key, new Point((counter++) * 10, 0), new Size(10, 10)); - - UpdateQueue = updateQueue; } /// protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); /// public override void Dispose() diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs index f42885f..f1793fd 100644 --- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs +++ b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.SteelSeries.API; using RGB.NET.Devices.SteelSeries.HID; @@ -12,7 +10,7 @@ namespace RGB.NET.Devices.SteelSeries /// /// Represents a device provider responsible for SteelSeries- devices. /// - public class SteelSeriesDeviceProvider : IRGBDeviceProvider + public class SteelSeriesDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -22,20 +20,6 @@ namespace RGB.NET.Devices.SteelSeries /// public static SteelSeriesDeviceProvider Instance => _instance ?? new SteelSeriesDeviceProvider(); - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for SteelSeries devices. - /// - public SteelSeriesDeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -48,67 +32,41 @@ namespace RGB.NET.Devices.SteelSeries { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SteelSeriesDeviceProvider)}"); _instance = this; - - UpdateTrigger = new SteelSeriesDeviceUpdateTrigger(); } #endregion #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - try - { - IsInitialized = false; - - UpdateTrigger.Stop(); - - if (!SteelSeriesSDK.IsInitialized) - SteelSeriesSDK.Initialize(); - - IList devices = new List(); - DeviceChecker.LoadDeviceList(loadFilter); - - try - { - foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, Dictionary ledMapping) in DeviceChecker.ConnectedDevices) - { - ISteelSeriesRGBDevice device = new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(deviceType, model, steelSeriesDeviceType)); - string apiName = steelSeriesDeviceType.GetAPIName() ?? throw new RGBDeviceException($"Missing API-name for device {model}"); - SteelSeriesDeviceUpdateQueue updateQueue = new(UpdateTrigger, apiName); - device.Initialize(updateQueue, ledMapping); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - IsInitialized = false; - if (throwExceptions) throw; - return false; - } - - return true; + if (!SteelSeriesSDK.IsInitialized) + SteelSeriesSDK.Initialize(); } - - /// - public void Dispose() - { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + DeviceChecker.LoadDeviceList(loadFilter); + + return base.GetLoadedDevices(loadFilter); + } + + protected override IEnumerable LoadDevices() + { + foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, Dictionary ledMapping) in DeviceChecker.ConnectedDevices) + { + string? apiName = steelSeriesDeviceType.GetAPIName(); + if (apiName == null) + Throw(new RGBDeviceException($"Missing API-name for device {model}")); + else + yield return new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(deviceType, model, steelSeriesDeviceType), apiName, ledMapping, GetUpdateTrigger()); + } + } + + /// + public override void Dispose() + { + base.Dispose(); try { SteelSeriesSDK.Dispose(); } catch { /* shit happens */ } diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs index ab658e5..545dccd 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs @@ -8,22 +8,12 @@ using RGB.NET.Core; namespace RGB.NET.Devices.WS281X.Arduino { // ReSharper disable once InconsistentNaming - /// /// /// Represents an arduino WS2812 device. /// public class ArduinoWS2812USBDevice : AbstractRGBDevice, ILedStripe { #region Properties & Fields - - /// - /// Gets the update queue performing updates for this device. - /// - public ArduinoWS2812USBUpdateQueue UpdateQueue { get; } - - /// - public override ArduinoWS2812USBDeviceInfo DeviceInfo { get; } - /// /// Gets the channel (as defined in the arduino-sketch) this device is attached to. /// @@ -39,18 +29,19 @@ namespace RGB.NET.Devices.WS281X.Arduino /// The update trigger used by this queue. /// The update queue performing updates for this device. /// The channel (as defined in the arduino-sketch) this device is attached to. - public ArduinoWS2812USBDevice(ArduinoWS2812USBDeviceInfo deviceInfo, ArduinoWS2812USBUpdateQueue updateQueue, int channel) + public ArduinoWS2812USBDevice(ArduinoWS2812USBDeviceInfo deviceInfo, ArduinoWS2812USBUpdateQueue updateQueue, int channel, int ledCount) + : base(deviceInfo, updateQueue) { - this.DeviceInfo = deviceInfo; - this.UpdateQueue = updateQueue; this.Channel = channel; + + InitializeLayout(ledCount); } #endregion #region Methods - internal void Initialize(int ledCount) + private void InitializeLayout(int ledCount) { for (int i = 0; i < ledCount; i++) AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); @@ -65,15 +56,6 @@ namespace RGB.NET.Devices.WS281X.Arduino /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - /// - public override void Dispose() - { - try { UpdateQueue.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - #endregion } } diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs index c6aa63c..adbf0bf 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs @@ -67,15 +67,14 @@ namespace RGB.NET.Devices.WS281X.Arduino /// public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) { + //TODO DarthAffe 04.03.2021: one queue per device ArduinoWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection); IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels(); int counter = 0; foreach ((int channel, int ledCount) in channels) { string name = string.Format(Name ?? $"Arduino WS2812 USB ({Port}) [{{0}}]", ++counter); - ArduinoWS2812USBDevice device = new(new ArduinoWS2812USBDeviceInfo(name), queue, channel); - device.Initialize(ledCount); - yield return device; + yield return new ArduinoWS2812USBDevice(new ArduinoWS2812USBDeviceInfo(name), queue, channel, ledCount); } } diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs index 5bb6bcc..9ff359d 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs @@ -2,13 +2,12 @@ // ReSharper disable UnusedMember.Global using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.WS281X.Bitwizard { // ReSharper disable once InconsistentNaming - /// + /// /// /// Represents an bitwizard WS2812 USB device. /// @@ -18,14 +17,6 @@ namespace RGB.NET.Devices.WS281X.Bitwizard private readonly int _ledOffset; - /// - /// Gets the update queue performing updates for this device. - /// - public BitwizardWS2812USBUpdateQueue UpdateQueue { get; } - - /// - public override BitwizardWS2812USBDeviceInfo DeviceInfo { get; } - #endregion #region Constructors @@ -35,19 +26,18 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// /// The update trigger used by this queue. /// The update queue performing updates for this device. - public BitwizardWS2812USBDevice(BitwizardWS2812USBDeviceInfo deviceInfo, BitwizardWS2812USBUpdateQueue updateQueue, int ledOffset) + public BitwizardWS2812USBDevice(BitwizardWS2812USBDeviceInfo deviceInfo, BitwizardWS2812USBUpdateQueue updateQueue, int ledOffset, int ledCount) + : base(deviceInfo, updateQueue) { - this.DeviceInfo = deviceInfo; - this.UpdateQueue = updateQueue; - this._ledOffset = ledOffset; + InitializeLayout(ledCount); } #endregion #region Methods - internal void Initialize(int ledCount) + private void InitializeLayout(int ledCount) { for (int i = 0; i < ledCount; i++) AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); @@ -59,15 +49,6 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - /// - public override void Dispose() - { - try { UpdateQueue.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - #endregion } } diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs index 3a46ac1..558548a 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs @@ -36,15 +36,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// public string? Name { get; set; } - /// - /// Gets or sets the pin sed to control the leds. - /// - public int Pin { get; set; } = 0; - - /// - /// Gets or sets the amount of leds of this device. - /// - public int StripLength { get; set; } = 384; + public List<(int pin, int stripLength)> Strips { get; } = new(); /// /// Gets or sets the amount of leds controlled by one pin. @@ -60,9 +52,11 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// Initializes a new instance of the class. /// /// The serial connection used for the device. - public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection) + public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection, params (int pin, int stripLength)[] strips) { this.SerialConnection = serialConnection; + + Strips.AddRange(strips); } /// @@ -70,9 +64,11 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// /// The name of the serial-port to connect to. /// The baud-rate of the serial-connection. - public BitwizardWS281XDeviceDefinition(string port, int baudRate = 115200) + public BitwizardWS281XDeviceDefinition(string port, int baudRate = 115200, params (int pin, int stripLength)[] strips) { SerialConnection = new SerialPortConnection(port, baudRate); + + Strips.AddRange(strips); } #endregion @@ -82,12 +78,13 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) { - BitwizardWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection); - string name = Name ?? $"Bitwizard WS2812 USB ({Port})"; - int ledOffset = Pin * MaxStripLength; - BitwizardWS2812USBDevice device = new(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset); - device.Initialize(StripLength); - yield return device; + foreach ((int pin, int stripLength) in Strips) + { + BitwizardWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection); + string name = Name ?? $"Bitwizard WS2812 USB ({Port}) Pin {pin}"; + int ledOffset = pin * MaxStripLength; + yield return new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset, stripLength); + } } #endregion diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs index 635d61b..3e59cd1 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs @@ -16,14 +16,6 @@ namespace RGB.NET.Devices.WS281X.NodeMCU { #region Properties & Fields - /// - /// Gets the update queue performing updates for this device. - /// - public NodeMCUWS2812USBUpdateQueue UpdateQueue { get; } - - /// - public override NodeMCUWS2812USBDeviceInfo DeviceInfo { get; } - /// /// Gets the channel (as defined in the NodeMCU-sketch) this device is attached to. /// @@ -39,18 +31,19 @@ namespace RGB.NET.Devices.WS281X.NodeMCU /// The update trigger used by this queue. /// The update queue performing updates for this device. /// The channel (as defined in the NodeMCU-sketch) this device is attached to. - public NodeMCUWS2812USBDevice(NodeMCUWS2812USBDeviceInfo deviceInfo, NodeMCUWS2812USBUpdateQueue updateQueue, int channel) + public NodeMCUWS2812USBDevice(NodeMCUWS2812USBDeviceInfo info, NodeMCUWS2812USBUpdateQueue updateQueue, int channel, int ledCount) + : base(info, updateQueue) { - this.DeviceInfo = deviceInfo; - this.UpdateQueue = updateQueue; this.Channel = channel; + + InitializeLayout(ledCount); } #endregion #region Methods - internal void Initialize(int ledCount) + private void InitializeLayout(int ledCount) { for (int i = 0; i < ledCount; i++) AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); @@ -65,15 +58,6 @@ namespace RGB.NET.Devices.WS281X.NodeMCU /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - /// - public override void Dispose() - { - try { UpdateQueue.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - #endregion } } diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs index b87f39e..04d34ff 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs @@ -72,9 +72,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU foreach ((int channel, int ledCount) in channels) { string name = string.Format(Name ?? $"NodeMCU WS2812 WIFI ({Hostname}) [{{0}}]", ++counter); - NodeMCUWS2812USBDevice device = new(new NodeMCUWS2812USBDeviceInfo(name), queue, channel); - device.Initialize(ledCount); - yield return device; + yield return new NodeMCUWS2812USBDevice(new NodeMCUWS2812USBDeviceInfo(name), queue, channel, ledCount); } } diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs index aeee841..deac3ae 100644 --- a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs +++ b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs @@ -2,8 +2,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using RGB.NET.Core; namespace RGB.NET.Devices.WS281X @@ -13,7 +11,7 @@ namespace RGB.NET.Devices.WS281X /// Represents a device provider responsible for WS2812B- and WS2811-Led-devices. /// // ReSharper disable once InconsistentNaming - public class WS281XDeviceProvider : IRGBDeviceProvider + public class WS281XDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -23,12 +21,6 @@ namespace RGB.NET.Devices.WS281X /// public static WS281XDeviceProvider Instance => _instance ?? new WS281XDeviceProvider(); - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - /// /// Gets a list of all defined device-definitions. /// @@ -36,11 +28,6 @@ namespace RGB.NET.Devices.WS281X // ReSharper disable once ReturnTypeCanBeEnumerable.Global public List DeviceDefinitions { get; } = new(); - /// - /// The used to trigger the updates for corsair devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -53,8 +40,6 @@ namespace RGB.NET.Devices.WS281X { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WS281XDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion @@ -68,49 +53,23 @@ namespace RGB.NET.Devices.WS281X // ReSharper disable once UnusedMember.Global public void AddDeviceDefinition(IWS281XDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false) + protected override void InitializeSDK() { } + + protected override IEnumerable LoadDevices() { - IsInitialized = false; - - try + int i = 0; + foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions) { - UpdateTrigger.Stop(); - - List devices = new(); - foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions) - { - try - { - devices.AddRange(deviceDefinition.CreateDevices(UpdateTrigger)); - } - catch { if (throwExceptions) throw; } - } - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + IDeviceUpdateTrigger updateTrigger = GetUpdateTrigger(i++); + foreach (IRGBDevice device in deviceDefinition.CreateDevices(updateTrigger)) + yield return device; } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; } - - /// - public void Dispose() - { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */} - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + /// + public override void Dispose() + { + base.Dispose(); DeviceDefinitions.Clear(); } diff --git a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs index b7356eb..932aff9 100644 --- a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs @@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Wooting.Generic /// /// Represents a Wooting RGB-device. /// - internal interface IWootingRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } + public interface IWootingRGBDevice : IRGBDevice + { } } diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs index 4f843a8..b7a4d22 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs @@ -10,60 +10,15 @@ namespace RGB.NET.Devices.Wooting.Generic public abstract class WootingRGBDevice : AbstractRGBDevice, IWootingRGBDevice where TDeviceInfo : WootingRGBDeviceInfo { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue? UpdateQueue { get; set; } - - #endregion - #region Constructors /// /// Initializes a new instance of the class. /// /// The generic information provided by Wooting for the device. - protected WootingRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - UpdateQueue = new WootingUpdateQueue(updateTrigger); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } + protected WootingRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new WootingUpdateQueue(updateTrigger)) + { } #endregion } diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs index bd8edea..2f7ac90 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; @@ -25,16 +24,17 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// Initializes a new instance of the class. /// /// The specific information provided by Wooting for the keyboard - internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info) - : base(info) - { } + internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + InitializeLayout(); + } #endregion #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() { //TODO DarthAffe 13.02.2021: Check how the mapping can work without knowing the physical layout Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][WootingPhysicalKeyboardLayout.US]; @@ -47,7 +47,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][WootingPhysicalKeyboardLayout.US][ledId]; /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate)); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); #endregion } diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index e0dc3e5..6decd4a 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; @@ -15,7 +13,7 @@ namespace RGB.NET.Devices.Wooting /// /// Represents a device provider responsible for Wooting devices. /// - public class WootingDeviceProvider : IRGBDeviceProvider + public class WootingDeviceProvider : AbstractRGBDeviceProvider { #region Properties & Fields @@ -37,20 +35,6 @@ namespace RGB.NET.Devices.Wooting /// public static List PossibleX64NativePaths { get; } = new() { "x64/wooting-rgb-sdk64.dll" }; - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - - /// - /// The used to trigger the updates for cooler master devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - #endregion #region Constructors @@ -61,68 +45,42 @@ namespace RGB.NET.Devices.Wooting /// Thrown if this constructor is called even if there is already an instance of this class. public WootingDeviceProvider() { - if (_instance != null) - throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); } #endregion #region Methods - /// - /// Thrown if the SDK failed to initialize - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + protected override void InitializeSDK() { - IsInitialized = false; + _WootingSDK.Reload(); + } - try + protected override IEnumerable LoadDevices() + { + if (_WootingSDK.KeyboardConnected()) { - UpdateTrigger.Stop(); - - _WootingSDK.Reload(); - - IList devices = new List(); - if (_WootingSDK.KeyboardConnected()) + _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!; + IWootingRGBDevice? device = nativeDeviceInfo.Model switch { - _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!; - IWootingRGBDevice device = nativeDeviceInfo.Model switch - { - "Wooting two" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo)), - "Wooting one" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne)), - _ => throw new RGBDeviceException("No supported Wooting keyboard connected") - }; + "Wooting two" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo), GetUpdateTrigger()), + "Wooting one" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne), GetUpdateTrigger()), + _ => null + }; - device.Initialize(UpdateTrigger); - devices.Add(device); - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + if (device == null) + Throw(new RGBDeviceException("No supported Wooting keyboard connected")); + else + yield return device; } - catch - { - if (throwExceptions) throw; - return false; - } - - return true; } /// - public void Dispose() + public override void Dispose() { - try { UpdateTrigger.Dispose(); } - catch { /* at least we tried */ } - - foreach (IRGBDevice device in Devices) - try { device.Dispose(); } - catch { /* at least we tried */ } - Devices = Enumerable.Empty(); + base.Dispose(); try { _WootingSDK.Close(); } catch { /* Unlucky.. */ }