diff --git a/Devices/Generic/AbstractCueDevice.cs b/Devices/Generic/AbstractCueDevice.cs
index 6a9fbc3..f58b846 100644
--- a/Devices/Generic/AbstractCueDevice.cs
+++ b/Devices/Generic/AbstractCueDevice.cs
@@ -6,6 +6,7 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using CUE.NET.Devices.Generic.Enums;
+using CUE.NET.Effects;
using CUE.NET.Native;
namespace CUE.NET.Devices.Generic
@@ -51,6 +52,11 @@ namespace CUE.NET.Devices.Generic
///
protected abstract bool HasEffect { get; }
+ ///
+ ///
+ ///
+ protected LinkedList Effects { get; } = new LinkedList();
+
private CancellationTokenSource _updateTokenSource;
private CancellationToken _updateToken;
private Task _updateTask;
@@ -146,11 +152,13 @@ namespace CUE.NET.Devices.Generic
}
///
- /// Perform an update for all dirty keys, or all keys if flushLeds is set to true.
+ /// Performs 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.
public virtual void Update(bool flushLeds = false)
{
+ UpdateEffects();
+
IList> ledsToUpdate = (flushLeds ? Leds : Leds.Where(x => x.Value.IsDirty)).ToList();
foreach (CorsairLed led in Leds.Values)
@@ -159,6 +167,48 @@ namespace CUE.NET.Devices.Generic
UpdateLeds(ledsToUpdate);
}
+ private void UpdateEffects()
+ {
+ List effectsToRemove = new List();
+ lock (Effects)
+ {
+ long currentTicks = DateTime.Now.Ticks;
+ foreach (EffectTimeContainer effect in Effects.OrderBy(x => x.ZIndex))
+ {
+ try
+ {
+ float deltaTime;
+ if (effect.TicksAtLastUpdate < 0)
+ {
+ effect.TicksAtLastUpdate = currentTicks;
+ deltaTime = 0f;
+ }
+ else
+ deltaTime = (currentTicks - effect.TicksAtLastUpdate) / 10000000f;
+
+ effect.TicksAtLastUpdate = currentTicks;
+ effect.Effect.Update(deltaTime);
+
+ ApplyEffect(effect.Effect);
+
+ if (effect.Effect.IsDone)
+ effectsToRemove.Add(effect.Effect);
+ }
+ // ReSharper disable once CatchAllClause
+ catch (Exception ex) { ManageException(ex); }
+ }
+ }
+
+ foreach (IEffect effect in effectsToRemove)
+ DetachEffect(effect);
+ }
+
+ ///
+ /// Applies the given effect to the device LEDs.
+ ///
+ /// The effect to apply.
+ protected abstract void ApplyEffect(IEffect effect);
+
private static void UpdateLeds(ICollection> ledsToUpdate)
{
ledsToUpdate = ledsToUpdate.Where(x => x.Value.Color != Color.Transparent).ToList();
@@ -186,6 +236,53 @@ namespace CUE.NET.Devices.Generic
Marshal.FreeHGlobal(ptr);
}
+ ///
+ /// Attaches the given effect.
+ ///
+ /// The effect to attach.
+ /// true if the effect could be attached; otherwise, false.
+ public bool AttachEffect(IEffect effect)
+ {
+ bool retVal = false;
+ lock (Effects)
+ {
+ if (effect != null && Effects.All(x => x.Effect != effect))
+ {
+ effect.OnAttach();
+ Effects.AddLast(new EffectTimeContainer(effect, -1));
+ retVal = true;
+ }
+ }
+
+ CheckUpdateLoop();
+ return retVal;
+ }
+
+ ///
+ /// Detaches the given effect.
+ ///
+ /// The effect to detached.
+ /// true if the effect could be detached; otherwise, false.
+ public bool DetachEffect(IEffect effect)
+ {
+ bool retVal = false;
+ lock (Effects)
+ {
+ if (effect != null)
+ {
+ EffectTimeContainer val = Effects.FirstOrDefault(x => x.Effect == effect);
+ if (val != null)
+ {
+ effect.OnDetach();
+ Effects.Remove(val);
+ retVal = true;
+ }
+ }
+ }
+ CheckUpdateLoop();
+ return retVal;
+ }
+
///
/// Handles the needed event-calls for an exception.
///
diff --git a/Devices/Headset/CorsairHeadset.cs b/Devices/Headset/CorsairHeadset.cs
index 9e4f826..5e3eac0 100644
--- a/Devices/Headset/CorsairHeadset.cs
+++ b/Devices/Headset/CorsairHeadset.cs
@@ -4,9 +4,11 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Drawing;
using System.Linq;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Headset.Enums;
+using CUE.NET.Effects;
namespace CUE.NET.Devices.Headset
{
@@ -69,6 +71,13 @@ namespace CUE.NET.Devices.Headset
#region Methods
+ protected override void ApplyEffect(IEffect effect)
+ {
+ //TODO DarthAffe 18.10.2015: How should brushes be applied to headsets?
+ foreach (CorsairLed led in effect.LedList)
+ led.Color = effect.EffectBrush.GetColorAtPoint(new RectangleF(0, 0, 2, 2), new PointF(1, 1));
+ }
+
private void InitializeLeds()
{
GetLed((int)CorsairHeadsetLedId.LeftLogo);
diff --git a/Devices/Keyboard/CorsairKeyboard.cs b/Devices/Keyboard/CorsairKeyboard.cs
index 3b9a860..7387038 100644
--- a/Devices/Keyboard/CorsairKeyboard.cs
+++ b/Devices/Keyboard/CorsairKeyboard.cs
@@ -76,7 +76,6 @@ namespace CUE.NET.Devices.Keyboard
#endregion
private readonly LinkedList _keyGroups = new LinkedList();
- private readonly LinkedList _effects = new LinkedList();
private Dictionary _keys = new Dictionary();
@@ -113,8 +112,8 @@ namespace CUE.NET.Devices.Keyboard
{
get
{
- lock (_effects)
- return _effects.Any();
+ lock (Effects)
+ return Effects.Any();
}
}
@@ -148,7 +147,6 @@ namespace CUE.NET.Devices.Keyboard
public override void Update(bool flushLeds = false)
{
UpdateKeyGroups();
- UpdateEffects();
// Perform 'real' update
base.Update(flushLeds);
@@ -166,42 +164,13 @@ namespace CUE.NET.Devices.Keyboard
}
}
- private void UpdateEffects()
+ protected override void ApplyEffect(IEffect effect)
{
- List effectsToRemove = new List();
- lock (_effects)
- {
- long currentTicks = DateTime.Now.Ticks;
- foreach (EffectTimeContainer effect in _effects.OrderBy(x => x.ZIndex))
- {
- try
- {
- float deltaTime;
- if (effect.TicksAtLastUpdate < 0)
- {
- effect.TicksAtLastUpdate = currentTicks;
- deltaTime = 0f;
- }
- else
- deltaTime = (currentTicks - effect.TicksAtLastUpdate) / 10000000f;
+ if (effect == null) return;
- effect.TicksAtLastUpdate = currentTicks;
- effect.Effect.Update(deltaTime);
-
- //TODO DarthAffe 18.10.2015: This is really dirty and might have a really negative performance impact - find a better solution.
- IEnumerable keys = effect.Effect?.LedList?.Select(x => this.FirstOrDefault(y => y.Led == x));
- ApplyBrush((keys ?? this).ToList(), effect.Effect.EffectBrush);
-
- if (effect.Effect.IsDone)
- effectsToRemove.Add(effect.Effect);
- }
- // ReSharper disable once CatchAllClause
- catch (Exception ex) { ManageException(ex); }
- }
- }
-
- foreach (IEffect effect in effectsToRemove)
- DetachEffect(effect);
+ //TODO DarthAffe 18.10.2015: This is really dirty and might have a really negative performance impact - find a better solution.
+ IEnumerable keys = effect.LedList?.Select(x => this.FirstOrDefault(y => y.Led == x));
+ ApplyBrush((keys ?? this).ToList(), effect.EffectBrush);
}
// ReSharper disable once MemberCanBeMadeStatic.Local - idc
@@ -259,53 +228,6 @@ namespace CUE.NET.Devices.Keyboard
}
}
- ///
- /// Attaches the given effect.
- ///
- /// The effect to attach.
- /// true if the effect could be attached; otherwise, false.
- public bool AttachEffect(IEffect effect)
- {
- bool retVal = false;
- lock (_effects)
- {
- if (effect != null && _effects.All(x => x.Effect != effect))
- {
- effect.OnAttach();
- _effects.AddLast(new EffectTimeContainer(effect, -1));
- retVal = true;
- }
- }
-
- CheckUpdateLoop();
- return retVal;
- }
-
- ///
- /// Detaches the given effect.
- ///
- /// The effect to detached.
- /// true if the effect could be detached; otherwise, false.
- public bool DetachEffect(IEffect effect)
- {
- bool retVal = false;
- lock (_effects)
- {
- if (effect != null)
- {
- EffectTimeContainer val = _effects.FirstOrDefault(x => x.Effect == effect);
- if (val != null)
- {
- effect.OnDetach();
- _effects.Remove(val);
- retVal = true;
- }
- }
- }
- CheckUpdateLoop();
- return retVal;
- }
-
private void InitializeKeys()
{
_CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositions(), typeof(_CorsairLedPositions));
diff --git a/Devices/Mouse/CorsairMouse.cs b/Devices/Mouse/CorsairMouse.cs
index 944b769..8ff3888 100644
--- a/Devices/Mouse/CorsairMouse.cs
+++ b/Devices/Mouse/CorsairMouse.cs
@@ -2,12 +2,15 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable UnusedMember.Global
+using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Drawing;
using System.Linq;
using CUE.NET.Devices.Generic;
using CUE.NET.Devices.Mouse.Enums;
+using CUE.NET.Effects;
using CUE.NET.Exceptions;
namespace CUE.NET.Devices.Mouse
@@ -72,6 +75,13 @@ namespace CUE.NET.Devices.Mouse
#region Methods
+ protected override void ApplyEffect(IEffect effect)
+ {
+ //TODO DarthAffe 18.10.2015: How should brushes be applied to mice?
+ foreach (CorsairLed led in effect.LedList)
+ led.Color = effect.EffectBrush.GetColorAtPoint(new RectangleF(0, 0, 2, 2), new PointF(1, 1));
+ }
+
private void InitializeLeds()
{
switch (MouseDeviceInfo.PhysicalLayout)
diff --git a/Effects/EffectTimeContainer.cs b/Effects/EffectTimeContainer.cs
index 3cb70b0..a1c5c8a 100644
--- a/Effects/EffectTimeContainer.cs
+++ b/Effects/EffectTimeContainer.cs
@@ -6,24 +6,24 @@ namespace CUE.NET.Effects
///
/// Represents a wrapped effect with additional time information.
///
- internal class EffectTimeContainer
+ public class EffectTimeContainer
{
#region Properties & Fields
///
/// Gets or sets the wrapped effect.
///
- internal IEffect Effect { get; set; }
+ public IEffect Effect { get; set; }
///
/// Gets or sets the tick-count from the last time the effect was updated.
///
- internal long TicksAtLastUpdate { get; set; }
+ public long TicksAtLastUpdate { get; set; }
///
/// Gets the z-index of the effect.
///
- internal int ZIndex => Effect?.ZIndex ?? 0;
+ public int ZIndex => Effect?.ZIndex ?? 0;
#endregion
@@ -34,7 +34,7 @@ namespace CUE.NET.Effects
///
/// The wrapped effect.
/// The tick-count from the last time the effect was updated.
- internal EffectTimeContainer(IEffect effect, long ticksAtLastUpdate)
+ public EffectTimeContainer(IEffect effect, long ticksAtLastUpdate)
{
this.Effect = effect;
this.TicksAtLastUpdate = ticksAtLastUpdate;