diff --git a/CUE.NET.csproj b/CUE.NET.csproj
index d92255b..4f0102f 100644
--- a/CUE.NET.csproj
+++ b/CUE.NET.csproj
@@ -48,6 +48,7 @@
+
diff --git a/CueSDK.cs b/CueSDK.cs
index 95a1541..3034540 100644
--- a/CueSDK.cs
+++ b/CueSDK.cs
@@ -2,7 +2,9 @@
// ReSharper disable UnusedMember.Global
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
+using CUE.NET.Devices;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Generic.Enums;
using CUE.NET.Devices.Headset;
@@ -14,7 +16,7 @@ using CUE.NET.Native;
namespace CUE.NET
{
- public static class CueSDK
+ public static partial class CueSDK
{
#region Properties & Fields
@@ -45,6 +47,11 @@ namespace CUE.NET
///
public static CorsairError LastError => _CUESDK.CorsairGetLastError();
+ ///
+ /// Gets all initialized devices managed by the CUE-SDK.
+ ///
+ public static IEnumerable InitializedDevices { get; private set; }
+
///
/// Gets the managed representation of a keyboard managed by the CUE-SDK.
/// Note that currently only one connected keyboard is supported.
@@ -155,6 +162,7 @@ namespace CUE.NET
HasExclusiveAccess = true;
}
+ IList devices = new List();
int deviceCount = _CUESDK.CorsairGetDeviceCount();
for (int i = 0; i < deviceCount; i++)
{
@@ -166,16 +174,16 @@ namespace CUE.NET
switch (info.Type)
{
case CorsairDeviceType.Keyboard:
- KeyboardSDK = new CorsairKeyboard(new CorsairKeyboardDeviceInfo(nativeDeviceInfo));
+ devices.Add(KeyboardSDK = new CorsairKeyboard(new CorsairKeyboardDeviceInfo(nativeDeviceInfo)));
break;
case CorsairDeviceType.Mouse:
- MouseSDK = new CorsairMouse(new CorsairMouseDeviceInfo(nativeDeviceInfo));
+ devices.Add(MouseSDK = new CorsairMouse(new CorsairMouseDeviceInfo(nativeDeviceInfo)));
break;
case CorsairDeviceType.Headset:
- HeadsetSDK = new CorsairHeadset(new CorsairHeadsetDeviceInfo(nativeDeviceInfo));
+ devices.Add(HeadsetSDK = new CorsairHeadset(new CorsairHeadsetDeviceInfo(nativeDeviceInfo)));
break;
case CorsairDeviceType.Mousemat:
- MousematSDK = new CorsairMousemat(new CorsairMousematDeviceInfo(nativeDeviceInfo));
+ devices.Add(MousematSDK = new CorsairMousemat(new CorsairMousematDeviceInfo(nativeDeviceInfo)));
break;
// ReSharper disable once RedundantCaseLabel
case CorsairDeviceType.Unknown:
@@ -188,6 +196,8 @@ namespace CUE.NET
Throw(error);
}
+ InitializedDevices = new ReadOnlyCollection(devices);
+
IsInitialized = true;
}
diff --git a/CueSDKAutoUpdate.cs b/CueSDKAutoUpdate.cs
new file mode 100644
index 0000000..9fe7877
--- /dev/null
+++ b/CueSDKAutoUpdate.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using CUE.NET.Devices;
+using CUE.NET.Devices.Generic.Enums;
+
+namespace CUE.NET
+{
+ public static partial class CueSDK
+ {
+ #region Properties & Fields
+
+ private static CancellationTokenSource _updateTokenSource;
+ private static CancellationToken _updateToken;
+ private static Task _updateTask;
+
+ ///
+ /// Gets or sets the update-frequency in seconds. (Calculate by using '1f / updates per second')
+ ///
+ public static float UpdateFrequency { get; set; } = 1f / 30f;
+
+ private static UpdateMode _updateMode = UpdateMode.Manual;
+ ///
+ /// Gets or sets the update-mode for the device.
+ ///
+ public static UpdateMode UpdateMode
+ {
+ get { return _updateMode; }
+ set
+ {
+ _updateMode = value;
+ CheckUpdateLoop();
+ }
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Checks if automatic updates should occur and starts/stops the update-loop if needed.
+ ///
+ /// Thrown if the requested update-mode is not available.
+ private static async void CheckUpdateLoop()
+ {
+ bool shouldRun;
+ switch (UpdateMode)
+ {
+ case UpdateMode.Manual:
+ shouldRun = false;
+ break;
+ case UpdateMode.Continuous:
+ shouldRun = true;
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if (shouldRun && _updateTask == null) // Start task
+ {
+ _updateTokenSource?.Dispose();
+ _updateTokenSource = new CancellationTokenSource();
+ _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token));
+ }
+ else if (!shouldRun && _updateTask != null) // Stop task
+ {
+ _updateTokenSource.Cancel();
+ await _updateTask;
+ _updateTask.Dispose();
+ _updateTask = null;
+ }
+ }
+
+ private static void UpdateLoop()
+ {
+ while (!_updateToken.IsCancellationRequested)
+ {
+ long preUpdateTicks = DateTime.Now.Ticks;
+
+ foreach (ICueDevice device in InitializedDevices)
+ device.Update();
+
+ int sleep = (int)((UpdateFrequency * 1000f) - ((DateTime.Now.Ticks - preUpdateTicks) / 10000f));
+ if (sleep > 0)
+ Thread.Sleep(sleep);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/Devices/Generic/AbstractCueDevice.cs b/Devices/Generic/AbstractCueDevice.cs
index 29410b1..aa69a43 100644
--- a/Devices/Generic/AbstractCueDevice.cs
+++ b/Devices/Generic/AbstractCueDevice.cs
@@ -29,35 +29,13 @@ namespace CUE.NET.Devices.Generic
{
#region Properties & Fields
- private CancellationTokenSource _updateTokenSource;
- private CancellationToken _updateToken;
- private Task _updateTask;
- private DateTime _lastUpdate = DateTime.Now;
+ private static DateTime _lastUpdate = DateTime.Now;
///
/// Gets generic information provided by CUE for the device.
///
public IDeviceInfo DeviceInfo { get; }
- private UpdateMode _updateMode = UpdateMode.Manual;
- ///
- /// Gets or sets the update-mode for the device.
- ///
- public UpdateMode UpdateMode
- {
- get { return _updateMode; }
- set
- {
- _updateMode = value;
- CheckUpdateLoop();
- }
- }
-
- ///
- /// Gets or sets the update-frequency in seconds. (Calculate by using '1f / updates per second')
- ///
- public float UpdateFrequency { get; set; } = 1f / 30f;
-
///
/// Gets the rectangle containing all LEDs of the device.
///
@@ -166,9 +144,7 @@ namespace CUE.NET.Devices.Generic
// ReSharper disable once VirtualMemberCallInConstructor - I know, but I need this ...
InitializeLeds();
- DeviceRectangle = RectangleHelper.CreateRectangleFromRectangles(((IEnumerable)this).Select(x => x.LedRectangle));
-
- CheckUpdateLoop();
+ DeviceRectangle = RectangleHelper.CreateRectangleFromRectangles((this).Select(x => x.LedRectangle));
}
#endregion
@@ -208,56 +184,6 @@ namespace CUE.NET.Devices.Generic
#endregion
- #region Update-Loop
-
- ///
- /// Checks if automatic updates should occur and starts/stops the update-loop if needed.
- ///
- /// Thrown if the requested update-mode is not available.
- protected async void CheckUpdateLoop()
- {
- bool shouldRun;
- switch (UpdateMode)
- {
- case UpdateMode.Manual:
- shouldRun = false;
- break;
- case UpdateMode.Continuous:
- shouldRun = true;
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
-
- if (shouldRun && _updateTask == null) // Start task
- {
- _updateTokenSource?.Dispose();
- _updateTokenSource = new CancellationTokenSource();
- _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token));
- }
- else if (!shouldRun && _updateTask != null) // Stop task
- {
- _updateTokenSource.Cancel();
- await _updateTask;
- _updateTask.Dispose();
- _updateTask = null;
- }
- }
-
- private void UpdateLoop()
- {
- while (!_updateToken.IsCancellationRequested)
- {
- long preUpdateTicks = DateTime.Now.Ticks;
- Update();
- int sleep = (int)((UpdateFrequency * 1000f) - ((DateTime.Now.Ticks - preUpdateTicks) / 10000f));
- if (sleep > 0)
- Thread.Sleep(sleep);
- }
- }
-
- #endregion
-
#region Update
///
diff --git a/Devices/ICueDevice.cs b/Devices/ICueDevice.cs
index 81dcd23..75a856f 100644
--- a/Devices/ICueDevice.cs
+++ b/Devices/ICueDevice.cs
@@ -10,6 +10,8 @@ using CUE.NET.Groups;
namespace CUE.NET.Devices
{
+ #region EventHandler
+
///
/// Represents the event-handler of the Exception-event.
///
@@ -45,26 +47,20 @@ namespace CUE.NET.Devices
/// The arguments provided by the event.
public delegate void LedsUpdatedEventHandler(object sender, LedsUpdatedEventArgs args);
+ #endregion
+
///
/// Represents a generic cue device.
///
public interface ICueDevice : ILedGroup, IEnumerable
{
+ #region Properties
+
///
/// Gets generic information provided by CUE for the device.
///
IDeviceInfo DeviceInfo { get; }
- ///
- /// Gets or sets the update-mode for the device.
- ///
- UpdateMode UpdateMode { get; set; }
-
- ///
- /// Gets or sets the update-frequency in seconds. (Calculate by using '1f / updates per second')
- ///
- float UpdateFrequency { get; set; }
-
///
/// Gets the rectangle containing all LEDs of the device.
///
@@ -75,6 +71,10 @@ namespace CUE.NET.Devices
///
IEnumerable Leds { get; }
+ #endregion
+
+ #region Indexer
+
///
/// Gets the with the specified ID.
///
@@ -97,6 +97,10 @@ namespace CUE.NET.Devices
///
IEnumerable this[RectangleF referenceRect, float minOverlayPercentage = 0.5f] { get; }
+ #endregion
+
+ #region Events
+
// ReSharper disable EventNeverSubscribedTo.Global
///
@@ -126,12 +130,21 @@ namespace CUE.NET.Devices
// ReSharper restore EventNeverSubscribedTo.Global
+ #endregion
+
+ #region Methods
+
///
/// Perform an update for all dirty keys, or all keys if flushLeds is set to true.
///
/// Specifies whether all keys (including clean ones) should be updated.
void Update(bool flushLeds = false);
+ ///
+ /// Attaches the given ledgroup.
+ ///
+ /// The ledgroup to attach.
+ /// true if the ledgroup could be attached; otherwise, false.
bool AttachLedGroup(ILedGroup ledGroup);
///
@@ -140,5 +153,7 @@ namespace CUE.NET.Devices
/// The ledgroup to detached.
/// true if the ledgroup could be detached; otherwise, false.
bool DetachLedGroup(ILedGroup ledGroup);
+
+ #endregion
}
}
diff --git a/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs b/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs
index f6c4bc2..16980ee 100644
--- a/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs
+++ b/Examples/AudioAnalyzer/Example_AudioAnalyzer_full/AudioAnalyzerExample.cs
@@ -62,7 +62,7 @@ namespace Example_AudioAnalyzer_full
public void Run()
{
- _keyboard.UpdateMode = UpdateMode.Continuous;
+ CueSDK.UpdateMode = UpdateMode.Continuous;
// Add a black background. We want this to be semi-transparent to add some sort of fade-effect - this will smooth everything out a bit
// Note that this isn't a 'real effect' since it's update-rate dependent. A real effect would do always the same thing not mather how fast the keyboard updates.
_keyboard.Brush = new SolidColorBrush(Color.FromArgb(96, 0, 0, 0));
diff --git a/Examples/SimpleDevTest/Program.cs b/Examples/SimpleDevTest/Program.cs
index fa5d975..80f5383 100644
--- a/Examples/SimpleDevTest/Program.cs
+++ b/Examples/SimpleDevTest/Program.cs
@@ -36,9 +36,13 @@ namespace SimpleDevTest
CueSDK.Initialize();
Console.WriteLine("Initialized with " + CueSDK.LoadedArchitecture + "-SDK");
+ CueSDK.UpdateMode = UpdateMode.Continuous;
+
IBrush rainbowBrush = new LinearGradientBrush(new RainbowGradient());
rainbowBrush.AddEffect(new FlashEffect());
+ AddTestBrush(CueSDK.KeyboardSDK, rainbowBrush);
+ AddTestBrush(CueSDK.KeyboardSDK, rainbowBrush);
AddTestBrush(CueSDK.KeyboardSDK, rainbowBrush);
AddTestBrush(CueSDK.MouseSDK, rainbowBrush);
AddTestBrush(CueSDK.HeadsetSDK, rainbowBrush);
@@ -378,7 +382,6 @@ namespace SimpleDevTest
{
if (device == null) return;
- device.UpdateMode = UpdateMode.Continuous;
device.Brush = (SolidColorBrush)Color.Black;
ILedGroup leds = new ListLedGroup(device, device);
leds.Brush = brush;