mirror of
https://github.com/DarthAffe/RGB.NET.git
synced 2025-12-12 17:48:31 +00:00
Changed all existing device-providers to use update-queues to decouple the physical update from the internal update-loop (first draft, code-documention is missing)
This commit is contained in:
parent
3965bfb9a0
commit
66d03cdf4f
12
RGB.NET.Core/Devices/Update/IUpdateTrigger.cs
Normal file
12
RGB.NET.Core/Devices/Update/IUpdateTrigger.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace RGB.NET.Core
|
||||
{
|
||||
public interface IUpdateTrigger
|
||||
{
|
||||
event EventHandler Starting;
|
||||
event EventHandler Update;
|
||||
|
||||
void TriggerHasData();
|
||||
}
|
||||
}
|
||||
92
RGB.NET.Core/Devices/Update/UpdateQueue.cs
Normal file
92
RGB.NET.Core/Devices/Update/UpdateQueue.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace RGB.NET.Core
|
||||
{
|
||||
public abstract class UpdateQueue<TIdentifier, TData>
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private readonly object _dataLock = new object();
|
||||
private readonly IUpdateTrigger _updateTrigger;
|
||||
private Dictionary<TIdentifier, TData> _currentDataSet;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public UpdateQueue(IUpdateTrigger updateTrigger)
|
||||
{
|
||||
this._updateTrigger = updateTrigger;
|
||||
|
||||
_updateTrigger.Starting += (sender, args) => OnStartup();
|
||||
_updateTrigger.Update += OnUpdate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected virtual void OnUpdate(object sender, EventArgs e)
|
||||
{
|
||||
Dictionary<TIdentifier, TData> dataSet;
|
||||
lock (_dataLock)
|
||||
{
|
||||
dataSet = _currentDataSet;
|
||||
_currentDataSet = null;
|
||||
}
|
||||
|
||||
if ((dataSet != null) && (dataSet.Count != 0))
|
||||
Update(dataSet);
|
||||
}
|
||||
|
||||
protected virtual void OnStartup() { }
|
||||
|
||||
protected abstract void Update(Dictionary<TIdentifier, TData> dataSet);
|
||||
|
||||
public virtual void SetData(Dictionary<TIdentifier, TData> dataSet)
|
||||
{
|
||||
if ((dataSet == null) || (dataSet.Count == 0)) return;
|
||||
|
||||
lock (_dataLock)
|
||||
{
|
||||
if (_currentDataSet == null)
|
||||
_currentDataSet = dataSet;
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<TIdentifier, TData> command in dataSet)
|
||||
_currentDataSet[command.Key] = command.Value;
|
||||
}
|
||||
}
|
||||
|
||||
_updateTrigger.TriggerHasData();
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
lock (_dataLock)
|
||||
_currentDataSet = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public abstract class UpdateQueue : UpdateQueue<object, Color>
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
/// <inheritdoc />
|
||||
protected UpdateQueue(IUpdateTrigger updateTrigger)
|
||||
: base(updateTrigger)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void SetData(IEnumerable<Led> leds) => SetData(leds?.ToDictionary(x => x.CustomData ?? x.Id, x => x.Color));
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
128
RGB.NET.Core/Devices/Update/UpdateTrigger.cs
Normal file
128
RGB.NET.Core/Devices/Update/UpdateTrigger.cs
Normal file
@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RGB.NET.Core
|
||||
{
|
||||
public class UpdateTrigger : IUpdateTrigger
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
public int Timeout { get; set; } = 100;
|
||||
|
||||
public double UpdateFrequency { get; private set; }
|
||||
|
||||
private double _maxUpdateRate;
|
||||
public double MaxUpdateRate
|
||||
{
|
||||
get => _maxUpdateRate;
|
||||
set
|
||||
{
|
||||
_maxUpdateRate = value;
|
||||
UpdateUpdateFrequency();
|
||||
}
|
||||
}
|
||||
|
||||
private double _updateRateHardLimit;
|
||||
public double UpdateRateHardLimit
|
||||
{
|
||||
get => _updateRateHardLimit;
|
||||
protected set
|
||||
{
|
||||
_updateRateHardLimit = value;
|
||||
UpdateUpdateFrequency();
|
||||
}
|
||||
}
|
||||
|
||||
private AutoResetEvent _hasDataEvent = new AutoResetEvent(false);
|
||||
|
||||
private bool _isRunning;
|
||||
private Task _updateTask;
|
||||
private CancellationTokenSource _updateTokenSource;
|
||||
private CancellationToken _updateToken;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler Starting;
|
||||
/// <inheritdoc />
|
||||
public event EventHandler Update;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public UpdateTrigger()
|
||||
{ }
|
||||
|
||||
public UpdateTrigger(double updateRateHardLimit)
|
||||
{
|
||||
this._updateRateHardLimit = updateRateHardLimit;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (_isRunning) return;
|
||||
|
||||
_isRunning = true;
|
||||
|
||||
_updateTokenSource?.Dispose();
|
||||
_updateTokenSource = new CancellationTokenSource();
|
||||
_updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default);
|
||||
|
||||
}
|
||||
|
||||
public async void Stop()
|
||||
{
|
||||
if (!_isRunning) return;
|
||||
|
||||
_isRunning = false;
|
||||
|
||||
_updateTokenSource.Cancel();
|
||||
await _updateTask;
|
||||
_updateTask.Dispose();
|
||||
_updateTask = null;
|
||||
}
|
||||
|
||||
private void UpdateLoop()
|
||||
{
|
||||
Starting?.Invoke(this, null);
|
||||
while (!_updateToken.IsCancellationRequested)
|
||||
{
|
||||
if (_hasDataEvent.WaitOne(Timeout))
|
||||
{
|
||||
long preUpdateTicks = Stopwatch.GetTimestamp();
|
||||
|
||||
Update?.Invoke(this, null);
|
||||
|
||||
if (UpdateFrequency > 0)
|
||||
{
|
||||
double lastUpdateTime = ((Stopwatch.GetTimestamp() - preUpdateTicks) / 10000.0);
|
||||
int sleep = (int)((UpdateFrequency * 1000.0) - lastUpdateTime);
|
||||
if (sleep > 0)
|
||||
Thread.Sleep(sleep);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void TriggerHasData() => _hasDataEvent.Set();
|
||||
|
||||
private void UpdateUpdateFrequency()
|
||||
{
|
||||
UpdateFrequency = MaxUpdateRate;
|
||||
if ((UpdateFrequency <= 0) || ((UpdateRateHardLimit > 0) && (UpdateRateHardLimit < UpdateFrequency)))
|
||||
UpdateFrequency = UpdateRateHardLimit;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -64,6 +64,9 @@
|
||||
<Compile Include="Devices\Layout\LedImage.cs" />
|
||||
<Compile Include="Devices\Layout\LedImageLayout.cs" />
|
||||
<Compile Include="Devices\RGBDeviceLighting.cs" />
|
||||
<Compile Include="Devices\Update\IUpdateTrigger.cs" />
|
||||
<Compile Include="Devices\Update\UpdateQueue.cs" />
|
||||
<Compile Include="Devices\Update\UpdateTrigger.cs" />
|
||||
<Compile Include="Helper\ConversionHelper.cs" />
|
||||
<Compile Include="Helper\CultureHelper.cs" />
|
||||
<Compile Include="Helper\PathHelper.cs" />
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=colorcorrection/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=decorators/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=devices/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=devices_005Cupdate/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=effects/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@ -63,6 +63,8 @@ namespace RGB.NET.Devices.Asus
|
||||
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
|
||||
public Func<CultureInfo> GetCulture { get; set; } = CultureHelper.GetCurrentCulture;
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -75,6 +77,8 @@ 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 UpdateTrigger();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -88,6 +92,8 @@ namespace RGB.NET.Devices.Asus
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger?.Stop();
|
||||
|
||||
_AsusSDK.Reload();
|
||||
|
||||
IList<IRGBDevice> devices = new List<IRGBDevice>();
|
||||
@ -112,7 +118,7 @@ namespace RGB.NET.Devices.Asus
|
||||
IntPtr handle = Marshal.ReadIntPtr(mainboardHandles, i);
|
||||
_AsusSDK.SetMbMode(handle, 1);
|
||||
AsusMainboardRGBDevice device = new AsusMainboardRGBDevice(new AsusMainboardRGBDeviceInfo(RGBDeviceType.Mainboard, handle));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -143,7 +149,7 @@ namespace RGB.NET.Devices.Asus
|
||||
IntPtr handle = Marshal.ReadIntPtr(grapicsCardHandles, i);
|
||||
_AsusSDK.SetGPUMode(handle, 1);
|
||||
AsusGraphicsCardRGBDevice device = new AsusGraphicsCardRGBDevice(new AsusGraphicsCardRGBDeviceInfo(RGBDeviceType.GraphicsCard, handle));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -172,7 +178,7 @@ namespace RGB.NET.Devices.Asus
|
||||
// IntPtr handle = Marshal.ReadIntPtr(dramHandles, i);
|
||||
// _AsusSDK.SetDramMode(handle, 1);
|
||||
// AsusDramRGBDevice device = new AsusDramRGBDevice(new AsusDramRGBDeviceInfo(RGBDeviceType.DRAM, handle));
|
||||
// device.Initialize();
|
||||
// device.Initialize(UpdateTrigger);
|
||||
// devices.Add(device);
|
||||
// }
|
||||
//catch { if (throwExceptions) throw; }
|
||||
@ -193,7 +199,7 @@ namespace RGB.NET.Devices.Asus
|
||||
{
|
||||
_AsusSDK.SetClaymoreKeyboardMode(keyboardHandle, 1);
|
||||
AsusKeyboardRGBDevice device = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(RGBDeviceType.Keyboard, keyboardHandle, GetCulture()));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
}
|
||||
@ -211,13 +217,15 @@ namespace RGB.NET.Devices.Asus
|
||||
{
|
||||
_AsusSDK.SetRogMouseMode(mouseHandle, 1);
|
||||
AsusMouseRGBDevice device = new AsusMouseRGBDevice(new AsusMouseRGBDeviceInfo(RGBDeviceType.Mouse, mouseHandle));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
|
||||
#endregion
|
||||
|
||||
UpdateTrigger?.Start();
|
||||
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Asus.Generic;
|
||||
|
||||
namespace RGB.NET.Devices.Asus
|
||||
{
|
||||
@ -16,17 +17,14 @@ namespace RGB.NET.Devices.Asus
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the internal color-data cache.
|
||||
/// </summary>
|
||||
protected byte[] ColorData { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets information about the <see cref="T:RGB.NET.Devices.Asus.AsusRGBDevice" />.
|
||||
/// </summary>
|
||||
public override TDeviceInfo DeviceInfo { get; }
|
||||
|
||||
protected AsusUpdateQueue UpdateQueue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -47,7 +45,7 @@ namespace RGB.NET.Devices.Asus
|
||||
/// <summary>
|
||||
/// Initializes the device.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
public void Initialize(IUpdateTrigger updateTrigger)
|
||||
{
|
||||
InitializeLayout();
|
||||
|
||||
@ -57,7 +55,8 @@ namespace RGB.NET.Devices.Asus
|
||||
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
|
||||
}
|
||||
|
||||
ColorData = new byte[LedMapping.Count * 3];
|
||||
UpdateQueue = new AsusUpdateQueue(updateTrigger);
|
||||
UpdateQueue.Initialize(GetUpdateColorAction(), DeviceInfo.Handle, LedMapping.Count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -66,28 +65,13 @@ namespace RGB.NET.Devices.Asus
|
||||
protected abstract void InitializeLayout();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
|
||||
|
||||
if (leds.Count > 0)
|
||||
{
|
||||
foreach (Led led in leds)
|
||||
{
|
||||
int index = ((int)led.CustomData) * 3;
|
||||
ColorData[index] = led.Color.R;
|
||||
ColorData[index + 1] = led.Color.B;
|
||||
ColorData[index + 2] = led.Color.G;
|
||||
}
|
||||
|
||||
ApplyColorData();
|
||||
}
|
||||
}
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
|
||||
|
||||
/// <summary>
|
||||
/// Sends the color-data-cache to the device.
|
||||
/// Gets a action to update the physical device.
|
||||
/// </summary>
|
||||
protected abstract void ApplyColorData();
|
||||
/// <returns></returns>
|
||||
protected abstract Action<IntPtr, byte[]> GetUpdateColorAction();
|
||||
|
||||
/// <inheritdoc cref="IDisposable.Dispose" />
|
||||
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}.Dispose" />
|
||||
@ -96,8 +80,6 @@ namespace RGB.NET.Devices.Asus
|
||||
if ((DeviceInfo is AsusRGBDeviceInfo deviceInfo) && (deviceInfo.Handle != IntPtr.Zero))
|
||||
Marshal.FreeHGlobal(deviceInfo.Handle);
|
||||
|
||||
ColorData = null;
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
|
||||
54
RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
Normal file
54
RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace RGB.NET.Devices.Asus.Generic
|
||||
{
|
||||
public class AsusUpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the internal color-data cache.
|
||||
/// </summary>
|
||||
protected byte[] ColorData { get; private set; }
|
||||
|
||||
private Action<IntPtr, byte[]> _updateAction;
|
||||
private IntPtr _handle;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public AsusUpdateQueue(IUpdateTrigger updateTrigger)
|
||||
: base(updateTrigger)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
public void Initialize(Action<IntPtr, byte[]> updateAction, IntPtr handle, int ledCount)
|
||||
{
|
||||
_updateAction = updateAction;
|
||||
_handle = handle;
|
||||
|
||||
ColorData = new byte[ledCount * 3];
|
||||
}
|
||||
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
{
|
||||
int index = ((int)data.Key) * 3;
|
||||
ColorData[index] = data.Value.R;
|
||||
ColorData[index + 1] = data.Value.B;
|
||||
ColorData[index + 2] = data.Value.G;
|
||||
}
|
||||
|
||||
_updateAction(_handle, ColorData);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,6 @@ namespace RGB.NET.Devices.Asus
|
||||
/// </summary>
|
||||
internal interface IAsusRGBDevice : IRGBDevice
|
||||
{
|
||||
void Initialize();
|
||||
void Initialize(IUpdateTrigger updateTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using RGB.NET.Core;
|
||||
using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Asus.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Asus
|
||||
@ -40,7 +41,7 @@ namespace RGB.NET.Devices.Asus
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ApplyColorData() => _AsusSDK.SetGPUColor(DeviceInfo.Handle, ColorData);
|
||||
protected override Action<IntPtr, byte[]> GetUpdateColorAction() => _AsusSDK.SetGPUColor;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using RGB.NET.Core;
|
||||
using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Asus.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Asus
|
||||
@ -38,9 +39,9 @@ namespace RGB.NET.Devices.Asus
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape;
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ApplyColorData() => _AsusSDK.SetClaymoreKeyboardColor(DeviceInfo.Handle, ColorData);
|
||||
protected override Action<IntPtr, byte[]> GetUpdateColorAction() => _AsusSDK.SetClaymoreKeyboardColor;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using RGB.NET.Core;
|
||||
using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Asus.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Asus
|
||||
@ -48,7 +49,7 @@ namespace RGB.NET.Devices.Asus
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ApplyColorData() => _AsusSDK.SetMbColor(DeviceInfo.Handle, ColorData);
|
||||
protected override Action<IntPtr, byte[]> GetUpdateColorAction() => _AsusSDK.SetMbColor;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using RGB.NET.Core;
|
||||
using System;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Asus.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Asus
|
||||
@ -39,7 +40,7 @@ namespace RGB.NET.Devices.Asus
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void ApplyColorData() => _AsusSDK.SetRogMouseColor(DeviceInfo.Handle, ColorData);
|
||||
protected override Action<IntPtr, byte[]> GetUpdateColorAction() => _AsusSDK.SetRogMouseColor;
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -54,6 +54,7 @@
|
||||
<Compile Include="Enum\AsusPhysicalKeyboardLayout.cs" />
|
||||
<Compile Include="Generic\AsusRGBDevice.cs" />
|
||||
<Compile Include="Generic\AsusRGBDeviceInfo.cs" />
|
||||
<Compile Include="Generic\AsusUpdateQueue.cs" />
|
||||
<Compile Include="Generic\IAsusRGBDevice.cs" />
|
||||
<Compile Include="GraphicsCard\AsusGraphicsCardRGBDevice.cs" />
|
||||
<Compile Include="GraphicsCard\AsusGraphicsCardRGBDeviceInfo.cs" />
|
||||
|
||||
@ -63,6 +63,8 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
// ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
|
||||
public Func<CultureInfo> GetCulture { get; set; } = CultureHelper.GetCurrentCulture;
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -75,6 +77,8 @@ 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 UpdateTrigger();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -88,6 +92,8 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger?.Stop();
|
||||
|
||||
_CoolerMasterSDK.Reload();
|
||||
if (_CoolerMasterSDK.GetSDKVersion() <= 0) return false;
|
||||
|
||||
@ -120,13 +126,15 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
|
||||
_CoolerMasterSDK.EnableLedControl(true);
|
||||
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
}
|
||||
|
||||
UpdateTrigger?.Start();
|
||||
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
@ -15,12 +15,15 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
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; }
|
||||
|
||||
protected CoolerMasterUpdateQueue UpdateQueue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -42,7 +45,7 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
/// <summary>
|
||||
/// Initializes the device.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
public void Initialize(IUpdateTrigger updateTrigger)
|
||||
{
|
||||
InitializeLayout();
|
||||
|
||||
@ -51,6 +54,8 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle));
|
||||
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
|
||||
}
|
||||
|
||||
UpdateQueue = new CoolerMasterUpdateQueue(updateTrigger, DeviceInfo.DeviceIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -59,23 +64,7 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
protected abstract void InitializeLayout();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
|
||||
|
||||
if (leds.Count > 0)
|
||||
{
|
||||
_CoolerMasterSDK.SetControlDevice(DeviceInfo.DeviceIndex);
|
||||
|
||||
foreach (Led led in leds)
|
||||
{
|
||||
(int row, int column) = ((int, int))led.CustomData;
|
||||
_CoolerMasterSDK.SetLedColor(row, column, led.Color.R, led.Color.G, led.Color.B);
|
||||
}
|
||||
|
||||
_CoolerMasterSDK.RefreshLed(false);
|
||||
}
|
||||
}
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
|
||||
|
||||
/// <inheritdoc cref="IDisposable.Dispose" />
|
||||
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}.Dispose" />
|
||||
|
||||
@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.CoolerMaster.Native;
|
||||
|
||||
namespace RGB.NET.Devices.CoolerMaster
|
||||
{
|
||||
public class CoolerMasterUpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private CoolerMasterDevicesIndexes _deviceIndex;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public CoolerMasterUpdateQueue(IUpdateTrigger updateTrigger, CoolerMasterDevicesIndexes deviceIndex)
|
||||
: base(updateTrigger)
|
||||
{
|
||||
this._deviceIndex = deviceIndex;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_CoolerMasterSDK.SetControlDevice(_deviceIndex);
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
{
|
||||
(int row, int column) = ((int, int))data.Key;
|
||||
_CoolerMasterSDK.SetLedColor(row, column, data.Value.R, data.Value.G, data.Value.B);
|
||||
}
|
||||
|
||||
_CoolerMasterSDK.RefreshLed(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,6 @@ namespace RGB.NET.Devices.CoolerMaster
|
||||
/// </summary>
|
||||
internal interface ICoolerMasterRGBDevice : IRGBDevice
|
||||
{
|
||||
void Initialize();
|
||||
void Initialize(IUpdateTrigger updateTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@
|
||||
<Compile Include="Enum\CoolerMasterLogicalKeyboardLayout.cs" />
|
||||
<Compile Include="Generic\CoolerMasterRGBDevice.cs" />
|
||||
<Compile Include="Generic\CoolerMasterRGBDeviceInfo.cs" />
|
||||
<Compile Include="Generic\CoolerMasterUpdateQueue.cs" />
|
||||
<Compile Include="Generic\ICoolerMasterRGBDevice.cs" />
|
||||
<Compile Include="Helper\EnumExtension.cs" />
|
||||
<Compile Include="Keyboard\CoolerMasterKeyboardRGBDevice.cs" />
|
||||
|
||||
@ -66,6 +66,9 @@ namespace RGB.NET.Devices.Corsair
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IRGBDevice> Devices { get; private set; }
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
private CorsairUpdateQueue _updateQueue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -78,6 +81,9 @@ 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 UpdateTrigger();
|
||||
_updateQueue = new CorsairUpdateQueue(UpdateTrigger);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -93,6 +99,8 @@ namespace RGB.NET.Devices.Corsair
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger?.Stop();
|
||||
|
||||
_CUESDK.Reload();
|
||||
|
||||
ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake());
|
||||
@ -130,7 +138,7 @@ namespace RGB.NET.Devices.Corsair
|
||||
ICorsairRGBDevice device = GetRGBDevice(info, i, nativeDeviceInfo);
|
||||
if ((device == null) || !loadFilter.HasFlag(device.DeviceInfo.DeviceType)) continue;
|
||||
|
||||
device.Initialize();
|
||||
device.Initialize(_updateQueue);
|
||||
AddSpecialParts(device);
|
||||
|
||||
error = LastError;
|
||||
@ -142,6 +150,8 @@ namespace RGB.NET.Devices.Corsair
|
||||
catch { if (throwExceptions) throw; }
|
||||
}
|
||||
|
||||
UpdateTrigger?.Start();
|
||||
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
@ -29,6 +29,8 @@ namespace RGB.NET.Devices.Corsair
|
||||
// ReSharper disable once MemberCanBePrivate.Global
|
||||
protected Dictionary<CorsairLedId, Led> InternalLedMapping { get; } = new Dictionary<CorsairLedId, Led>();
|
||||
|
||||
protected CorsairUpdateQueue UpdateQueue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Indexer
|
||||
@ -61,8 +63,10 @@ namespace RGB.NET.Devices.Corsair
|
||||
/// <summary>
|
||||
/// Initializes the device.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
public void Initialize(CorsairUpdateQueue updateQueue)
|
||||
{
|
||||
UpdateQueue = updateQueue;
|
||||
|
||||
InitializeLayout();
|
||||
|
||||
foreach (Led led in LedMapping.Values)
|
||||
@ -86,31 +90,7 @@ namespace RGB.NET.Devices.Corsair
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid))).ToList();
|
||||
|
||||
if (leds.Count > 0) // CUE seems to crash if 'CorsairSetLedsColors' is called with a zero length array
|
||||
{
|
||||
int structSize = Marshal.SizeOf(typeof(_CorsairLedColor));
|
||||
IntPtr ptr = Marshal.AllocHGlobal(structSize * leds.Count);
|
||||
IntPtr addPtr = new IntPtr(ptr.ToInt64());
|
||||
foreach (Led led in leds)
|
||||
{
|
||||
_CorsairLedColor color = new _CorsairLedColor
|
||||
{
|
||||
ledId = (int)led.CustomData,
|
||||
r = led.Color.R,
|
||||
g = led.Color.G,
|
||||
b = led.Color.B
|
||||
};
|
||||
|
||||
Marshal.StructureToPtr(color, addPtr, false);
|
||||
addPtr = new IntPtr(addPtr.ToInt64() + structSize);
|
||||
}
|
||||
_CUESDK.CorsairSetLedsColors(leds.Count, ptr);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
=> UpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid))));
|
||||
|
||||
/// <inheritdoc cref="IRGBDevice.SyncBack" />
|
||||
public override void SyncBack()
|
||||
|
||||
46
RGB.NET.Devices.Corsair/Generic/CorsairUpdateQueue.cs
Normal file
46
RGB.NET.Devices.Corsair/Generic/CorsairUpdateQueue.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Corsair.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Corsair
|
||||
{
|
||||
public class CorsairUpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public CorsairUpdateQueue(IUpdateTrigger updateTrigger)
|
||||
: base(updateTrigger)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
int structSize = Marshal.SizeOf(typeof(_CorsairLedColor));
|
||||
IntPtr ptr = Marshal.AllocHGlobal(structSize * dataSet.Count);
|
||||
IntPtr addPtr = new IntPtr(ptr.ToInt64());
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
{
|
||||
_CorsairLedColor color = new _CorsairLedColor
|
||||
{
|
||||
ledId = (int)data.Key,
|
||||
r = data.Value.R,
|
||||
g = data.Value.G,
|
||||
b = data.Value.B
|
||||
};
|
||||
|
||||
Marshal.StructureToPtr(color, addPtr, false);
|
||||
addPtr = new IntPtr(addPtr.ToInt64() + structSize);
|
||||
}
|
||||
_CUESDK.CorsairSetLedsColors(dataSet.Count, ptr);
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,6 @@ namespace RGB.NET.Devices.Corsair
|
||||
/// </summary>
|
||||
internal interface ICorsairRGBDevice : IRGBDevice
|
||||
{
|
||||
void Initialize();
|
||||
void Initialize(CorsairUpdateQueue updateQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@
|
||||
<Compile Include="Generic\CorsairProtocolDetails.cs" />
|
||||
<Compile Include="Generic\CorsairRGBDeviceInfo.cs" />
|
||||
<Compile Include="Generic\CorsairRGBDevice.cs" />
|
||||
<Compile Include="Generic\CorsairUpdateQueue.cs" />
|
||||
<Compile Include="Generic\ICorsairRGBDevice.cs" />
|
||||
<Compile Include="HeadsetStand\CorsairHeadsetStandRGBDevice.cs" />
|
||||
<Compile Include="HeadsetStand\CorsairHeadsetStandRGBDeviceInfo.cs" />
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=generic_005Cupdate/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=headsetstand/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=helper/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=libs/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
@ -37,6 +37,8 @@ namespace RGB.NET.Devices.DMX
|
||||
/// </summary>
|
||||
public List<IDMXDeviceDefinition> DeviceDefinitions { get; } = new List<IDMXDeviceDefinition>();
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -49,6 +51,8 @@ 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 UpdateTrigger();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -68,6 +72,8 @@ namespace RGB.NET.Devices.DMX
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger.Stop();
|
||||
|
||||
IList<IRGBDevice> devices = new List<IRGBDevice>();
|
||||
|
||||
foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions)
|
||||
@ -79,7 +85,7 @@ namespace RGB.NET.Devices.DMX
|
||||
if (e131DMXDeviceDefinition.Leds.Count > 0)
|
||||
{
|
||||
E131Device device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds);
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
}
|
||||
@ -87,6 +93,8 @@ namespace RGB.NET.Devices.DMX
|
||||
catch { if (throwExceptions) throw; }
|
||||
}
|
||||
|
||||
UpdateTrigger.Start();
|
||||
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace RGB.NET.Devices.DMX.E131
|
||||
@ -13,27 +12,13 @@ namespace RGB.NET.Devices.DMX.E131
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// Gets the UDP-Connection used to send data.
|
||||
/// </summary>
|
||||
private UdpClient _socket;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the byte-representation of a E1.31 packet as described in http://tsp.esta.org/tsp/documents/docs/E1-31-2016.pdf.
|
||||
/// CID, SequenceNumber, Universe and PropertyValues needs to be updated before use!
|
||||
/// </summary>
|
||||
private byte[] _dataPacket = { 0x00, 0x10, 0x00, 0x00, 0x41, 0x53, 0x43, 0x2D, 0x45, 0x31, 0x2E, 0x31, 0x37, 0x00, 0x00, 0x00, 0x72, 0x6E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x72, 0x0B, 0x02, 0xA1, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Sequence number used to detect the order in which packages where sent.
|
||||
/// </summary>
|
||||
private byte _sequenceNumber = 0;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override E131DeviceInfo DeviceInfo { get; }
|
||||
|
||||
private readonly Dictionary<LedId, List<(int channel, Func<Color, byte> getValueFunc)>> _ledMappings;
|
||||
|
||||
private E131UpdateQueue _updateQueue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -49,18 +34,12 @@ namespace RGB.NET.Devices.DMX.E131
|
||||
|
||||
#region Methods
|
||||
|
||||
internal void Initialize()
|
||||
internal void Initialize(IUpdateTrigger updateTrigger)
|
||||
{
|
||||
int count = 0;
|
||||
foreach (LedId id in _ledMappings.Keys)
|
||||
InitializeLed(id, new Rectangle((count++) * 10, 0, 10, 10));
|
||||
|
||||
_socket = new UdpClient();
|
||||
_socket.Connect(DeviceInfo.Hostname, DeviceInfo.Port);
|
||||
|
||||
_dataPacket.SetCID(DeviceInfo.CID);
|
||||
_dataPacket.SetUniverse(DeviceInfo.Universe);
|
||||
|
||||
//TODO DarthAffe 18.02.2018: Allow to load a layout.
|
||||
|
||||
if (Size == Size.Invalid)
|
||||
@ -68,44 +47,17 @@ namespace RGB.NET.Devices.DMX.E131
|
||||
Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle));
|
||||
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
|
||||
}
|
||||
|
||||
_updateQueue = new E131UpdateQueue(updateTrigger, DeviceInfo.Hostname, DeviceInfo.Port);
|
||||
_updateQueue.DataPacket.SetCID(DeviceInfo.CID);
|
||||
_updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override object CreateLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
|
||||
if (leds.Count > 0)
|
||||
{
|
||||
_dataPacket.SetSequenceNumber(GetNextSequenceNumber());
|
||||
|
||||
foreach (Led led in leds)
|
||||
{
|
||||
LedChannelMapping mapping = (LedChannelMapping)led.CustomData;
|
||||
foreach ((int channel, Func<Color, byte> getValue) in mapping)
|
||||
_dataPacket.SetChannel(channel, getValue(led.Color));
|
||||
}
|
||||
|
||||
_socket.Send(_dataPacket, _dataPacket.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increments the sequence number and wraps it if neded.
|
||||
/// </summary>
|
||||
/// <returns>The next usable sequence number.</returns>
|
||||
private byte GetNextSequenceNumber()
|
||||
{
|
||||
if (_sequenceNumber == byte.MaxValue)
|
||||
{
|
||||
_sequenceNumber = byte.MinValue;
|
||||
return byte.MaxValue;
|
||||
}
|
||||
|
||||
return _sequenceNumber++;
|
||||
}
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => _updateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
74
RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs
Normal file
74
RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs
Normal file
@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Sockets;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace RGB.NET.Devices.DMX.E131
|
||||
{
|
||||
public class E131UpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
/// <summary>
|
||||
/// The UDP-Connection used to send data.
|
||||
/// </summary>
|
||||
private UdpClient _socket;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the byte-representation of a E1.31 packet as described in http://tsp.esta.org/tsp/documents/docs/E1-31-2016.pdf.
|
||||
/// CID, SequenceNumber, Universe and PropertyValues needs to be updated before use!
|
||||
/// </summary>
|
||||
internal byte[] DataPacket { get; } = { 0x00, 0x10, 0x00, 0x00, 0x41, 0x53, 0x43, 0x2D, 0x45, 0x31, 0x2E, 0x31, 0x37, 0x00, 0x00, 0x00, 0x72, 0x6E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x72, 0x0B, 0x02, 0xA1, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
/// <summary>
|
||||
/// The sequence-number used to detect the order in which packages where sent.
|
||||
/// </summary>
|
||||
private byte _sequenceNumber = 0;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public E131UpdateQueue(IUpdateTrigger updateTrigger, string hostname, int port)
|
||||
: base(updateTrigger)
|
||||
{
|
||||
_socket = new UdpClient();
|
||||
_socket.Connect(hostname, port);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
DataPacket.SetSequenceNumber(GetNextSequenceNumber());
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
{
|
||||
LedChannelMapping mapping = (LedChannelMapping)data.Key;
|
||||
foreach ((int channel, Func<Color, byte> getValue) in mapping)
|
||||
DataPacket.SetChannel(channel, getValue(data.Value));
|
||||
}
|
||||
|
||||
_socket.Send(DataPacket, DataPacket.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increments the sequence number and wraps it if neded.
|
||||
/// </summary>
|
||||
/// <returns>The next usable sequence number.</returns>
|
||||
private byte GetNextSequenceNumber()
|
||||
{
|
||||
if (_sequenceNumber == byte.MaxValue)
|
||||
{
|
||||
_sequenceNumber = byte.MinValue;
|
||||
return byte.MaxValue;
|
||||
}
|
||||
|
||||
return _sequenceNumber++;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -51,6 +51,7 @@
|
||||
<Compile Include="E131\E131Device.cs" />
|
||||
<Compile Include="E131\E131DeviceInfo.cs" />
|
||||
<Compile Include="E131\E131DMXDeviceDefinition.cs" />
|
||||
<Compile Include="E131\E131UpdateQueue.cs" />
|
||||
<Compile Include="Generic\IDMXDeviceDefinition.cs" />
|
||||
<Compile Include="Generic\LedChannelMapping.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@ -7,6 +7,6 @@ namespace RGB.NET.Devices.Logitech
|
||||
/// </summary>
|
||||
internal interface ILogitechRGBDevice : IRGBDevice
|
||||
{
|
||||
void Initialize();
|
||||
void Initialize(UpdateQueue updateQueue);
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@ namespace RGB.NET.Devices.Logitech
|
||||
/// </summary>
|
||||
public override TDeviceInfo DeviceInfo { get; }
|
||||
|
||||
protected UpdateQueue UpdateQueue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -39,7 +41,7 @@ namespace RGB.NET.Devices.Logitech
|
||||
/// <summary>
|
||||
/// Initializes the device.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
public void Initialize(UpdateQueue updateQueue)
|
||||
{
|
||||
InitializeLayout();
|
||||
|
||||
@ -48,6 +50,8 @@ namespace RGB.NET.Devices.Logitech
|
||||
Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle));
|
||||
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
|
||||
}
|
||||
|
||||
UpdateQueue = updateQueue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -56,6 +56,10 @@ namespace RGB.NET.Devices.Logitech
|
||||
/// </summary>
|
||||
public Func<CultureInfo> GetCulture { get; set; } = CultureHelper.GetCurrentCulture;
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
private LogitechPerDeviceUpdateQueue _perDeviceUpdateQueue;
|
||||
private LogitechPerKeyUpdateQueue _perKeyUpdateQueue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -68,6 +72,10 @@ 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 UpdateTrigger();
|
||||
_perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(UpdateTrigger);
|
||||
_perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(UpdateTrigger);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -88,6 +96,8 @@ namespace RGB.NET.Devices.Logitech
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger?.Stop();
|
||||
|
||||
_LogitechGSDK.Reload();
|
||||
if (!_LogitechGSDK.LogiLedInit()) return false;
|
||||
|
||||
@ -104,7 +114,7 @@ namespace RGB.NET.Devices.Logitech
|
||||
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, imageLayout, layoutPath));
|
||||
device.Initialize();
|
||||
device.Initialize(_perKeyUpdateQueue);
|
||||
devices.Add(device);
|
||||
}
|
||||
}
|
||||
@ -119,13 +129,15 @@ namespace RGB.NET.Devices.Logitech
|
||||
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, imageLayout, layoutPath));
|
||||
device.Initialize();
|
||||
device.Initialize(_perDeviceUpdateQueue);
|
||||
devices.Add(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
|
||||
UpdateTrigger?.Start();
|
||||
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Logitech.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Logitech
|
||||
{
|
||||
@ -37,19 +35,10 @@ namespace RGB.NET.Devices.Logitech
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override object CreateLedCustomData(LedId ledId) => LogitechLedId.DEVICE;
|
||||
protected override object CreateLedCustomData(LedId ledId) => (ledId, LogitechLedId.DEVICE);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
Led led = ledsToUpdate.FirstOrDefault(x => x.Color.A > 0);
|
||||
if (led == null) return;
|
||||
|
||||
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB);
|
||||
_LogitechGSDK.LogiLedSetLighting((int)Math.Round(led.Color.RPercent * 100),
|
||||
(int)Math.Round(led.Color.GPercent * 100),
|
||||
(int)Math.Round(led.Color.BPercent * 100));
|
||||
}
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0).Take(1));
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Logitech.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Logitech
|
||||
{
|
||||
public class LogitechPerDeviceUpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public LogitechPerDeviceUpdateQueue(IUpdateTrigger updateTrigger)
|
||||
: base(updateTrigger)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
Color color = dataSet.Values.First();
|
||||
|
||||
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB);
|
||||
_LogitechGSDK.LogiLedSetLighting((int)Math.Round(color.RPercent * 100),
|
||||
(int)Math.Round(color.GPercent * 100),
|
||||
(int)Math.Round(color.BPercent * 100));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Logitech.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Logitech
|
||||
{
|
||||
@ -28,37 +26,10 @@ namespace RGB.NET.Devices.Logitech
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override object CreateLedCustomData(LedId ledId) => PerKeyIdMapping.DEFAULT.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : LogitechLedId.Invalid;
|
||||
protected override object CreateLedCustomData(LedId ledId) => (ledId, PerKeyIdMapping.DEFAULT.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : LogitechLedId.Invalid);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
|
||||
if (leds.Count <= 0) return;
|
||||
|
||||
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB);
|
||||
|
||||
byte[] bitmap = null;
|
||||
foreach (Led led in leds)
|
||||
{
|
||||
// DarthAffe 26.03.2017: This is only needed since update by name doesn't work as expected for all keys ...
|
||||
if (BitmapMapping.BitmapOffset.TryGetValue(led.Id, out int bitmapOffset))
|
||||
{
|
||||
if (bitmap == null)
|
||||
bitmap = BitmapMapping.CreateBitmap();
|
||||
|
||||
BitmapMapping.SetColor(ref bitmap, bitmapOffset, led.Color);
|
||||
}
|
||||
else
|
||||
_LogitechGSDK.LogiLedSetLightingForKeyWithKeyName((int)led.CustomData,
|
||||
(int)Math.Round(led.Color.RPercent * 100),
|
||||
(int)Math.Round(led.Color.GPercent * 100),
|
||||
(int)Math.Round(led.Color.BPercent * 100));
|
||||
}
|
||||
|
||||
if (bitmap != null)
|
||||
_LogitechGSDK.LogiLedSetLightingFromBitmap(bitmap);
|
||||
}
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
51
RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs
Normal file
51
RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Logitech.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Logitech
|
||||
{
|
||||
public class LogitechPerKeyUpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public LogitechPerKeyUpdateQueue(IUpdateTrigger updateTrigger)
|
||||
: base(updateTrigger)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB);
|
||||
|
||||
byte[] bitmap = null;
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
{
|
||||
(LedId id, int customData) = ((LedId, int))data.Key;
|
||||
|
||||
// DarthAffe 26.03.2017: This is only needed since update by name doesn't work as expected for all keys ...
|
||||
if (BitmapMapping.BitmapOffset.TryGetValue(id, out int bitmapOffset))
|
||||
{
|
||||
if (bitmap == null)
|
||||
bitmap = BitmapMapping.CreateBitmap();
|
||||
|
||||
BitmapMapping.SetColor(ref bitmap, bitmapOffset, data.Value);
|
||||
}
|
||||
else
|
||||
_LogitechGSDK.LogiLedSetLightingForKeyWithKeyName(customData,
|
||||
(int)Math.Round(data.Value.RPercent * 100),
|
||||
(int)Math.Round(data.Value.GPercent * 100),
|
||||
(int)Math.Round(data.Value.BPercent * 100));
|
||||
}
|
||||
|
||||
if (bitmap != null)
|
||||
_LogitechGSDK.LogiLedSetLightingFromBitmap(bitmap);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -57,11 +57,13 @@
|
||||
<Compile Include="Generic\LogitechRGBDevice.cs" />
|
||||
<Compile Include="Generic\LogitechRGBDeviceInfo.cs" />
|
||||
<Compile Include="LogitechDeviceProviderLoader.cs" />
|
||||
<Compile Include="PerDevice\LogitechPerDeviceUpdateQueue.cs" />
|
||||
<Compile Include="PerKey\BitmapMapping.cs" />
|
||||
<Compile Include="HID\DeviceChecker.cs" />
|
||||
<Compile Include="LogitechDeviceProvider.cs" />
|
||||
<Compile Include="Native\_LogitechGSDK.cs" />
|
||||
<Compile Include="PerDevice\LogitechPerDeviceRGBDevice.cs" />
|
||||
<Compile Include="PerKey\LogitechPerKeyUpdateQueue.cs" />
|
||||
<Compile Include="PerKey\PerKeyIdMapping.cs" />
|
||||
<Compile Include="PerKey\LogitechPerKeyRGBDevice.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
||||
@ -7,6 +7,6 @@ namespace RGB.NET.Devices.Novation
|
||||
/// </summary>
|
||||
internal interface INovationRGBDevice : IRGBDevice
|
||||
{
|
||||
void Initialize();
|
||||
void Initialize(IUpdateTrigger updateTrigger);
|
||||
}
|
||||
}
|
||||
|
||||
56
RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs
Normal file
56
RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
using Sanford.Multimedia.Midi;
|
||||
|
||||
namespace RGB.NET.Devices.Novation
|
||||
{
|
||||
public class LimitedColorUpdateQueue : MidiUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public LimitedColorUpdateQueue(IUpdateTrigger updateTrigger, int deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override ShortMessage CreateMessage(KeyValuePair<object, Color> data)
|
||||
{
|
||||
NovationLedId ledId = (NovationLedId)data.Key;
|
||||
return new ShortMessage(Convert.ToByte(ledId.GetStatus()), Convert.ToByte(ledId.GetId()), Convert.ToByte(ConvertColor(data.Value)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="Color"/> to its novation-representation depending on the <see cref="NovationColorCapabilities"/> of the <see cref="NovationRGBDevice{TDeviceInfo}"/>.
|
||||
/// The conversion uses only a limited amount of colors (3 red, 3 yellow, 3 green).
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert.</param>
|
||||
/// <returns>The novation-representation of the <see cref="Color"/>.</returns>
|
||||
protected virtual int ConvertColor(Color color)
|
||||
{
|
||||
if ((color.Hue >= 330) || (color.Hue < 30))
|
||||
return (int)Math.Ceiling(color.Value * 3); // red with brightness 1, 2 or 3
|
||||
|
||||
if ((color.Hue >= 30) && (color.Hue < 90)) // yellow with brightness 17, 34 or 51
|
||||
return (int)Math.Ceiling(color.Value * 3) * 17;
|
||||
|
||||
if ((color.Hue >= 90) && (color.Hue < 150)) // green with brightness 16, 32 or 48
|
||||
return (int)Math.Ceiling(color.Value * 3) * 16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
SendMessage(new ShortMessage(Convert.ToByte(0xB0), Convert.ToByte(0), Convert.ToByte(0)));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
46
RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs
Normal file
46
RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
using Sanford.Multimedia.Midi;
|
||||
|
||||
namespace RGB.NET.Devices.Novation
|
||||
{
|
||||
public abstract class MidiUpdateQueue : UpdateQueue, IDisposable
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private readonly OutputDevice _outputDevice;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public MidiUpdateQueue(IUpdateTrigger updateTrigger, int deviceId)
|
||||
: base(updateTrigger)
|
||||
{
|
||||
_outputDevice = new OutputDevice(deviceId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
SendMessage(CreateMessage(data));
|
||||
}
|
||||
|
||||
protected virtual void SendMessage(ShortMessage message) => _outputDevice.SendShort(message.Message);
|
||||
|
||||
protected abstract ShortMessage CreateMessage(KeyValuePair<object, Color> data);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_outputDevice.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
using Sanford.Multimedia.Midi;
|
||||
|
||||
namespace RGB.NET.Devices.Novation
|
||||
{
|
||||
@ -16,14 +15,13 @@ namespace RGB.NET.Devices.Novation
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private readonly OutputDevice _outputDevice;
|
||||
private readonly TDeviceInfo _deviceInfo;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets information about the <see cref="T:RGB.NET.Devices.Novation.NovationRGBDevice" />.
|
||||
/// </summary>
|
||||
public override TDeviceInfo DeviceInfo => _deviceInfo;
|
||||
public override TDeviceInfo DeviceInfo { get; }
|
||||
|
||||
protected MidiUpdateQueue UpdateQueue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
@ -35,20 +33,17 @@ namespace RGB.NET.Devices.Novation
|
||||
/// <param name="info">The generic information provided by Novation for the device.</param>
|
||||
protected NovationRGBDevice(TDeviceInfo info)
|
||||
{
|
||||
this._deviceInfo = info;
|
||||
|
||||
_outputDevice = new OutputDevice(info.DeviceId);
|
||||
this.DeviceInfo = info;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the device.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
public void Initialize(IUpdateTrigger updateTrigger)
|
||||
{
|
||||
InitializeLayout();
|
||||
|
||||
@ -57,6 +52,9 @@ namespace RGB.NET.Devices.Novation
|
||||
Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle));
|
||||
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
|
||||
}
|
||||
|
||||
if (DeviceInfo.ColorCapabilities == NovationColorCapabilities.LimitedRG)
|
||||
UpdateQueue = new LimitedColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -65,96 +63,19 @@ namespace RGB.NET.Devices.Novation
|
||||
protected abstract void InitializeLayout();
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
|
||||
|
||||
if (leds.Count > 0)
|
||||
{
|
||||
foreach (Led led in leds)
|
||||
{
|
||||
NovationLedId ledId = (NovationLedId)led.CustomData;
|
||||
|
||||
int color = ConvertColor(led.Color);
|
||||
SendMessage(ledId.GetStatus(), ledId.GetId(), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
|
||||
|
||||
/// <summary>
|
||||
/// Resets the <see cref="NovationRGBDevice{TDeviceInfo}"/> back top default.
|
||||
/// Resets the <see cref="NovationRGBDevice{TDeviceInfo}"/> back to default.
|
||||
/// </summary>
|
||||
public virtual void Reset() => SendMessage(0xB0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="Color"/> to its novation-representation depending on the <see cref="NovationColorCapabilities"/> of the <see cref="NovationRGBDevice{TDeviceInfo}"/>.
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert.</param>
|
||||
/// <returns>The novation-representation of the <see cref="Color"/>.</returns>
|
||||
protected virtual int ConvertColor(Color color)
|
||||
{
|
||||
switch (_deviceInfo.ColorCapabilities)
|
||||
{
|
||||
case NovationColorCapabilities.RGB:
|
||||
return ConvertColorFull(color);
|
||||
case NovationColorCapabilities.LimitedRG:
|
||||
return ConvertColorLimited(color);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="Color"/> to its novation-representation depending on the <see cref="NovationColorCapabilities"/> of the <see cref="NovationRGBDevice{TDeviceInfo}"/>.
|
||||
/// The conversion uses the full rgb-range.
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert.</param>
|
||||
/// <returns>The novation-representation of the <see cref="Color"/>.</returns>
|
||||
protected virtual int ConvertColorFull(Color color)
|
||||
{
|
||||
//TODO DarthAffe 16.08.2017: How are colors for full rgb devices encoded?
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a <see cref="Color"/> to its novation-representation depending on the <see cref="NovationColorCapabilities"/> of the <see cref="NovationRGBDevice{TDeviceInfo}"/>.
|
||||
/// The conversion uses only a limited amount of colors (3 red, 3 yellow, 3 green).
|
||||
/// </summary>
|
||||
/// <param name="color">The <see cref="Color"/> to convert.</param>
|
||||
/// <returns>The novation-representation of the <see cref="Color"/>.</returns>
|
||||
protected virtual int ConvertColorLimited(Color color)
|
||||
{
|
||||
if ((color.Hue >= 330) || (color.Hue < 30))
|
||||
return (int)Math.Ceiling(color.Value * 3); // red with brightness 1, 2 or 3
|
||||
|
||||
if ((color.Hue >= 30) && (color.Hue < 90)) // yellow with brightness 17, 34 or 51
|
||||
return (int)Math.Ceiling(color.Value * 3) * 17;
|
||||
|
||||
if ((color.Hue >= 90) && (color.Hue < 150)) // green with brightness 16, 32 or 48
|
||||
return (int)Math.Ceiling(color.Value * 3) * 16;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a message to the <see cref="NovationRGBDevice{TDeviceInfo}"/>.
|
||||
/// </summary>
|
||||
/// <param name="status">The status-code of the message.</param>
|
||||
/// <param name="data1">The first data-package of the message.</param>
|
||||
/// <param name="data2">The second data-package of the message.</param>
|
||||
protected virtual void SendMessage(int status, int data1, int data2)
|
||||
{
|
||||
ShortMessage shortMessage = new ShortMessage(Convert.ToByte(status), Convert.ToByte(data1), Convert.ToByte(data2));
|
||||
_outputDevice.SendShort(shortMessage.Message);
|
||||
}
|
||||
public virtual void Reset() => UpdateQueue.Reset();
|
||||
|
||||
/// <inheritdoc cref="IDisposable.Dispose" />
|
||||
/// <inheritdoc cref="AbstractRGBDevice{TDeviceInfo}.Dispose" />
|
||||
public override void Dispose()
|
||||
{
|
||||
Reset();
|
||||
_outputDevice.Dispose();
|
||||
|
||||
UpdateQueue.Dispose();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -39,6 +39,8 @@ namespace RGB.NET.Devices.Novation
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IRGBDevice> Devices { get; private set; }
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -51,6 +53,8 @@ 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 UpdateTrigger();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -64,6 +68,8 @@ namespace RGB.NET.Devices.Novation
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger?.Stop();
|
||||
|
||||
IList<IRGBDevice> devices = new List<IRGBDevice>();
|
||||
|
||||
if (loadFilter.HasFlag(RGBDeviceType.LedMatrix))
|
||||
@ -81,12 +87,13 @@ namespace RGB.NET.Devices.Novation
|
||||
if (deviceId == null) continue;
|
||||
|
||||
INovationRGBDevice device = new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, deviceId.GetColorCapability()));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
}
|
||||
|
||||
UpdateTrigger?.Start();
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
@ -54,6 +54,8 @@
|
||||
<Compile Include="Enum\NovationColorCapabilities.cs" />
|
||||
<Compile Include="Enum\NovationDevices.cs" />
|
||||
<Compile Include="Enum\NovationLedId.cs" />
|
||||
<Compile Include="Generic\LimitedColorUpdateQueue.cs" />
|
||||
<Compile Include="Generic\MidiUpdateQueue.cs" />
|
||||
<Compile Include="Generic\NovationRGBDevice.cs" />
|
||||
<Compile Include="Generic\NovationRGBDeviceInfo.cs" />
|
||||
<Compile Include="Helper\DictionaryExtension.cs" />
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
@ -45,20 +42,7 @@ namespace RGB.NET.Devices.Razer
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(IEnumerable<Led> leds)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.CHROMALINK_MAX_LEDS];
|
||||
|
||||
foreach (Led led in leds)
|
||||
colors[(int)led.CustomData] = new _Color(led.Color.R, led.Color.G, led.Color.B);
|
||||
|
||||
_ChromaLinkCustomEffect effectParams = new _ChromaLinkCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
protected override RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger updateTrigger) => new RazerChromaLinkUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public class RazerChromaLinkUpdateQueue : RazerUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public RazerChromaLinkUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.CHROMALINK_MAX_LEDS];
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
colors[(int)data.Key] = new _Color(data.Value);
|
||||
|
||||
_ChromaLinkCustomEffect effectParams = new _ChromaLinkCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@ namespace RGB.NET.Devices.Razer
|
||||
/// </summary>
|
||||
internal interface IRazerRGBDevice : IRGBDevice
|
||||
{
|
||||
void Initialize();
|
||||
void Initialize(IUpdateTrigger updateTrigger);
|
||||
void Reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
@ -16,14 +14,14 @@ namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private Guid? _lastEffect;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Gets information about the <see cref="T:RGB.NET.Devices.Razer.RazerRGBDevice" />.
|
||||
/// </summary>
|
||||
public override TDeviceInfo DeviceInfo { get; }
|
||||
|
||||
protected RazerUpdateQueue UpdateQueue { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -46,7 +44,7 @@ namespace RGB.NET.Devices.Razer
|
||||
/// <summary>
|
||||
/// Initializes the device.
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
public void Initialize(IUpdateTrigger updateTrigger)
|
||||
{
|
||||
InitializeLayout();
|
||||
|
||||
@ -55,50 +53,24 @@ namespace RGB.NET.Devices.Razer
|
||||
Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle));
|
||||
Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y);
|
||||
}
|
||||
|
||||
UpdateQueue = CreateUpdateQueue(updateTrigger);
|
||||
}
|
||||
|
||||
protected abstract RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger 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)
|
||||
{
|
||||
List<Led> leds = ledsToUpdate.Where(x => x.Color.A > 0).ToList();
|
||||
|
||||
if (leds.Count <= 0) return;
|
||||
|
||||
IntPtr effectParams = CreateEffectParams(leds);
|
||||
Guid effectId = Guid.NewGuid();
|
||||
_RazerSDK.CreateEffect(DeviceInfo.DeviceId, _Defines.EFFECT_ID, effectParams, ref effectId);
|
||||
|
||||
_RazerSDK.SetEffect(effectId);
|
||||
|
||||
if (_lastEffect.HasValue)
|
||||
_RazerSDK.DeleteEffect(_lastEffect.Value);
|
||||
|
||||
_lastEffect = effectId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the device-specific effect parameters for the led-update.
|
||||
/// </summary>
|
||||
/// <param name="leds">The leds to be updated.</param>
|
||||
/// <returns>An <see cref="IntPtr"/> pointing to the effect parameter struct.</returns>
|
||||
protected abstract IntPtr CreateEffectParams(IEnumerable<Led> leds);
|
||||
protected override void UpdateLeds(IEnumerable<Led> ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
|
||||
|
||||
/// <summary>
|
||||
/// Resets the device.
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
if (_lastEffect.HasValue)
|
||||
{
|
||||
_RazerSDK.DeleteEffect(_lastEffect.Value);
|
||||
_lastEffect = null;
|
||||
}
|
||||
}
|
||||
public void Reset() => UpdateQueue.Reset();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
63
RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs
Normal file
63
RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public abstract class RazerUpdateQueue : UpdateQueue
|
||||
{
|
||||
#region Properties & Fields
|
||||
|
||||
private readonly Guid _deviceId;
|
||||
private Guid? _lastEffect;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
protected RazerUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger)
|
||||
{
|
||||
this._deviceId = deviceId;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Update(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
IntPtr effectParams = CreateEffectParams(dataSet);
|
||||
Guid effectId = Guid.NewGuid();
|
||||
_RazerSDK.CreateEffect(_deviceId, _Defines.EFFECT_ID, effectParams, ref effectId);
|
||||
|
||||
_RazerSDK.SetEffect(effectId);
|
||||
|
||||
if (_lastEffect.HasValue)
|
||||
_RazerSDK.DeleteEffect(_lastEffect.Value);
|
||||
|
||||
_lastEffect = effectId;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Reset()
|
||||
{
|
||||
if (_lastEffect.HasValue)
|
||||
{
|
||||
_RazerSDK.DeleteEffect(_lastEffect.Value);
|
||||
_lastEffect = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the device-specific effect parameters for the led-update.
|
||||
/// </summary>
|
||||
/// <param name="dataSet">The data to be updated.</param>
|
||||
/// <returns>An <see cref="IntPtr"/> pointing to the effect parameter struct.</returns>
|
||||
protected abstract IntPtr CreateEffectParams(Dictionary<object, Color> dataSet);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
@ -45,20 +42,7 @@ namespace RGB.NET.Devices.Razer
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(IEnumerable<Led> leds)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.HEADSET_MAX_LEDS];
|
||||
|
||||
foreach (Led led in leds)
|
||||
colors[(int)led.CustomData] = new _Color(led.Color.R, led.Color.G, led.Color.B);
|
||||
|
||||
_HeadsetCustomEffect effectParams = new _HeadsetCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
protected override RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger updateTrigger) => new RazerHeadsetUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
39
RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs
Normal file
39
RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public class RazerHeadsetUpdateQueue : RazerUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public RazerHeadsetUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.HEADSET_MAX_LEDS];
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
colors[(int)data.Key] = new _Color(data.Value);
|
||||
|
||||
_HeadsetCustomEffect effectParams = new _HeadsetCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
@ -51,20 +48,7 @@ namespace RGB.NET.Devices.Razer
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(IEnumerable<Led> leds)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.KEYBOARD_MAX_LEDS];
|
||||
|
||||
foreach (Led led in leds)
|
||||
colors[(int)led.CustomData] = new _Color(led.Color.R, led.Color.G, led.Color.B);
|
||||
|
||||
_KeyboardCustomEffect effectParams = new _KeyboardCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
protected override RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger updateTrigger) => new RazerKeyboardUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
39
RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs
Normal file
39
RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public class RazerKeyboardUpdateQueue : RazerUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public RazerKeyboardUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.KEYBOARD_MAX_LEDS];
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
colors[(int)data.Key] = new _Color(data.Value);
|
||||
|
||||
_KeyboardCustomEffect effectParams = new _KeyboardCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
@ -48,20 +45,7 @@ namespace RGB.NET.Devices.Razer
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(IEnumerable<Led> leds)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.KEYPAD_MAX_LEDS];
|
||||
|
||||
foreach (Led led in leds)
|
||||
colors[(int)led.CustomData] = new _Color(led.Color.R, led.Color.G, led.Color.B);
|
||||
|
||||
_KeypadCustomEffect effectParams = new _KeypadCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
protected override RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger updateTrigger) => new RazerKeypadUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
39
RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs
Normal file
39
RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public class RazerKeypadUpdateQueue : RazerUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public RazerKeypadUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.KEYPAD_MAX_LEDS];
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
colors[(int)data.Key] = new _Color(data.Value);
|
||||
|
||||
_KeypadCustomEffect effectParams = new _KeypadCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
@ -48,20 +45,7 @@ namespace RGB.NET.Devices.Razer
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(IEnumerable<Led> leds)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.MOUSE_MAX_LEDS];
|
||||
|
||||
foreach (Led led in leds)
|
||||
colors[(int)led.CustomData] = new _Color(led.Color.R, led.Color.G, led.Color.B);
|
||||
|
||||
_MouseCustomEffect effectParams = new _MouseCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
protected override RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger updateTrigger) => new RazerMouseUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
39
RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs
Normal file
39
RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public class RazerMouseUpdateQueue : RazerUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public RazerMouseUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.MOUSE_MAX_LEDS];
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
colors[(int)data.Key] = new _Color(data.Value);
|
||||
|
||||
_MouseCustomEffect effectParams = new _MouseCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,6 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
@ -45,20 +42,7 @@ namespace RGB.NET.Devices.Razer
|
||||
protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1;
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(IEnumerable<Led> leds)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.MOUSEPAD_MAX_LEDS];
|
||||
|
||||
foreach (Led led in leds)
|
||||
colors[(int)led.CustomData] = new _Color(led.Color.R, led.Color.G, led.Color.B);
|
||||
|
||||
_MousepadCustomEffect effectParams = new _MousepadCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
protected override RazerUpdateQueue CreateUpdateQueue(IUpdateTrigger updateTrigger) => new RazerMousepadUpdateQueue(updateTrigger, DeviceInfo.DeviceId);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
39
RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs
Normal file
39
RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
using RGB.NET.Devices.Razer.Native;
|
||||
|
||||
namespace RGB.NET.Devices.Razer
|
||||
{
|
||||
public class RazerMousepadUpdateQueue : RazerUpdateQueue
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
public RazerMousepadUpdateQueue(IUpdateTrigger updateTrigger, Guid deviceId)
|
||||
: base(updateTrigger, deviceId)
|
||||
{ }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IntPtr CreateEffectParams(Dictionary<object, Color> dataSet)
|
||||
{
|
||||
_Color[] colors = new _Color[_Defines.MOUSEPAD_MAX_LEDS];
|
||||
|
||||
foreach (KeyValuePair<object, Color> data in dataSet)
|
||||
colors[(int)data.Key] = new _Color(data.Value);
|
||||
|
||||
_MousepadCustomEffect effectParams = new _MousepadCustomEffect { Color = colors };
|
||||
|
||||
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
|
||||
Marshal.StructureToPtr(effectParams, ptr, false);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,7 @@
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using RGB.NET.Core;
|
||||
|
||||
namespace RGB.NET.Devices.Razer.Native
|
||||
{
|
||||
@ -19,6 +20,9 @@ namespace RGB.NET.Devices.Razer.Native
|
||||
|
||||
#region Constructors
|
||||
|
||||
public _Color(Color color)
|
||||
: this(color.R, color.G, color.B) { }
|
||||
|
||||
public _Color(byte red, byte green, byte blue)
|
||||
: this()
|
||||
{
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ChromaLink\RazerChromaLinkUpdateQueue.cs" />
|
||||
<Compile Include="Enum\RazerLogicalKeyboardLayout.cs" />
|
||||
<Compile Include="Enum\RazerPhysicalKeyboardLayout.cs" />
|
||||
<Compile Include="Enum\DeviceType.cs" />
|
||||
@ -55,12 +56,18 @@
|
||||
<Compile Include="Generic\IRazerRGBDevice.cs" />
|
||||
<Compile Include="ChromaLink\RazerChromaLinkRGBDevice.cs" />
|
||||
<Compile Include="ChromaLink\RazerChromaLinkRGBDeviceInfo.cs" />
|
||||
<Compile Include="Generic\RazerUpdateQueue.cs" />
|
||||
<Compile Include="Headset\RazerHeadsetUpdateQueue.cs" />
|
||||
<Compile Include="Keyboard\RazerKeyboardUpdateQueue.cs" />
|
||||
<Compile Include="Keypad\RazerKeypadUpdateQueue.cs" />
|
||||
<Compile Include="Mousepad\RazerMousepadUpdateQueue.cs" />
|
||||
<Compile Include="Mousepad\RazerMousepadRGBDevice.cs" />
|
||||
<Compile Include="Mousepad\RazerMousepadRGBDeviceInfo.cs" />
|
||||
<Compile Include="Keypad\RazerKeypadRGBDevice.cs" />
|
||||
<Compile Include="Keypad\RazerKeypadRGBDeviceInfo.cs" />
|
||||
<Compile Include="Headset\RazerHeadsetRGBDevice.cs" />
|
||||
<Compile Include="Headset\RazerHeadsetRGBDeviceInfo.cs" />
|
||||
<Compile Include="Mouse\RazerMouseUpdateQueue.cs" />
|
||||
<Compile Include="Mouse\RazerMouseRGBDevice.cs" />
|
||||
<Compile Include="Mouse\RazerMouseRGBDeviceInfo.cs" />
|
||||
<Compile Include="Keyboard\RazerKeyboardRGBDevice.cs" />
|
||||
|
||||
@ -68,6 +68,8 @@ namespace RGB.NET.Devices.Razer
|
||||
/// </summary>
|
||||
public bool LoadEmulatorDevices { get; set; } = false;
|
||||
|
||||
public UpdateTrigger UpdateTrigger { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -80,6 +82,8 @@ 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 UpdateTrigger();
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -96,10 +100,12 @@ namespace RGB.NET.Devices.Razer
|
||||
|
||||
try
|
||||
{
|
||||
UpdateTrigger?.Stop();
|
||||
|
||||
_RazerSDK.Reload();
|
||||
|
||||
RazerError error;
|
||||
if (((error = _RazerSDK.Init()) != RazerError.Success)
|
||||
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);
|
||||
|
||||
@ -113,7 +119,7 @@ namespace RGB.NET.Devices.Razer
|
||||
&& (!LoadEmulatorDevices || (Razer.Devices.KEYBOARDS.FirstOrDefault().guid != guid))) continue;
|
||||
|
||||
RazerKeyboardRGBDevice device = new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(guid, model, GetCulture()));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -126,7 +132,7 @@ namespace RGB.NET.Devices.Razer
|
||||
&& (!LoadEmulatorDevices || (Razer.Devices.MICE.FirstOrDefault().guid != guid))) continue;
|
||||
|
||||
RazerMouseRGBDevice device = new RazerMouseRGBDevice(new RazerMouseRGBDeviceInfo(guid, model));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -139,7 +145,7 @@ namespace RGB.NET.Devices.Razer
|
||||
&& (!LoadEmulatorDevices || (Razer.Devices.HEADSETS.FirstOrDefault().guid != guid))) continue;
|
||||
|
||||
RazerHeadsetRGBDevice device = new RazerHeadsetRGBDevice(new RazerHeadsetRGBDeviceInfo(guid, model));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -152,7 +158,7 @@ namespace RGB.NET.Devices.Razer
|
||||
&& (!LoadEmulatorDevices || (Razer.Devices.MOUSEMATS.FirstOrDefault().guid != guid))) continue;
|
||||
|
||||
RazerMousepadRGBDevice device = new RazerMousepadRGBDevice(new RazerMousepadRGBDeviceInfo(guid, model));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -165,7 +171,7 @@ namespace RGB.NET.Devices.Razer
|
||||
&& (!LoadEmulatorDevices || (Razer.Devices.KEYPADS.FirstOrDefault().guid != guid))) continue;
|
||||
|
||||
RazerKeypadRGBDevice device = new RazerKeypadRGBDevice(new RazerKeypadRGBDeviceInfo(guid, model));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
@ -178,11 +184,12 @@ namespace RGB.NET.Devices.Razer
|
||||
&& (!LoadEmulatorDevices || (Razer.Devices.CHROMALINKS.FirstOrDefault().guid != guid))) continue;
|
||||
|
||||
RazerChromaLinkRGBDevice device = new RazerChromaLinkRGBDevice(new RazerChromaLinkRGBDeviceInfo(guid, model));
|
||||
device.Initialize();
|
||||
device.Initialize(UpdateTrigger);
|
||||
devices.Add(device);
|
||||
}
|
||||
catch { if (throwExceptions) throw; }
|
||||
|
||||
UpdateTrigger?.Start();
|
||||
Devices = new ReadOnlyCollection<IRGBDevice>(devices);
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user