diff --git a/RGB.NET.Core/Decorators/AbstractDecorateable.cs b/RGB.NET.Core/Decorators/AbstractDecorateable.cs index 8acfc54..1120bc4 100644 --- a/RGB.NET.Core/Decorators/AbstractDecorateable.cs +++ b/RGB.NET.Core/Decorators/AbstractDecorateable.cs @@ -14,13 +14,18 @@ namespace RGB.NET.Core private readonly List _decorators = new(); /// - public IReadOnlyCollection Decorators + public IReadOnlyList Decorators { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + protected AbstractDecoratable() { - get - { - lock (_decorators) - return new ReadOnlyCollection(_decorators); - } + Decorators = new ReadOnlyCollection(_decorators); } #endregion diff --git a/RGB.NET.Core/Decorators/IDecoratable.cs b/RGB.NET.Core/Decorators/IDecoratable.cs index 2892638..ae8def2 100644 --- a/RGB.NET.Core/Decorators/IDecoratable.cs +++ b/RGB.NET.Core/Decorators/IDecoratable.cs @@ -20,7 +20,7 @@ namespace RGB.NET.Core /// /// Gets a readonly-list of all attached to this . /// - IReadOnlyCollection Decorators { get; } + IReadOnlyList Decorators { get; } /// /// Adds an to the . diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs index 81ac6f2..6b4ee57 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs @@ -30,7 +30,7 @@ namespace RGB.NET.Core protected Dictionary UpdateTriggerMapping { get; } = new(); /// - public ReadOnlyCollection<(int id, IDeviceUpdateTrigger trigger)> UpdateTriggers => new(UpdateTriggerMapping.Select(x => (x.Key, x.Value)).ToList()); + public IReadOnlyList<(int id, IDeviceUpdateTrigger trigger)> UpdateTriggers => new ReadOnlyCollection<(int id, IDeviceUpdateTrigger trigger)>(UpdateTriggerMapping.Select(x => (x.Key, x.Value)).ToList()); #endregion diff --git a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs index d2a8d1d..1193a65 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; namespace RGB.NET.Core { @@ -31,7 +30,7 @@ namespace RGB.NET.Core /// /// Gets a collection registered to this device provider. /// - ReadOnlyCollection<(int id, IDeviceUpdateTrigger trigger)> UpdateTriggers { get; } + IReadOnlyList<(int id, IDeviceUpdateTrigger trigger)> UpdateTriggers { get; } #endregion diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs index 6b9d726..3cebaa7 100644 --- a/RGB.NET.Core/RGBSurface.cs +++ b/RGB.NET.Core/RGBSurface.cs @@ -26,20 +26,15 @@ namespace RGB.NET.Core /// /// Gets a readonly list containing all loaded . + /// This collection should be locked when enumerated in a multi-threaded application. /// - public IEnumerable Devices - { - get - { - lock (_devices) - return new ReadOnlyCollection(_devices); - } - } + public IReadOnlyList Devices { get; } /// /// Gets a readonly list containing all registered . + /// This collection should be locked when enumerated in a multi-threaded application. /// - public IEnumerable UpdateTriggers => new ReadOnlyCollection(_updateTriggers); + public IReadOnlyList UpdateTriggers { get; } /// /// Gets a copy of the representing this . @@ -53,7 +48,7 @@ namespace RGB.NET.Core { get { - lock (_devices) + lock (Devices) return _devices.SelectMany(x => x); } } @@ -124,6 +119,9 @@ namespace RGB.NET.Core public RGBSurface() { _deltaTimeCounter = Stopwatch.StartNew(); + + Devices = new ReadOnlyCollection(_devices); + UpdateTriggers = new ReadOnlyCollection(_updateTriggers); } #endregion @@ -146,8 +144,8 @@ namespace RGB.NET.Core bool render = customData["render"] as bool? ?? true; bool updateDevices = customData["updateDevices"] as bool? ?? true; - lock (_updateTriggers) - lock (_devices) + lock (UpdateTriggers) + lock (Devices) { OnUpdating(updateTrigger, customData); @@ -178,7 +176,7 @@ namespace RGB.NET.Core public void Dispose() { List devices; - lock (_devices) + lock (Devices) devices = new List(_devices); foreach (IRGBDevice device in devices) @@ -267,7 +265,7 @@ namespace RGB.NET.Core /// The to attach. public void Attach(IRGBDevice device) { - lock (_devices) + lock (Devices) { if (string.IsNullOrWhiteSpace(device.DeviceInfo.DeviceName)) throw new RGBDeviceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' has no valid name."); if (device.Surface != null) throw new RGBSurfaceException($"The device '{device.DeviceInfo.DeviceName}' is already attached to a surface."); @@ -287,7 +285,7 @@ namespace RGB.NET.Core /// true if the could be detached; false otherwise. public void Detach(IRGBDevice device) { - lock (_devices) + lock (Devices) { if (!_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.DeviceName}' is not attached to this surface."); @@ -314,7 +312,7 @@ namespace RGB.NET.Core private void UpdateSurfaceRectangle() { - lock (_devices) + lock (Devices) { Rectangle devicesRectangle = new(_devices.Select(d => d.Boundary)); Boundary = Boundary.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height)); diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs index 98a7237..6c10753 100644 --- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs +++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs @@ -92,10 +92,20 @@ namespace RGB.NET.Core if (UpdateTask != null) { UpdateTokenSource?.Cancel(); - // ReSharper disable once MethodSupportsCancellation - UpdateTask.Wait(); - UpdateTask.Dispose(); - UpdateTask = null; + try + { + // ReSharper disable once MethodSupportsCancellation + UpdateTask.Wait(); + } + catch (AggregateException) + { + // ignored + } + finally + { + UpdateTask.Dispose(); + UpdateTask = null; + } } } } diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs index 74fd5b2..8e3fdfc 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs @@ -48,6 +48,21 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Mouse3, (0,2) } } }, + + { CoolerMasterDevicesIndexes.MM830, new Dictionary + { + { LedId.Mouse1, (0,0) }, + { LedId.Mouse2, (0,1) }, + { LedId.Mouse3, (0,2) }, + { LedId.Mouse4, (0,3) }, + { LedId.Mouse5, (0,4) }, + { LedId.Mouse6, (0,5) }, + { LedId.Mouse7, (0,6) }, + { LedId.Mouse8, (0,7) }, + { LedId.Mouse9, (0,8) }, + { LedId.Mouse10, (0,9) }, + } + }, }; #endregion diff --git a/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs b/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs index a7606af..d7f46be 100644 --- a/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs +++ b/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs @@ -68,7 +68,7 @@ namespace RGB.NET.Devices.DMX.E131 this.Hostname = deviceDefinition.Hostname; this.Port = deviceDefinition.Port; this.Universe = deviceDefinition.Universe; - + byte[]? cid = deviceDefinition.CID; if ((cid == null) || (cid.Length != CID_LENGTH)) { @@ -76,7 +76,7 @@ namespace RGB.NET.Devices.DMX.E131 new Random().NextBytes(cid); } - CID = cid!; + CID = cid; DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } diff --git a/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs b/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs index 6b25a54..53c2015 100644 --- a/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs +++ b/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs @@ -7,10 +7,14 @@ namespace RGB.NET.Devices.Wooting.Enum /// public enum WootingDeviceType { + /// /// 10 Keyless Keyboard. E.g. Wooting One + /// KeyboardTKL = 1, + /// /// Full Size keyboard. E.g. Wooting Two + /// Keyboard = 2 } } diff --git a/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs b/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs deleted file mode 100644 index c25afa4..0000000 --- a/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs +++ /dev/null @@ -1,21 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -using System.ComponentModel; - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Wooting.Enum -{ - /// - /// Contains a list of available device-indexes. - /// - public enum WootingDevicesIndexes - { - [Description("Wooting One")] - WootingOne = 0, - - [Description("Wooting Two")] - WootingTwo = 1 - } -} diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs index 850f8a4..f217c00 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs @@ -1,6 +1,7 @@ using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Helper; +using RGB.NET.Devices.Wooting.Native; namespace RGB.NET.Devices.Wooting.Generic { @@ -28,9 +29,9 @@ namespace RGB.NET.Devices.Wooting.Generic public object? LayoutMetadata { get; set; } /// - /// Gets the of the . + /// Gets the of the . /// - public WootingDevicesIndexes DeviceIndex { get; } + public WootingDeviceType WootingDeviceType { get; } #endregion @@ -40,13 +41,13 @@ namespace RGB.NET.Devices.Wooting.Generic /// Internal constructor of managed . /// /// The type of the . - /// The of the . - internal WootingRGBDeviceInfo(RGBDeviceType deviceType, WootingDevicesIndexes deviceIndex) + /// The of the . + internal WootingRGBDeviceInfo(RGBDeviceType deviceType, _WootingDeviceInfo deviceInfo) { this.DeviceType = deviceType; - this.DeviceIndex = deviceIndex; + this.WootingDeviceType = deviceInfo.DeviceType; - Model = deviceIndex.GetDescription(); + Model = deviceInfo.Model; DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs index 0ce7e41..618f31c 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs @@ -13,9 +13,9 @@ namespace RGB.NET.Devices.Wooting.Keyboard { #region Properties & Fields - #region Wooting One + #region TKL - private static readonly Dictionary WootingOne_US = new() + private static readonly Dictionary TKL_US = new() { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, @@ -111,7 +111,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_ArrowRight, (5,16) } }; - private static readonly Dictionary WootingOne_UK = new() + private static readonly Dictionary TKL_UK = new() { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, @@ -178,7 +178,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_L, (3,9) }, { LedId.Keyboard_SemicolonAndColon, (3,10) }, { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, { LedId.Keyboard_Enter, (3,13) }, { LedId.Keyboard_LeftShift, (4,0) }, @@ -211,9 +211,9 @@ namespace RGB.NET.Devices.Wooting.Keyboard #endregion - #region Wooting Two + #region Fullsize - private static readonly Dictionary WootingTwo_US = new() + private static readonly Dictionary Fullsize_US = new() { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, @@ -330,7 +330,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_NumPeriodAndDelete, (5,19) } }; - private static readonly Dictionary WootingTwo_UK = new() + private static readonly Dictionary Fullsize_UK = new() { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, @@ -454,20 +454,20 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// /// Contains all the hardware-id mappings for Wooting devices. /// - public static readonly Dictionary>> Mapping = + public static readonly Dictionary>> Mapping = new() { - { WootingDevicesIndexes.WootingOne, new Dictionary> + { WootingDeviceType.KeyboardTKL, new Dictionary> { - { WootingPhysicalKeyboardLayout.US, WootingOne_US }, - { WootingPhysicalKeyboardLayout.UK, WootingOne_UK } + { WootingPhysicalKeyboardLayout.US, TKL_US }, + { WootingPhysicalKeyboardLayout.UK, TKL_UK } } }, - { WootingDevicesIndexes.WootingTwo, new Dictionary> + { WootingDeviceType.Keyboard, new Dictionary> { - { WootingPhysicalKeyboardLayout.US, WootingTwo_US }, - { WootingPhysicalKeyboardLayout.UK, WootingTwo_UK } + { WootingPhysicalKeyboardLayout.US, Fullsize_US }, + { WootingPhysicalKeyboardLayout.UK, Fullsize_UK } } } }; diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs index 4e643bd..cace6cd 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs @@ -38,14 +38,14 @@ namespace RGB.NET.Devices.Wooting.Keyboard 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]; + Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.WootingDeviceType][WootingPhysicalKeyboardLayout.US]; foreach (KeyValuePair led in mapping) AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19)); } /// - protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][WootingPhysicalKeyboardLayout.US][ledId]; + protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.WootingDeviceType][WootingPhysicalKeyboardLayout.US][ledId]; /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs index f2dcfdf..abfe5dd 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs @@ -1,6 +1,7 @@ using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; +using RGB.NET.Devices.Wooting.Native; namespace RGB.NET.Devices.Wooting.Keyboard { @@ -22,9 +23,9 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// /// Internal constructor of managed . /// - /// The index of the . - internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex) - : base(RGBDeviceType.Keyboard, deviceIndex) + /// The native . + internal WootingKeyboardRGBDeviceInfo(_WootingDeviceInfo deviceInfo) + : base(RGBDeviceType.Keyboard, deviceInfo) { } #endregion diff --git a/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs b/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs index b1a7d51..fab57c6 100644 --- a/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs @@ -20,5 +20,7 @@ namespace RGB.NET.Devices.Wooting.Native internal byte KeycodeLimit { get; private set; } internal WootingDeviceType DeviceType { get; private set; } + + internal bool V2Interface { get; set; } } } diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index 6c06d35..3f964e0 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -70,17 +70,8 @@ namespace RGB.NET.Devices.Wooting if (_WootingSDK.KeyboardConnected()) { _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!; - IWootingRGBDevice? device = nativeDeviceInfo.Model switch - { - "Wooting two" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo), GetUpdateTrigger()), - "Wooting one" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne), GetUpdateTrigger()), - _ => null - }; - if (device == null) - Throw(new RGBDeviceException("No supported Wooting keyboard connected")); - else - yield return device; + yield return new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(nativeDeviceInfo), GetUpdateTrigger()); } } }