1
0
mirror of https://github.com/DarthAffe/RGB.NET.git synced 2025-12-13 01:58:30 +00:00

Streamlined device loading/handling in device providers

This commit is contained in:
Darth Affe 2021-03-04 23:33:00 +01:00
parent f6f3e9185c
commit 2a9a43683c
81 changed files with 867 additions and 1864 deletions

View File

@ -34,7 +34,7 @@ namespace RGB.NET.Core
}
/// <inheritdoc />
public abstract TDeviceInfo DeviceInfo { get; }
public TDeviceInfo DeviceInfo { get; }
/// <inheritdoc />
IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo;
@ -52,6 +52,8 @@ namespace RGB.NET.Core
/// </summary>
protected Dictionary<LedId, Led> LedMapping { get; } = new();
protected IUpdateQueue UpdateQueue { get; }
#region Indexer
/// <inheritdoc />
@ -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
/// <inheritdoc />
@ -112,14 +124,16 @@ namespace RGB.NET.Core
}
}
/// <summary>
/// Sends all the updated <see cref="Led"/> to the device.
/// </summary>
protected virtual void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
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 */ }
}
/// <summary>
@ -128,11 +142,6 @@ namespace RGB.NET.Core
protected virtual void DeviceUpdate()
{ }
/// <summary>
/// Sends all the updated <see cref="Led"/> to the device.
/// </summary>
protected abstract void UpdateLeds(IEnumerable<Led> ledsToUpdate);
/// <summary>
/// Initializes the <see cref="Led"/> with the specified id.
/// </summary>

View File

@ -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<IRGBDevice> Devices { get; protected set; } = Enumerable.Empty<IRGBDevice>();
protected Dictionary<int, IDeviceUpdateTrigger> UpdateTriggers { get; } = new();
#endregion
#region Events
public event EventHandler<Exception>? 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<IRGBDevice>(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<IRGBDevice> 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<IRGBDevice> 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<IRGBDevice>();
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<IRGBDevice> devices = Devices;
Reset();
foreach (IRGBDevice device in devices)
device.Dispose();
}
#endregion
}
}

View File

@ -22,6 +22,15 @@ namespace RGB.NET.Core
#endregion
#region Events
/// <summary>
/// Occurs when an exception is thrown in the device provider
/// </summary>
event EventHandler<Exception>? Exception;
#endregion
#region Methods
bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false);

View File

@ -30,6 +30,9 @@ namespace RGB.NET.Core
/// <param name="updateData">Optional custom-data passed to the subscribers of the <see cref="Update"/>.event.</param>
protected virtual void OnUpdate(CustomUpdateData? updateData = null) => Update?.Invoke(this, updateData ?? new CustomUpdateData());
/// <inheritdoc />
public abstract void Start();
/// <inheritdoc />
public abstract void Dispose();

View File

@ -86,7 +86,7 @@ namespace RGB.NET.Core
/// <summary>
/// Starts the trigger.
/// </summary>
public void Start()
public override void Start()
{
if (IsRunning) return;

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
namespace RGB.NET.Core
{
public interface IUpdateQueue<TIdentifier, TData> : IDisposable
where TIdentifier : notnull
{
/// <summary>
/// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available.
/// </summary>
/// <param name="dataSet">The set of data.</param>
// ReSharper disable once MemberCanBeProtected.Global
void SetData(IEnumerable<(TIdentifier, TData)> dataSet);
/// <summary>
/// Resets the current data set.
/// </summary>
void Reset();
}
public interface IUpdateQueue : IUpdateQueue<object, Color>
{ }
}

View File

@ -10,7 +10,7 @@ namespace RGB.NET.Core
/// </summary>
/// <typeparam name="TIdentifier">The type of the key used to identify some data.</typeparam>
/// <typeparam name="TData">The type of the data.</typeparam>
public abstract class UpdateQueue<TIdentifier, TData> : IDisposable
public abstract class UpdateQueue<TIdentifier, TData> : IUpdateQueue<TIdentifier, TData>
where TIdentifier : notnull
{
#region Properties & Fields
@ -123,7 +123,7 @@ namespace RGB.NET.Core
/// <summary>
/// Represents a generic <see cref="UpdateQueue{TIdentifier,TData}"/> using an object as the key and a color as the value.
/// </summary>
public abstract class UpdateQueue : UpdateQueue<object, Color>
public abstract class UpdateQueue : UpdateQueue<object, Color>, IUpdateQueue
{
#region Constructors

View File

@ -16,5 +16,7 @@ namespace RGB.NET.Core
/// Occurs when the trigger wants to cause an update.
/// </summary>
event EventHandler<CustomUpdateData>? Update;
void Start();
}
}

View File

@ -44,7 +44,7 @@ namespace RGB.NET.Core
/// <summary>
/// Starts the trigger if needed, causing it to performing updates.
/// </summary>
private void Start()
public override void Start()
{
if (UpdateTask == null)
{

View File

@ -56,7 +56,7 @@ namespace RGB.NET.Core
/// <summary>
/// Starts the trigger if needed, causing it to performing updates.
/// </summary>
public void Start()
public override void Start()
{
lock (_lock)
{

View File

@ -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
/// <summary>
/// Represents a device provider responsible for Cooler Master devices.
/// </summary>
public class AsusDeviceProvider : IRGBDeviceProvider
public class AsusDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -24,20 +22,6 @@ namespace RGB.NET.Devices.Asus
/// </summary>
public static AsusDeviceProvider Instance => _instance ?? new AsusDeviceProvider();
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for asus devices.
/// </summary>
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
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK()
{
IsInitialized = false;
try
{
UpdateTrigger.Stop();
// ReSharper disable once SuspiciousTypeConversion.Global
_sdk = (IAuraSdk2)new AuraSdk();
_sdk.SwitchMode();
}
protected override IEnumerable<IRGBDevice> LoadDevices()
{
if (_sdk == null) yield break;
IList<IRGBDevice> devices = new List<IRGBDevice>();
foreach (IAuraSyncDevice device in _sdk.Enumerate(0))
{
try
yield return (AsusDeviceType)device.Type switch
{
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;
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())
};
}
if (loadFilter.HasFlag(rgbDevice.DeviceInfo.DeviceType))
{
rgbDevice.Initialize(UpdateTrigger);
devices.Add(rgbDevice);
}
}
catch
{
if (throwExceptions)
throw;
}
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions)
throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
try { _sdk?.ReleaseControl(0); }
catch { /* at least we tried */ }

View File

@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusDramRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the DRAM.</param>
internal AsusDramRGBDevice(AsusRGBDeviceInfo info)
: base(info)
{ }
internal AsusDramRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)

View File

@ -1,75 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Core;
namespace RGB.NET.Devices.Asus
{
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}" />
/// <inheritdoc cref="IAsusRGBDevice" />
/// <summary>
/// Represents a generic Asus-device. (keyboard, mouse, headset, mousepad).
/// </summary>
public abstract class AsusRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, IAsusRGBDevice
where TDeviceInfo : AsusRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Asus.AsusRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected AsusUpdateQueue? UpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="AsusRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by Asus for the device.</param>
protected AsusRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
UpdateQueue = new AsusUpdateQueue(updateTrigger);
UpdateQueue.Initialize(DeviceInfo.Device);
}
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout();
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
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
}

View File

@ -21,18 +21,19 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusHeadsetRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the headset.</param>
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
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)_baseLedId;
#endregion
}
}

View File

@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Asus
/// <summary>
/// The device to be updated.
/// </summary>
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 <see cref="AsusUpdateQueue"/> class.
/// </summary>
/// <param name="updateTrigger">The update trigger used by this queue.</param>
public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger)
public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger, IAuraSyncDevice device)
: base(updateTrigger)
{ }
{
this.Device = device;
}
#endregion
#region Methods
/// <summary>
/// Initializes the queue.
/// </summary>
/// <param name="device">The device to be updated.</param>
public void Initialize(IAuraSyncDevice device)
{
Device = device;
}
/// <inheritdoc />
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))

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Asus
/// <summary>
/// Represents a asus RGB-device.
/// </summary>
internal interface IAsusRGBDevice : IRGBDevice
{
void Initialize(IDeviceUpdateTrigger updateTrigger);
}
public interface IAsusRGBDevice : IRGBDevice
{ }
}

View File

@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusGraphicsCardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the graphics card.</param>
internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info)
: base(info)
{ }
internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)

View File

@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusHeadsetRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the headset.</param>
internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info)
: base(info)
{ }
internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)

View File

@ -24,16 +24,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusKeyboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the keyboard.</param>
internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info)
: base(info)
{ }
internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
Dictionary<AsusLedId, LedId> reversedMapping = AsusKeyboardLedMapping.MAPPING.ToDictionary(x => x.Value, x => x.Key);

View File

@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusMainboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the mainboard.</param>
internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info)
: base(info)
{ }
internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)

View File

@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Asus.AsusMouseRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Asus for the mouse.</param>
internal AsusMouseRGBDevice(AsusRGBDeviceInfo info)
: base(info)
{ }
internal AsusMouseRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)

View File

@ -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
/// <summary>
/// Represents a device provider responsible for Cooler Master devices.
/// </summary>
public class CoolerMasterDeviceProvider : IRGBDeviceProvider
public class CoolerMasterDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -37,20 +35,6 @@ namespace RGB.NET.Devices.CoolerMaster
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new() { "x64/CMSDK.dll" };
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for cooler master devices.
/// </summary>
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
/// <inheritdoc />
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;
if (_CoolerMasterSDK.GetSDKVersion() <= 0) Throw(new RGBDeviceException("Failed to initialize CoolerMaster-SDK"));
}
IList<IRGBDevice> devices = new List<IRGBDevice>();
foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes)))
protected override IEnumerable<IRGBDevice> LoadDevices()
{
try
foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes)))
{
RGBDeviceType deviceType = index.GetDeviceType();
if (deviceType == RGBDeviceType.None) continue;
if (_CoolerMasterSDK.IsDevicePlugged(index))
{
if (!loadFilter.HasFlag(deviceType)) continue;
ICoolerMasterRGBDevice device;
if (!_CoolerMasterSDK.EnableLedControl(true, index))
Throw(new RGBDeviceException("Failed to enable LED control for device " + index));
else
{
switch (deviceType)
{
case RGBDeviceType.Keyboard:
CoolerMasterPhysicalKeyboardLayout physicalLayout = _CoolerMasterSDK.GetDeviceLayout(index);
device = new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, physicalLayout));
yield return new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, _CoolerMasterSDK.GetDeviceLayout(index)), GetUpdateTrigger());
break;
case RGBDeviceType.Mouse:
device = new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index));
yield return new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index), GetUpdateTrigger());
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);
Throw(new RGBDeviceException("Unknown Device-Type"));
break;
}
}
catch { if (throwExceptions) throw; }
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions)
throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
// 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 */ }
}
#endregion

View File

@ -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
{
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}" />
/// <inheritdoc cref="ICoolerMasterRGBDevice" />
/// <summary>
/// Represents a generic CoolerMaster-device. (keyboard, mouse, headset, mousepad).
/// </summary>
public abstract class CoolerMasterRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, ICoolerMasterRGBDevice
where TDeviceInfo : CoolerMasterRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.CoolerMaster.CoolerMasterRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected CoolerMasterUpdateQueue? UpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CoolerMasterRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by CoolerMaster for the device.</param>
protected CoolerMasterRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
protected CoolerMasterRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new CoolerMasterUpdateQueue(updateTrigger, info.DeviceIndex))
{ }
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
UpdateQueue = new CoolerMasterUpdateQueue(updateTrigger, DeviceInfo.DeviceIndex);
}
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout();
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc cref="IDisposable.Dispose" />
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}.Dispose" />
public override void Dispose()
{
try { UpdateQueue?.Dispose(); }
catch { /* at least we tried */ }
_CoolerMasterSDK.EnableLedControl(false, DeviceInfo.DeviceIndex);
base.Dispose();

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.CoolerMaster
/// <summary>
/// Represents a CoolerMaster RGB-device.
/// </summary>
internal interface ICoolerMasterRGBDevice : IRGBDevice
{
void Initialize(IDeviceUpdateTrigger updateTrigger);
}
public interface ICoolerMasterRGBDevice : IRGBDevice
{ }
}

View File

@ -22,16 +22,17 @@ namespace RGB.NET.Devices.CoolerMaster
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.CoolerMaster.CoolerMasterKeyboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CoolerMaster for the keyboard</param>
internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info)
: base(info)
{ }
internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary<CoolerMasterPhysicalKeyboardLayout, Dictionary<LedId, (int row, int column)>>? deviceMappings))
throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex}");

View File

@ -16,16 +16,15 @@ namespace RGB.NET.Devices.CoolerMaster
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.CoolerMaster.CoolerMasterMouseRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CoolerMaster for the mouse</param>
internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info)
: base(info)
internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{ }
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
Dictionary<LedId, (int row, int column)> mapping = CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex];

View File

@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Corsair
/// <summary>
/// Represents a device provider responsible for corsair (CUE) devices.
/// </summary>
public class CorsairDeviceProvider : IRGBDeviceProvider
public class CorsairDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -37,12 +37,6 @@ namespace RGB.NET.Devices.Corsair
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new() { "x64/CUESDK.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" };
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <summary>
/// Gets the protocol details for the current SDK-connection.
/// </summary>
@ -53,14 +47,6 @@ namespace RGB.NET.Devices.Corsair
/// </summary>
public CorsairError LastError => _CUESDK.CorsairGetLastError();
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for corsair devices.
/// </summary>
public DeviceUpdateTrigger UpdateTrigger { get; }
#endregion
#region Constructors
@ -73,114 +59,68 @@ 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
/// <inheritdoc />
/// <exception cref="RGBDeviceException">Thrown if the SDK is already initialized or if the SDK is not compatible to CUE.</exception>
/// <exception cref="CUEException">Thrown if the CUE-SDK provides an error.</exception>
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK()
{
IsInitialized = false;
try
{
UpdateTrigger.Stop();
_CUESDK.Reload();
ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake());
CorsairError error = LastError;
if (error != CorsairError.Success)
throw new CUEException(error);
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"
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})");
+ $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})"));
// DarthAffe 02.02.2021: 127 is iCUE
if (!_CUESDK.CorsairSetLayerPriority(128))
throw new CUEException(LastError);
Throw(new CUEException(LastError));
}
protected override IEnumerable<IRGBDevice> LoadDevices()
{
Dictionary<string, int> modelCounter = new();
IList<IRGBDevice> devices = new List<IRGBDevice>();
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<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
Reset();
if (throwExceptions) throw;
return false;
}
return true;
}
private static IEnumerable<ICorsairRGBDevice> GetRGBDevice(CorsairRGBDeviceInfo info, int i, _CorsairDeviceInfo nativeDeviceInfo, Dictionary<string, int> modelCounter)
{
CorsairDeviceUpdateQueue updateQueue = new(GetUpdateTrigger(), info.CorsairDeviceIndex);
switch (info.CorsairDeviceType)
{
case CorsairDeviceType.Keyboard:
yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
break;
case CorsairDeviceType.Mouse:
yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
break;
case CorsairDeviceType.Headset:
yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
break;
case CorsairDeviceType.Mousepad:
yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
break;
case CorsairDeviceType.HeadsetStand:
yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
break;
case CorsairDeviceType.MemoryModule:
yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
break;
case CorsairDeviceType.Cooler:
@ -205,7 +145,7 @@ namespace RGB.NET.Devices.Corsair
{
_CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!;
yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter));
yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter), updateQueue);
referenceLed += channelDeviceInfo.deviceLedCount;
channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize);
@ -215,14 +155,12 @@ namespace RGB.NET.Devices.Corsair
channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize);
}
}
break;
// ReSharper disable once RedundantCaseLabel
case CorsairDeviceType.Unknown:
default:
throw new RGBDeviceException("Unknown Device-Type");
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<IRGBDevice>();
IsInitialized = false;
base.Reset();
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
try { _CUESDK.UnloadCUESDK(); }
catch { /* at least we tried */ }

View File

@ -25,16 +25,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairCustomRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the custom-device.</param>
internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info)
: base(info)
{ }
internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
LedId referenceId = GetReferenceLed(DeviceInfo.DeviceType);

View File

@ -1,99 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Core;
namespace RGB.NET.Devices.Corsair
{
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}" />
/// <inheritdoc cref="ICorsairRGBDevice" />
/// <summary>
/// Represents a generic CUE-device. (keyboard, mouse, headset, mousepad).
/// </summary>
public abstract class CorsairRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, ICorsairRGBDevice
where TDeviceInfo : CorsairRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Corsair.CorsairRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets a dictionary containing all <see cref="Led"/> of the <see cref="CorsairRGBDevice{TDeviceInfo}"/>.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected Dictionary<CorsairLedId, Led> InternalLedMapping { get; } = new();
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected CorsairDeviceUpdateQueue? DeviceUpdateQueue { get; set; }
#endregion
#region Indexer
/// <summary>
/// Gets the <see cref="Led"/> with the specified <see cref="CorsairLedId"/>.
/// </summary>
/// <param name="ledId">The <see cref="CorsairLedId"/> of the <see cref="Led"/> to get.</param>
/// <returns>The <see cref="Led"/> with the specified <see cref="CorsairLedId"/> or null if no <see cref="Led"/> is found.</returns>
// ReSharper disable once MemberCanBePrivate.Global
public Led? this[CorsairLedId ledId] => InternalLedMapping.TryGetValue(ledId, out Led? led) ? led : null;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="CorsairRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by CUE for the device.</param>
protected CorsairRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
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);
}
}
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout();
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
=> DeviceUpdateQueue?.SetData(GetUpdateData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid)))));
/// <inheritdoc />
public override void Dispose()
{
try { DeviceUpdateQueue?.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}
protected CorsairRGBDevice(TDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{ }
#endregion
}

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Corsair
/// <summary>
/// Represents a corsair RGB-device.
/// </summary>
internal interface ICorsairRGBDevice : IRGBDevice
{
void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue);
}
public interface ICorsairRGBDevice : IRGBDevice
{ }
}

View File

@ -18,16 +18,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairHeadsetRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the headset</param>
internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info)
: base(info)
{ }
internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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));

View File

@ -23,16 +23,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairHeadsetStandRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the headset stand</param>
internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info)
: base(info)
{ }
internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;

View File

@ -28,16 +28,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairKeyboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the keyboard</param>
internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info)
: base(info)
{ }
internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;

View File

@ -22,16 +22,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairMemoryRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the memory.</param>
internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info)
: base(info)
{ }
internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;

View File

@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairMouseRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the mouse</param>
internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info)
: base(info)
{ }
internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
switch (DeviceInfo.PhysicalLayout)
{

View File

@ -23,16 +23,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Corsair.CorsairMousepadRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the mousepad</param>
internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info)
: base(info)
{ }
internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;

View File

@ -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
/// <summary>
/// Represents a device provider responsible for DMX devices.
/// </summary>
public class DMXDeviceProvider : IRGBDeviceProvider
public class DMXDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -24,22 +22,11 @@ namespace RGB.NET.Devices.DMX
/// </summary>
public static DMXDeviceProvider Instance => _instance ?? new DMXDeviceProvider();
/// <inheritdoc />
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// Gets a list of all defined device-definitions.
/// </summary>
public List<IDMXDeviceDefinition> DeviceDefinitions { get; } = new();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for dmx devices.
/// </summary>
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
/// <param name="deviceDefinition">The <see cref="IDMXDeviceDefinition"/> to add.</param>
public void AddDeviceDefinition(IDMXDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition);
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK() { }
protected override IEnumerable<IRGBDevice> LoadDevices()
{
IsInitialized = false;
try
{
UpdateTrigger.Stop();
IList<IRGBDevice> devices = new List<IRGBDevice>();
foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions)
{
IRGBDevice? device = null;
try
{
if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition)
{
if (e131DMXDeviceDefinition.Leds.Count > 0)
device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds, GetUpdateTrigger(0));
}
catch (Exception ex)
{
E131Device device = new(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds);
device.Initialize(UpdateTrigger);
devices.Add(device);
}
}
}
catch { if (throwExceptions) throw; }
Throw(ex);
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
if (device != null)
yield return device;
}
catch
{
if (throwExceptions) throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
}
#endregion

View File

@ -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
/// <inheritdoc />
public override E131DeviceInfo DeviceInfo { get; }
private readonly Dictionary<LedId, List<(int channel, Func<Color, byte> getValueFunc)>> _ledMappings;
private E131UpdateQueue? _updateQueue;
#endregion
#region Constructors
/// <inheritdoc />
internal E131Device(E131DeviceInfo deviceInfo, Dictionary<LedId, List<(int channel, Func<Color, byte> getValueFunc)>> ledMappings)
internal E131Device(E131DeviceInfo deviceInfo, Dictionary<LedId, List<(int channel, Func<Color, byte> 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);
}
/// <inheritdoc />
protected override object GetLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]);
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => _updateQueue?.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
public override void Dispose()
{
try { _updateQueue?.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}
#endregion
}
}

View File

@ -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
/// <summary>
/// Represents a device provider responsible for debug devices.
/// </summary>
public class DebugDeviceProvider : IRGBDeviceProvider
public class DebugDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -24,13 +22,7 @@ namespace RGB.NET.Devices.Debug
/// </summary>
public static DebugDeviceProvider Instance => _instance ?? new DebugDeviceProvider();
/// <inheritdoc />
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
private List<(IDeviceLayout layout, string imageLayout, Action<IEnumerable<Led>>? updateLedsAction)> _fakeDeviceDefinitions = new();
private List<(IDeviceLayout layout, Action<IEnumerable<Led>>? updateLedsAction)> _fakeDeviceDefinitions = new();
#endregion
@ -54,48 +46,28 @@ namespace RGB.NET.Devices.Debug
/// Adds a new fake device definition.
/// </summary>
/// <param name="layout">The path of the layout file to be used.</param>
/// <param name="imageLayout">The image-layout to load.</param>
/// <param name="updateLedsAction">A action emulating led-updates.</param>
public void AddFakeDeviceDefinition(IDeviceLayout layout, string imageLayout, Action<IEnumerable<Led>>? updateLedsAction = null)
=> _fakeDeviceDefinitions.Add((layout, imageLayout, updateLedsAction));
public void AddFakeDeviceDefinition(IDeviceLayout layout, Action<IEnumerable<Led>>? updateLedsAction = null)
=> _fakeDeviceDefinitions.Add((layout, updateLedsAction));
/// <summary>
/// Removes all previously added fake device definitions.
/// </summary>
public void ClearFakeDeviceDefinitions() => _fakeDeviceDefinitions.Clear();
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false)
{
IsInitialized = false;
try
{
List<IRGBDevice> devices = new();
foreach ((IDeviceLayout layout, string imageLayout, Action<IEnumerable<Led>>? updateLedsAction) in _fakeDeviceDefinitions)
{
DebugRGBDevice device = new(layout, updateLedsAction);
devices.Add(device);
}
protected override void InitializeSDK() { }
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
return true;
}
catch
protected override IEnumerable<IRGBDevice> LoadDevices()
{
if (throwExceptions) throw;
return false;
}
foreach ((IDeviceLayout layout, Action<IEnumerable<Led>>? updateLedsAction) in _fakeDeviceDefinitions)
yield return new DebugRGBDevice(layout, updateLedsAction);
}
/// <inheritdoc />
public void ResetDevices()
{ }
/// <inheritdoc />
public void Dispose()
public override void Dispose()
{
base.Dispose();
_fakeDeviceDefinitions.Clear();
}

View File

@ -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
}
}

View File

@ -13,9 +13,6 @@ namespace RGB.NET.Devices.Debug
{
#region Properties & Fields
/// <inheritdoc />
public override DebugRGBDeviceInfo DeviceInfo { get; }
public IDeviceLayout Layout { get; }
private Action<IEnumerable<Led>>? _updateLedsAction;
@ -27,12 +24,11 @@ namespace RGB.NET.Devices.Debug
/// Internal constructor of <see cref="DebugRGBDeviceInfo"/>.
/// </summary>
internal DebugRGBDevice(IDeviceLayout layout, Action<IEnumerable<Led>>? 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);
}

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Logitech
/// <summary>
/// Represents a logitech RGB-device.
/// </summary>
internal interface ILogitechRGBDevice : IRGBDevice
{
void Initialize(UpdateQueue updateQueue);
}
public interface ILogitechRGBDevice : IRGBDevice
{ }
}

View File

@ -3,60 +3,21 @@
namespace RGB.NET.Devices.Logitech
{
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}" />
/// <inheritdoc cref="ILogitechRGBDevice" />
/// <summary>
/// Represents a generic Logitech-device. (keyboard, mouse, headset, mousepad).
/// </summary>
public abstract class LogitechRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, ILogitechRGBDevice
where TDeviceInfo : LogitechRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Logitech.LogitechRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected UpdateQueue? UpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="LogitechRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by Logitech for the device.</param>
protected LogitechRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
public virtual void Initialize(UpdateQueue updateQueue)
{
UpdateQueue = updateQueue;
}
/// <inheritdoc />
public override void Dispose()
{
try { UpdateQueue?.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}
protected LogitechRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue)
: base(info, updateQueue)
{ }
#endregion
}

View File

@ -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
/// <summary>
/// Represents a device provider responsible for logitech devices.
/// </summary>
public class LogitechDeviceProvider : IRGBDeviceProvider
public class LogitechDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -37,21 +35,8 @@ namespace RGB.NET.Devices.Logitech
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new() { "x64/LogitechLedEnginesWrapper.dll" };
/// <inheritdoc />
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for logitech devices.
/// </summary>
public DeviceUpdateTrigger UpdateTrigger { get; }
// ReSharper disable once CollectionNeverQueried.Local - for now this is just to make sure they're never collected
private readonly Dictionary<RGBDeviceType, LogitechZoneUpdateQueue> _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
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK()
{
try
{
if (IsInitialized)
_LogitechGSDK.LogiLedRestoreLighting();
}
catch { /* At least we tried ... */ }
IsInitialized = false;
try
{
UpdateTrigger.Stop();
_perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(GetUpdateTrigger());
_perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(GetUpdateTrigger());
_LogitechGSDK.Reload();
if (!_LogitechGSDK.LogiLedInit()) return false;
if (!_LogitechGSDK.LogiLedInit()) Throw(new RGBDeviceException("Failed to initialize Logitech-SDK."));
_LogitechGSDK.LogiLedSaveCurrentLighting();
}
IList<IRGBDevice> devices = new List<IRGBDevice>();
//TODO DarthAffe 04.03.2021: Rework device selection and configuration for HID-based providers
protected override IEnumerable<IRGBDevice> LoadDevices()
{
DeviceChecker.LoadDeviceList();
try
{
if (DeviceChecker.IsPerKeyDeviceConnected)
if (DeviceChecker.IsPerKeyDeviceConnected && (_perKeyUpdateQueue != null))
{
(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);
yield return new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0), _perKeyUpdateQueue);
}
}
}
catch { if (throwExceptions) throw; }
try
{
if (DeviceChecker.IsPerDeviceDeviceConnected)
if (DeviceChecker.IsPerDeviceDeviceConnected && (_perDeviceUpdateQueue != null))
{
(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);
yield return new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0), _perDeviceUpdateQueue);
}
}
}
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);
LogitechZoneUpdateQueue updateQueue = new(GetUpdateTrigger(), deviceType);
yield return new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones), updateQueue);
}
}
catch { if (throwExceptions) throw; }
}
}
catch { if (throwExceptions) throw; }
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions)
throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
try { _LogitechGSDK.LogiLedRestoreLighting(); }
catch { /* at least we tried */ }

View File

@ -17,26 +17,25 @@ namespace RGB.NET.Devices.Logitech
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Logitech.LogitechPerDeviceRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by logitech for the per-device-lightable device</param>
internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info)
: base(info)
{ }
internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue)
: base(info, updateQueue)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
public override void Initialize(UpdateQueue updateQueue)
private void InitializeLayout()
{
base.Initialize(updateQueue);
AddLed(LedId.Custom1, new Point(0, 0), new Size(10, 10));
}
/// <inheritdoc />
protected override object GetLedCustomData(LedId ledId) => (ledId, LogitechLedId.DEVICE);
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate.Take(1)));
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate.Take(1)));
#endregion
}

View File

@ -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 <see cref="T:RGB.NET.Devices.Logitech.LogitechPerKeyRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by logitech for the per-key-lightable device</param>
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);
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}

View File

@ -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 <see cref="T:RGB.NET.Devices.Logitech.LogitechZoneRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by logitech for the zone-lightable device</param>
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
/// <inheritdoc />
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);
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Msi
/// <summary>
/// Represents a MSI RGB-device.
/// </summary>
internal interface IMsiRGBDevice : IRGBDevice
{
void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount);
}
public interface IMsiRGBDevice : IRGBDevice
{ }
}

View File

@ -1,75 +1,23 @@
using System.Collections.Generic;
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Core;
namespace RGB.NET.Devices.Msi
{
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}" />
/// <inheritdoc cref="IMsiRGBDevice" />
/// <summary>
/// Represents a generic MSI-device. (keyboard, mouse, headset, mousepad).
/// </summary>
public abstract class MsiRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, IMsiRGBDevice
where TDeviceInfo : MsiRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Msi.MsiRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected MsiDeviceUpdateQueue? DeviceUpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="MsiRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by MSI for the device.</param>
protected MsiRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
public void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount)
{
DeviceUpdateQueue = updateQueue;
InitializeLayout(ledCount);
}
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout(int ledCount);
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
=> DeviceUpdateQueue?.SetData(GetUpdateData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int))));
/// <inheritdoc />
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
}

View File

@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Msi.MsiGraphicsCardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by MSI for graphics cards.</param>
internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info)
: base(info)
{ }
internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout(ledCount);
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout(int ledCount)
private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
{

View File

@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Msi.MsiMainboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by MSI for the mainboard.</param>
internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info)
: base(info)
{ }
internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout(ledCount);
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout(int ledCount)
private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
{

View File

@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Msi.MsiMouseRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by MSI for the mouse.</param>
internal MsiMouseRGBDevice(MsiRGBDeviceInfo info)
: base(info)
{ }
internal MsiMouseRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout(ledCount);
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout(int ledCount)
private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
{

View File

@ -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
/// <summary>
/// Represents a device provider responsible for MSI devices.
/// </summary>
public class MsiDeviceProvider : IRGBDeviceProvider
public class MsiDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -37,20 +35,6 @@ namespace RGB.NET.Devices.Msi
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new() { "x64/MysticLight_SDK.dll" };
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for corsair devices.
/// </summary>
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
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK()
{
IsInitialized = false;
try
{
UpdateTrigger.Stop();
_MsiSDK.Reload();
IList<IRGBDevice> devices = new List<IRGBDevice>();
int errorCode;
if ((errorCode = _MsiSDK.Initialize()) != 0)
ThrowMsiError(errorCode);
}
protected override IEnumerable<IRGBDevice> LoadDevices()
{
int 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);
//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.
MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType);
IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard"));
graphicscard.Initialize(updateQueue, ledCount);
devices.Add(graphicscard);
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.
MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType);
IMsiRGBDevice mouses = new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse"));
mouses.Initialize(updateQueue, ledCount);
devices.Add(mouses);
yield return new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse"), ledCount, GetUpdateTrigger());
}
}
}
//TODO DarthAffe 22.02.2020: Add other devices
}
catch { if (throwExceptions) throw; }
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions)
throw;
return false;
}
return true;
}
private void ThrowMsiError(int errorCode) => throw new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode));
private void ThrowMsiError(int errorCode) => Throw(new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)));
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
try { _MsiSDK.UnloadMsiSDK(); }
catch { /* at least we tried */ }

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Novation
/// <summary>
/// Represents a novation RGB-device.
/// </summary>
internal interface INovationRGBDevice : IRGBDevice
{
void Initialize(IDeviceUpdateTrigger updateTrigger);
}
public interface INovationRGBDevice : IRGBDevice
{ }
}

View File

@ -1,76 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.Novation
{
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}" />
/// <inheritdoc cref="INovationRGBDevice" />
/// <summary>
/// Represents a generic Novation-device. (launchpad).
/// </summary>
public abstract class NovationRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, INovationRGBDevice
where TDeviceInfo : NovationRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Novation.NovationRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// The <see cref="MidiUpdateQueue"/> used to update this <see cref="NovationRGBDevice{TDeviceInfo}"/>.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected MidiUpdateQueue? UpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="NovationRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by Novation for the device.</param>
protected NovationRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
protected NovationRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, GetUpdateQueue(updateTrigger, info))
{ }
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
public void Initialize(IDeviceUpdateTrigger updateTrigger)
private static UpdateQueue GetUpdateQueue(IDeviceUpdateTrigger updateTrigger, TDeviceInfo info) =>
info.ColorCapabilities switch
{
InitializeLayout();
UpdateQueue = DeviceInfo.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()
};
}
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout();
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <summary>
/// Resets the <see cref="NovationRGBDevice{TDeviceInfo}"/> back to default.
/// </summary>
public virtual void Reset() => UpdateQueue?.Reset();
public virtual void Reset() => UpdateQueue.Reset();
/// <inheritdoc cref="IDisposable.Dispose" />
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}.Dispose" />
@ -78,9 +47,6 @@ namespace RGB.NET.Devices.Novation
{
Reset();
try { UpdateQueue?.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}

View File

@ -17,16 +17,17 @@ namespace RGB.NET.Devices.Novation
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Novation.NovationLaunchpadRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Novation for the launchpad</param>
internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info)
: base(info)
{ }
internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
Dictionary<LedId, (byte mode, byte id, int x, int y)> mapping = GetDeviceMapping();

View File

@ -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
/// <summary>
/// Represents a device provider responsible for Novation devices.
/// </summary>
public class NovationDeviceProvider : IRGBDeviceProvider
public class NovationDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -24,20 +23,6 @@ namespace RGB.NET.Devices.Novation
/// </summary>
public static NovationDeviceProvider Instance => _instance ?? new NovationDeviceProvider();
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for novation devices.
/// </summary>
public DeviceUpdateTrigger UpdateTrigger { get; }
#endregion
#region Constructors
@ -50,29 +35,17 @@ 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
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK() { }
protected override IEnumerable<IRGBDevice> LoadDevices()
{
IsInitialized = false;
try
{
UpdateTrigger.Stop();
IList<IRGBDevice> devices = new List<IRGBDevice>();
if (loadFilter.HasFlag(RGBDeviceType.LedMatrix))
for (int index = 0; index < OutputDeviceBase.DeviceCount; index++)
{
try
{
MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index);
if (outCaps.name == null) continue;
@ -86,37 +59,8 @@ namespace RGB.NET.Devices.Novation
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);
yield return new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping()), GetUpdateTrigger());
}
catch { if (throwExceptions) throw; }
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions)
throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
}
#endregion

View File

@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Razer.RazerChromaLinkRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the chroma link.</param>
internal RazerChromaLinkRGBDevice(RazerChromaLinkRGBDeviceInfo info)
: base(info)
{ }
internal RazerChromaLinkRGBDevice(RazerChromaLinkRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new RazerChromaLinkUpdateQueue(updateTrigger, info.DeviceId))
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1;
/// <inheritdoc />
protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerChromaLinkUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
#endregion
}
}

View File

@ -5,9 +5,6 @@ namespace RGB.NET.Devices.Razer
/// <summary>
/// Represents a razer RGB-device.
/// </summary>
internal interface IRazerRGBDevice : IRGBDevice
{
void Initialize(IDeviceUpdateTrigger updateTrigger);
void Reset();
}
public interface IRazerRGBDevice : IRGBDevice
{ }
}

View File

@ -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<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, IRazerRGBDevice
where TDeviceInfo : RazerRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Razer.RazerRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected RazerUpdateQueue? UpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="RazerRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by razer for the device.</param>
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
/// <summary>
/// Initializes the device.
/// </summary>
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
UpdateQueue = CreateUpdateQueue(updateTrigger);
}
/// <summary>
/// Creates a specific <see cref="RazerUpdateQueue"/> for this device.
/// </summary>
/// <param name="updateTrigger">The trigger used to update the queue.</param>
/// <returns>The <see cref="RazerUpdateQueue"/> for this device.</returns>
protected abstract RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger);
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout();
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
/// <summary>
/// Resets the device.
/// </summary>
public void Reset() => UpdateQueue?.Reset();
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
public override void Dispose()

View File

@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Razer.RazerHeadsetRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the headset.</param>
internal RazerHeadsetRGBDevice(RazerHeadsetRGBDeviceInfo info)
: base(info)
{ }
internal RazerHeadsetRGBDevice(RazerHeadsetRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new RazerHeadsetUpdateQueue(updateTrigger, info.DeviceId))
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1;
/// <inheritdoc />
protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerHeadsetUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
#endregion
}
}

View File

@ -25,16 +25,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Razer.RazerKeyboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the keyboard.</param>
internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info)
: base(info)
{ }
internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new RazerKeyboardUpdateQueue(updateTrigger, info.DeviceId))
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape;
/// <inheritdoc />
protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeyboardUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
#endregion
}
}

View File

@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Razer.RazerKeypadRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the keypad.</param>
internal RazerKeypadRGBDevice(RazerKeypadRGBDeviceInfo info)
: base(info)
{ }
internal RazerKeypadRGBDevice(RazerKeypadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new RazerKeypadUpdateQueue(updateTrigger, info.DeviceId))
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1;
/// <inheritdoc />
protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeypadUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
#endregion
}
}

View File

@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Razer.RazerMouseRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the mouse.</param>
internal RazerMouseRGBDevice(RazerMouseRGBDeviceInfo info)
: base(info)
{ }
internal RazerMouseRGBDevice(RazerMouseRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new RazerMouseUpdateQueue(updateTrigger, info.DeviceId))
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1;
/// <inheritdoc />
protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMouseUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
#endregion
}
}

View File

@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the <see cref="T:RGB.NET.Devices.Razer.RazerMousepadRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by CUE for the mousepad.</param>
internal RazerMousepadRGBDevice(RazerMousepadRGBDeviceInfo info)
: base(info)
{ }
internal RazerMousepadRGBDevice(RazerMousepadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, new RazerMousepadUpdateQueue(updateTrigger, info.DeviceId))
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
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
/// <inheritdoc />
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1;
/// <inheritdoc />
protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMousepadUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
#endregion
}
}

View File

@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Razer
/// <summary>
/// Represents a device provider responsible for razer devices.
/// </summary>
public class RazerDeviceProvider : IRGBDeviceProvider
public class RazerDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -37,25 +37,11 @@ namespace RGB.NET.Devices.Razer
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new() { @"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll" };
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// Forces to load the devices represented by the emulator even if they aren't reported to exist.
/// </summary>
public bool LoadEmulatorDevices { get; set; } = false;
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for razer devices.
/// </summary>
public DeviceUpdateTrigger UpdateTrigger { get; }
#endregion
#region Constructors
@ -68,125 +54,73 @@ 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
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK()
{
if (IsInitialized)
TryUnInit();
IsInitialized = false;
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<IRGBDevice> devices = new List<IRGBDevice>();
if (loadFilter.HasFlag(RGBDeviceType.Keyboard))
protected override IEnumerable<IRGBDevice> LoadDevices()
{
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);
yield return new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(guid, model), GetUpdateTrigger());
}
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);
yield return new RazerMouseRGBDevice(new RazerMouseRGBDeviceInfo(guid, model), GetUpdateTrigger());
}
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);
yield return new RazerHeadsetRGBDevice(new RazerHeadsetRGBDeviceInfo(guid, model), GetUpdateTrigger());
}
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);
yield return new RazerMousepadRGBDevice(new RazerMousepadRGBDeviceInfo(guid, model), GetUpdateTrigger());
}
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);
yield return new RazerKeypadRGBDevice(new RazerKeypadRGBDeviceInfo(guid, model), GetUpdateTrigger());
}
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);
yield return new RazerChromaLinkRGBDevice(new RazerChromaLinkRGBDeviceInfo(guid, model), GetUpdateTrigger());
}
catch { if (throwExceptions) throw; }
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
TryUnInit();
if (throwExceptions) throw;
return false;
}
return true;
}
private void ThrowRazerError(RazerError errorCode) => throw new RazerException(errorCode);
@ -198,15 +132,9 @@ namespace RGB.NET.Devices.Razer
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
TryUnInit();

View File

@ -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.
/// </summary>
internal interface ISteelSeriesRGBDevice : IRGBDevice
{
void Initialize(UpdateQueue updateQueue, Dictionary<LedId, SteelSeriesLedId> ledMapping);
}
{ }
}

View File

@ -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<LedId, SteelSeriesLedId> _ledMapping = new();
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="SteelSeriesRGBDevice" />.
/// </summary>
public override SteelSeriesRGBDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected UpdateQueue? UpdateQueue { get; set; }
private readonly Dictionary<LedId, SteelSeriesLedId> _ledMapping;
#endregion
@ -35,34 +22,30 @@ namespace RGB.NET.Devices.SteelSeries
/// Initializes a new instance of the <see cref="SteelSeriesRGBDevice"/> class.
/// </summary>
/// <param name="info">The generic information provided by SteelSeries for the device.</param>
internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info)
internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info, string apiName, Dictionary<LedId, SteelSeriesLedId> ledMapping, IDeviceUpdateTrigger updateTrigger)
: base(info, new SteelSeriesDeviceUpdateQueue(updateTrigger, apiName))
{
this.DeviceInfo = info;
this._ledMapping = ledMapping;
InitializeLayout();
}
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
void ISteelSeriesRGBDevice.Initialize(UpdateQueue updateQueue, Dictionary<LedId, SteelSeriesLedId> ledMapping)
private void InitializeLayout()
{
_ledMapping = ledMapping;
int counter = 0;
foreach (KeyValuePair<LedId, SteelSeriesLedId> mapping in ledMapping)
foreach (KeyValuePair<LedId, SteelSeriesLedId> mapping in _ledMapping)
AddLed(mapping.Key, new Point((counter++) * 10, 0), new Size(10, 10));
UpdateQueue = updateQueue;
}
/// <inheritdoc />
protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId];
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
public override void Dispose()

View File

@ -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
/// <summary>
/// Represents a device provider responsible for SteelSeries- devices.
/// </summary>
public class SteelSeriesDeviceProvider : IRGBDeviceProvider
public class SteelSeriesDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -22,20 +20,6 @@ namespace RGB.NET.Devices.SteelSeries
/// </summary>
public static SteelSeriesDeviceProvider Instance => _instance ?? new SteelSeriesDeviceProvider();
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="SteelSeriesDeviceUpdateTrigger"/> used to trigger the updates for SteelSeries devices.
/// </summary>
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
/// <inheritdoc />
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<IRGBDevice> devices = new List<IRGBDevice>();
protected override IEnumerable<IRGBDevice> GetLoadedDevices(RGBDeviceType loadFilter)
{
DeviceChecker.LoadDeviceList(loadFilter);
try
return base.GetLoadedDevices(loadFilter);
}
protected override IEnumerable<IRGBDevice> LoadDevices()
{
foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, Dictionary<LedId, SteelSeriesLedId> 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);
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());
}
}
catch { if (throwExceptions) throw; }
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
IsInitialized = false;
if (throwExceptions) throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
try { SteelSeriesSDK.Dispose(); }
catch { /* shit happens */ }

View File

@ -8,22 +8,12 @@ using RGB.NET.Core;
namespace RGB.NET.Devices.WS281X.Arduino
{
// ReSharper disable once InconsistentNaming
/// <inheritdoc />
/// <summary>
/// Represents an arduino WS2812 device.
/// </summary>
public class ArduinoWS2812USBDevice : AbstractRGBDevice<ArduinoWS2812USBDeviceInfo>, ILedStripe
{
#region Properties & Fields
/// <summary>
/// Gets the update queue performing updates for this device.
/// </summary>
public ArduinoWS2812USBUpdateQueue UpdateQueue { get; }
/// <inheritdoc />
public override ArduinoWS2812USBDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets the channel (as defined in the arduino-sketch) this device is attached to.
/// </summary>
@ -39,18 +29,19 @@ namespace RGB.NET.Devices.WS281X.Arduino
/// <param name="deviceInfo">The update trigger used by this queue.</param>
/// <param name="updateQueue">The update queue performing updates for this device.</param>
/// <param name="channel">The channel (as defined in the arduino-sketch) this device is attached to.</param>
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
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
public override void Dispose()
{
try { UpdateQueue.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}
#endregion
}
}

View File

@ -67,15 +67,14 @@ namespace RGB.NET.Devices.WS281X.Arduino
/// <inheritdoc />
public IEnumerable<IRGBDevice> 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);
}
}

View File

@ -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
/// <inheritdoc />
/// <inheritdoc cref="AbstractRGBDevice{T}" />
/// <summary>
/// Represents an bitwizard WS2812 USB device.
/// </summary>
@ -18,14 +17,6 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
private readonly int _ledOffset;
/// <summary>
/// Gets the update queue performing updates for this device.
/// </summary>
public BitwizardWS2812USBUpdateQueue UpdateQueue { get; }
/// <inheritdoc />
public override BitwizardWS2812USBDeviceInfo DeviceInfo { get; }
#endregion
#region Constructors
@ -35,19 +26,18 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
/// </summary>
/// <param name="deviceInfo">The update trigger used by this queue.</param>
/// <param name="updateQueue">The update queue performing updates for this device.</param>
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
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
public override void Dispose()
{
try { UpdateQueue.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}
#endregion
}
}

View File

@ -36,15 +36,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Gets or sets the pin sed to control the leds.
/// </summary>
public int Pin { get; set; } = 0;
/// <summary>
/// Gets or sets the amount of leds of this device.
/// </summary>
public int StripLength { get; set; } = 384;
public List<(int pin, int stripLength)> Strips { get; } = new();
/// <summary>
/// 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 <see cref="BitwizardWS281XDeviceDefinition"/> class.
/// </summary>
/// <param name="serialConnection">The serial connection used for the device.</param>
public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection)
public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection, params (int pin, int stripLength)[] strips)
{
this.SerialConnection = serialConnection;
Strips.AddRange(strips);
}
/// <summary>
@ -70,9 +64,11 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
/// </summary>
/// <param name="port">The name of the serial-port to connect to.</param>
/// <param name="baudRate">The baud-rate of the serial-connection.</param>
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
@ -81,13 +77,14 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
/// <inheritdoc />
public IEnumerable<IRGBDevice> CreateDevices(IDeviceUpdateTrigger updateTrigger)
{
foreach ((int pin, int stripLength) in Strips)
{
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;
string name = Name ?? $"Bitwizard WS2812 USB ({Port}) Pin {pin}";
int ledOffset = pin * MaxStripLength;
yield return new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset, stripLength);
}
}
#endregion

View File

@ -16,14 +16,6 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
{
#region Properties & Fields
/// <summary>
/// Gets the update queue performing updates for this device.
/// </summary>
public NodeMCUWS2812USBUpdateQueue UpdateQueue { get; }
/// <inheritdoc />
public override NodeMCUWS2812USBDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets the channel (as defined in the NodeMCU-sketch) this device is attached to.
/// </summary>
@ -39,18 +31,19 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
/// <param name="deviceInfo">The update trigger used by this queue.</param>
/// <param name="updateQueue">The update queue performing updates for this device.</param>
/// <param name="channel">The channel (as defined in the NodeMCU-sketch) this device is attached to.</param>
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
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
/// <inheritdoc />
public override void Dispose()
{
try { UpdateQueue.Dispose(); }
catch { /* at least we tried */ }
base.Dispose();
}
#endregion
}
}

View File

@ -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);
}
}

View File

@ -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.
/// </summary>
// ReSharper disable once InconsistentNaming
public class WS281XDeviceProvider : IRGBDeviceProvider
public class WS281XDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -23,12 +21,6 @@ namespace RGB.NET.Devices.WS281X
/// </summary>
public static WS281XDeviceProvider Instance => _instance ?? new WS281XDeviceProvider();
/// <inheritdoc />
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// Gets a list of all defined device-definitions.
/// </summary>
@ -36,11 +28,6 @@ namespace RGB.NET.Devices.WS281X
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
public List<IWS281XDeviceDefinition> DeviceDefinitions { get; } = new();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for corsair devices.
/// </summary>
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);
/// <inheritdoc />
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false)
{
IsInitialized = false;
protected override void InitializeSDK() { }
try
protected override IEnumerable<IRGBDevice> LoadDevices()
{
UpdateTrigger.Stop();
List<IRGBDevice> devices = new();
int i = 0;
foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions)
{
try
{
devices.AddRange(deviceDefinition.CreateDevices(UpdateTrigger));
IDeviceUpdateTrigger updateTrigger = GetUpdateTrigger(i++);
foreach (IRGBDevice device in deviceDefinition.CreateDevices(updateTrigger))
yield return device;
}
catch { if (throwExceptions) throw; }
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions)
throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
DeviceDefinitions.Clear();
}

View File

@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Wooting.Generic
/// <summary>
/// Represents a Wooting RGB-device.
/// </summary>
internal interface IWootingRGBDevice : IRGBDevice
{
void Initialize(IDeviceUpdateTrigger updateTrigger);
}
public interface IWootingRGBDevice : IRGBDevice
{ }
}

View File

@ -10,60 +10,15 @@ namespace RGB.NET.Devices.Wooting.Generic
public abstract class WootingRGBDevice<TDeviceInfo> : AbstractRGBDevice<TDeviceInfo>, IWootingRGBDevice
where TDeviceInfo : WootingRGBDeviceInfo
{
#region Properties & Fields
/// <inheritdoc />
/// <summary>
/// Gets information about the <see cref="T:RGB.NET.Devices.Wooting.WootingRGBDevice" />.
/// </summary>
public override TDeviceInfo DeviceInfo { get; }
/// <summary>
/// Gets or sets the update queue performing updates for this device.
/// </summary>
// ReSharper disable once MemberCanBePrivate.Global
protected UpdateQueue? UpdateQueue { get; set; }
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="WootingRGBDevice{TDeviceInfo}"/> class.
/// </summary>
/// <param name="info">The generic information provided by Wooting for the device.</param>
protected WootingRGBDevice(TDeviceInfo info)
{
this.DeviceInfo = info;
}
#endregion
#region Methods
/// <summary>
/// Initializes the device.
/// </summary>
public void Initialize(IDeviceUpdateTrigger updateTrigger)
{
InitializeLayout();
UpdateQueue = new WootingUpdateQueue(updateTrigger);
}
/// <summary>
/// Initializes the <see cref="Led"/> and <see cref="Size"/> of the device.
/// </summary>
protected abstract void InitializeLayout();
/// <inheritdoc />
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
}

View File

@ -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 <see cref="T:RGB.NET.Devices.Wooting.Keyboard.WootingKeyboardRGBDevice" /> class.
/// </summary>
/// <param name="info">The specific information provided by Wooting for the keyboard</param>
internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info)
: base(info)
{ }
internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
: base(info, updateTrigger)
{
InitializeLayout();
}
#endregion
#region Methods
/// <inheritdoc />
protected override void InitializeLayout()
private void InitializeLayout()
{
//TODO DarthAffe 13.02.2021: Check how the mapping can work without knowing the physical layout
Dictionary<LedId, (int row, int column)> 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];
/// <inheritdoc />
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue?.SetData(GetUpdateData(ledsToUpdate));
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}

View File

@ -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
/// <summary>
/// Represents a device provider responsible for Wooting devices.
/// </summary>
public class WootingDeviceProvider : IRGBDeviceProvider
public class WootingDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@ -37,20 +35,6 @@ namespace RGB.NET.Devices.Wooting
/// </summary>
public static List<string> PossibleX64NativePaths { get; } = new() { "x64/wooting-rgb-sdk64.dll" };
/// <inheritdoc />
/// <summary>
/// Indicates if the SDK is initialized and ready to use.
/// </summary>
public bool IsInitialized { get; private set; }
/// <inheritdoc />
public IEnumerable<IRGBDevice> Devices { get; private set; } = Enumerable.Empty<IRGBDevice>();
/// <summary>
/// The <see cref="DeviceUpdateTrigger"/> used to trigger the updates for cooler master devices.
/// </summary>
public DeviceUpdateTrigger UpdateTrigger { get; }
#endregion
#region Constructors
@ -61,68 +45,42 @@ namespace RGB.NET.Devices.Wooting
/// <exception cref="InvalidOperationException">Thrown if this constructor is called even if there is already an instance of this class.</exception>
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
/// <inheritdoc />
/// <exception cref="RGBDeviceException">Thrown if the SDK failed to initialize</exception>
public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
protected override void InitializeSDK()
{
IsInitialized = false;
try
{
UpdateTrigger.Stop();
_WootingSDK.Reload();
}
IList<IRGBDevice> devices = new List<IRGBDevice>();
protected override IEnumerable<IRGBDevice> LoadDevices()
{
if (_WootingSDK.KeyboardConnected())
{
_WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!;
IWootingRGBDevice device = nativeDeviceInfo.Model switch
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);
if (device == null)
Throw(new RGBDeviceException("No supported Wooting keyboard connected"));
else
yield return device;
}
UpdateTrigger.Start();
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
IsInitialized = true;
}
catch
{
if (throwExceptions) throw;
return false;
}
return true;
}
/// <inheritdoc />
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<IRGBDevice>();
base.Dispose();
try { _WootingSDK.Close(); }
catch { /* Unlucky.. */ }