diff --git a/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs b/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs
deleted file mode 100644
index 127ce9c..0000000
--- a/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs
+++ /dev/null
@@ -1,121 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-// ReSharper disable MemberCanBeProtected.Global
-// ReSharper disable ReturnTypeCanBeEnumerable.Global
-// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
-// ReSharper disable UnusedMember.Global
-
-using System;
-using RGB.NET.Brushes.Gradients;
-using RGB.NET.Core;
-
-namespace RGB.NET.Brushes
-{
- ///
- ///
- ///
- /// Represents a brush drawing a conical gradient.
- ///
- public class ConicalGradientBrush : AbstractBrush, IGradientBrush
- {
- #region Properties & Fields
-
- private float _origin = (float)Math.Atan2(-1, 0);
- ///
- /// Gets or sets the origin (radian-angle) this is drawn to. (default: -π/2)
- ///
- public float Origin
- {
- get => _origin;
- set => SetProperty(ref _origin, value);
- }
-
- private Point _center = new(0.5, 0.5);
- ///
- /// Gets or sets the center (as percentage in the range [0..1]) of the drawn by this . (default: 0.5, 0.5)
- ///
- public Point Center
- {
- get => _center;
- set => SetProperty(ref _center, value);
- }
-
- private IGradient? _gradient;
- ///
- ///
- /// Gets or sets the gradient drawn by the brush. If null it will default to full transparent.
- ///
- public IGradient? Gradient
- {
- get => _gradient;
- set => SetProperty(ref _gradient, value);
- }
-
- #endregion
-
- #region Constructors
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- public ConicalGradientBrush()
- { }
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The drawn by this .
- public ConicalGradientBrush(IGradient gradient)
- {
- this.Gradient = gradient;
- }
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The center (as percentage in the range [0..1]).
- /// The drawn by this .
- public ConicalGradientBrush(Point center, IGradient gradient)
- {
- this.Center = center;
- this.Gradient = gradient;
- }
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The center (as percentage in the range [0..1]).
- /// The origin (radian-angle) the is drawn to.
- /// The drawn by this .
- public ConicalGradientBrush(Point center, float origin, IGradient gradient)
- {
- this.Center = center;
- this.Origin = origin;
- this.Gradient = gradient;
- }
-
- #endregion
-
- #region Methods
-
- ///
- protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget)
- {
- if (Gradient == null) return Color.Transparent;
-
- double centerX = rectangle.Size.Width * Center.X;
- double centerY = rectangle.Size.Height * Center.Y;
-
- double angle = Math.Atan2(renderTarget.Point.Y - centerY, renderTarget.Point.X - centerX) - Origin;
- if (angle < 0) angle += Math.PI * 2;
- double offset = angle / (Math.PI * 2);
-
- return Gradient.GetColor(offset);
- }
-
- #endregion
- }
-}
diff --git a/RGB.NET.Brushes/Brushes/IGradientBrush.cs b/RGB.NET.Brushes/Brushes/IGradientBrush.cs
deleted file mode 100644
index 80522a3..0000000
--- a/RGB.NET.Brushes/Brushes/IGradientBrush.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using RGB.NET.Brushes.Gradients;
-using RGB.NET.Core;
-
-namespace RGB.NET.Brushes
-{
- ///
- ///
- /// Represents a basic gradient-brush.
- ///
- public interface IGradientBrush : IBrush
- {
- ///
- /// Gets the used by this .
- ///
- IGradient? Gradient { get; }
- }
-}
diff --git a/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs b/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs
deleted file mode 100644
index c175068..0000000
--- a/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// ReSharper disable CollectionNeverUpdated.Global
-// ReSharper disable MemberCanBePrivate.Global
-// ReSharper disable MemberCanBeProtected.Global
-// ReSharper disable ReturnTypeCanBeEnumerable.Global
-// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
-// ReSharper disable UnusedMember.Global
-
-using RGB.NET.Brushes.Gradients;
-using RGB.NET.Brushes.Helper;
-using RGB.NET.Core;
-
-namespace RGB.NET.Brushes
-{
- ///
- ///
- ///
- /// Represents a brush drawing a linear gradient.
- ///
- public class LinearGradientBrush : AbstractBrush, IGradientBrush
- {
- #region Properties & Fields
-
- private Point _startPoint = new(0, 0.5);
- ///
- /// Gets or sets the start (as percentage in the range [0..1]) of the drawn by this . (default: 0.0, 0.5)
- ///
- public Point StartPoint
- {
- get => _startPoint;
- set => SetProperty(ref _startPoint, value);
- }
-
- private Point _endPoint = new(1, 0.5);
- ///
- /// Gets or sets the end (as percentage in the range [0..1]) of the drawn by this . (default: 1.0, 0.5)
- ///
- public Point EndPoint
- {
- get => _endPoint;
- set => SetProperty(ref _endPoint, value);
- }
-
- private IGradient? _gradient;
- ///
- public IGradient? Gradient
- {
- get => _gradient;
- set => SetProperty(ref _gradient, value);
- }
-
- #endregion
-
- #region Constructor
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- public LinearGradientBrush()
- { }
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The drawn by this .
- public LinearGradientBrush(IGradient gradient)
- {
- this.Gradient = gradient;
- }
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The start (as percentage in the range [0..1]).
- /// The end (as percentage in the range [0..1]).
- /// The drawn by this .
- public LinearGradientBrush(Point startPoint, Point endPoint, IGradient gradient)
- {
- this.StartPoint = startPoint;
- this.EndPoint = endPoint;
- this.Gradient = gradient;
- }
-
- #endregion
-
- #region Methods
-
- ///
- ///
- /// Gets the color at an specific point assuming the brush is drawn into the given rectangle.
- ///
- /// The rectangle in which the brush should be drawn.
- /// The target (key/point) from which the color should be taken.
- /// The color at the specified point.
- protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget)
- {
- if (Gradient == null) return Color.Transparent;
-
- Point startPoint = new(StartPoint.X * rectangle.Size.Width, StartPoint.Y * rectangle.Size.Height);
- Point endPoint = new(EndPoint.X * rectangle.Size.Width, EndPoint.Y * rectangle.Size.Height);
-
- double offset = GradientHelper.CalculateLinearGradientOffset(startPoint, endPoint, renderTarget.Point);
- return Gradient.GetColor(offset);
- }
-
- #endregion
- }
-}
diff --git a/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs b/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs
deleted file mode 100644
index 9d2ee34..0000000
--- a/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
-// ReSharper disable UnusedMember.Global
-
-using System;
-using RGB.NET.Brushes.Gradients;
-using RGB.NET.Brushes.Helper;
-using RGB.NET.Core;
-
-namespace RGB.NET.Brushes
-{
- ///
- ///
- ///
- /// Represents a brush drawing a radial gradient around a center point.
- ///
- public class RadialGradientBrush : AbstractBrush, IGradientBrush
- {
- #region Properties & Fields
-
- private Point _center = new(0.5, 0.5);
- ///
- /// Gets or sets the center (as percentage in the range [0..1]) around which the should be drawn. (default: 0.5, 0.5)
- ///
- public Point Center
- {
- get => _center;
- set => SetProperty(ref _center, value);
- }
-
- private IGradient? _gradient;
- ///
- public IGradient? Gradient
- {
- get => _gradient;
- set => SetProperty(ref _gradient, value);
- }
-
- #endregion
-
- #region Constructors
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- public RadialGradientBrush()
- { }
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The gradient drawn by the brush.
- public RadialGradientBrush(IGradient gradient)
- {
- this.Gradient = gradient;
- }
-
- ///
- ///
- /// Initializes a new instance of the class.
- ///
- /// The center point (as percentage in the range [0..1]).
- /// The gradient drawn by the brush.
- public RadialGradientBrush(Point center, IGradient gradient)
- {
- this.Center = center;
- this.Gradient = gradient;
- }
-
- #endregion
-
- #region Methods
-
- ///
- protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget)
- {
- if (Gradient == null) return Color.Transparent;
-
- Point centerPoint = new(rectangle.Location.X + (rectangle.Size.Width * Center.X), rectangle.Location.Y + (rectangle.Size.Height * Center.Y));
-
- // Calculate the distance to the farthest point from the center as reference (this has to be a corner)
- // ReSharper disable once RedundantCast - never trust this ...
- double refDistance = Math.Max(Math.Max(Math.Max(GradientHelper.CalculateDistance(rectangle.Location, centerPoint),
- GradientHelper.CalculateDistance(new Point(rectangle.Location.X + rectangle.Size.Width, rectangle.Location.Y), centerPoint)),
- GradientHelper.CalculateDistance(new Point(rectangle.Location.X, rectangle.Location.Y + rectangle.Size.Height), centerPoint)),
- GradientHelper.CalculateDistance(new Point(rectangle.Location.X + rectangle.Size.Width, rectangle.Location.Y + rectangle.Size.Height), centerPoint));
-
- double distance = GradientHelper.CalculateDistance(renderTarget.Point, centerPoint);
- double offset = distance / refDistance;
- return Gradient.GetColor(offset);
- }
-
- #endregion
- }
-}
diff --git a/RGB.NET.Brushes/RGB.NET.Brushes.csproj b/RGB.NET.Brushes/RGB.NET.Brushes.csproj
deleted file mode 100644
index f17e2aa..0000000
--- a/RGB.NET.Brushes/RGB.NET.Brushes.csproj
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
- net5.0
- latest
- enable
-
- Darth Affe
- Wyrez
- en-US
- en-US
- RGB.NET.Brushes
- RGB.NET.Brushes
- RGB.NET.Brushes
- RGB.NET.Brushes
- RGB.NET.Brushes
- Brushes-Presets of RGB.NET
- Brushes-Presets of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals
- Copyright © Darth Affe 2020
- Copyright © Darth Affe 2020
- http://lib.arge.be/icon.png
- https://github.com/DarthAffe/RGB.NET
- https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE
- Github
- https://github.com/DarthAffe/RGB.NET
- True
-
-
-
- 0.0.1
- 0.0.1
- 0.0.1
-
- ..\bin\
- true
- True
- True
-
-
-
- $(DefineConstants);TRACE;DEBUG
- true
- full
- false
-
-
-
- pdbonly
- true
- $(NoWarn);CS1591;CS1572;CS1573
- $(DefineConstants);RELEASE
-
-
-
-
-
-
\ No newline at end of file
diff --git a/RGB.NET.Brushes/RGB.NET.Brushes.csproj.DotSettings b/RGB.NET.Brushes/RGB.NET.Brushes.csproj.DotSettings
deleted file mode 100644
index c25ceff..0000000
--- a/RGB.NET.Brushes/RGB.NET.Brushes.csproj.DotSettings
+++ /dev/null
@@ -1,3 +0,0 @@
-
- True
- True
\ No newline at end of file
diff --git a/RGB.NET.Core/Brushes/IBrush.cs b/RGB.NET.Core/Brushes/IBrush.cs
deleted file mode 100644
index 7d7f2c0..0000000
--- a/RGB.NET.Core/Brushes/IBrush.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// ReSharper disable UnusedMemberInSuper.Global
-// ReSharper disable UnusedMember.Global
-// ReSharper disable ReturnTypeCanBeEnumerable.Global
-
-using System.Collections.Generic;
-
-namespace RGB.NET.Core
-{
- ///
- /// Represents a basic brush.
- ///
- public interface IBrush : IDecoratable
- {
- ///
- /// Gets or sets if the is enabled and will be drawn on an update.
- ///
- bool IsEnabled { get; set; }
-
- ///
- /// Gets or sets the calculation mode used for the rectangle/points used for color-selection in brushes.
- ///
- BrushCalculationMode BrushCalculationMode { get; set; }
-
- ///
- /// Gets or sets the overall percentage brightness of the .
- ///
- double Brightness { get; set; }
-
- ///
- /// Gets or sets the overall percentage opacity of the .
- ///
- double Opacity { get; set; }
-
- ///
- /// Gets a list of used to correct the colors of the .
- ///
- IList ColorCorrections { get; }
-
- ///
- /// Gets the used in the last render pass.
- ///
- Rectangle RenderedRectangle { get; }
-
- ///
- /// Gets a dictionary containing all for calculated in the last render pass.
- ///
- Dictionary RenderedTargets { get; }
-
- ///
- /// Performs the render pass of the and calculates the raw for all requested .
- ///
- /// The in which the brush should be drawn.
- /// The (keys/points) of which the color should be calculated.
- void PerformRender(Rectangle rectangle, IEnumerable renderTargets);
-
- ///
- /// Performs the finalize pass of the and calculates the final for all previously calculated .
- ///
- void PerformFinalize();
- }
-}
\ No newline at end of file
diff --git a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs
index 40b0eec..48ef24f 100644
--- a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs
+++ b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs
@@ -8,18 +8,18 @@
/// Converts the individual byte values of this to a human-readable string.
///
/// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]".
- public virtual string ToString(Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]";
+ public virtual string ToString(in Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]";
///
/// Tests whether the specified object is a and is equivalent to this .
///
/// The object to test.
/// true if is a equivalent to this ; otherwise, false.
- public virtual bool Equals(Color color, object? obj)
+ public virtual bool Equals(in Color color, object? obj)
{
- if (!(obj is Color)) return false;
+ if (!(obj is Color color2)) return false;
- (double a, double r, double g, double b) = ((Color)obj).GetRGB();
+ (float a, float r, float g, float b) = color2.GetRGB();
return color.A.EqualsInTolerance(a) && color.R.EqualsInTolerance(r) && color.G.EqualsInTolerance(g) && color.B.EqualsInTolerance(b);
}
@@ -27,7 +27,7 @@
/// Returns a hash code for this .
///
/// An integer value that specifies the hash code for this .
- public virtual int GetHashCode(Color color)
+ public virtual int GetHashCode(in Color color)
{
unchecked
{
@@ -43,17 +43,17 @@
/// Blends a over this color.
///
/// The to blend.
- public virtual Color Blend(Color baseColor, Color blendColor)
+ public virtual Color Blend(in Color baseColor, in Color blendColor)
{
if (blendColor.A.EqualsInTolerance(0)) return baseColor;
if (blendColor.A.EqualsInTolerance(1))
return blendColor;
- double resultA = (1.0 - ((1.0 - blendColor.A) * (1.0 - baseColor.A)));
- double resultR = (((blendColor.R * blendColor.A) / resultA) + ((baseColor.R * baseColor.A * (1.0 - blendColor.A)) / resultA));
- double resultG = (((blendColor.G * blendColor.A) / resultA) + ((baseColor.G * baseColor.A * (1.0 - blendColor.A)) / resultA));
- double resultB = (((blendColor.B * blendColor.A) / resultA) + ((baseColor.B * baseColor.A * (1.0 - blendColor.A)) / resultA));
+ float resultA = (1.0f - ((1.0f - blendColor.A) * (1.0f - baseColor.A)));
+ float resultR = (((blendColor.R * blendColor.A) / resultA) + ((baseColor.R * baseColor.A * (1.0f - blendColor.A)) / resultA));
+ float resultG = (((blendColor.G * blendColor.A) / resultA) + ((baseColor.G * baseColor.A * (1.0f - blendColor.A)) / resultA));
+ float resultB = (((blendColor.B * blendColor.A) / resultA) + ((baseColor.B * baseColor.A * (1.0f - blendColor.A)) / resultA));
return new Color(resultA, resultR, resultG, resultB);
}
diff --git a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs
index 3ee7b78..0e4a23f 100644
--- a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs
+++ b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs
@@ -2,12 +2,12 @@
{
public interface IColorBehavior
{
- string ToString(Color color);
+ string ToString(in Color color);
- bool Equals(Color color, object? obj);
+ bool Equals(in Color color, object? obj);
- int GetHashCode(Color color);
+ int GetHashCode(in Color color);
- Color Blend(Color baseColor, Color blendColor);
+ Color Blend(in Color baseColor, in Color blendColor);
}
}
diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs
index e389f19..9e8f83e 100644
--- a/RGB.NET.Core/Color/Color.cs
+++ b/RGB.NET.Core/Color/Color.cs
@@ -15,10 +15,11 @@ namespace RGB.NET.Core
{
#region Constants
+ private static readonly Color TRANSPARENT = new(0, 0, 0, 0);
///
/// Gets an transparent color [A: 0, R: 0, G: 0, B: 0]
///
- public static Color Transparent => new(0, 0, 0, 0);
+ public static ref readonly Color Transparent => ref TRANSPARENT;
#endregion
@@ -32,22 +33,22 @@ namespace RGB.NET.Core
///
/// Gets the alpha component value of this as percentage in the range [0..1].
///
- public double A { get; }
+ public float A { get; }
///
/// Gets the red component value of this as percentage in the range [0..1].
///
- public double R { get; }
+ public float R { get; }
///
/// Gets the green component value of this as percentage in the range [0..1].
///
- public double G { get; }
+ public float G { get; }
///
/// Gets the blue component value of this as percentage in the range [0..1].
///
- public double B { get; }
+ public float B { get; }
#endregion
@@ -106,8 +107,8 @@ namespace RGB.NET.Core
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
- public Color(double r, double g, double b)
- : this(1.0, r, g, b)
+ public Color(float r, float g, float b)
+ : this(1.0f, r, g, b)
{ }
///
@@ -117,7 +118,7 @@ namespace RGB.NET.Core
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
- public Color(double a, byte r, byte g, byte b)
+ public Color(float a, byte r, byte g, byte b)
: this(a, r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue())
{ }
@@ -128,7 +129,7 @@ namespace RGB.NET.Core
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
- public Color(double a, int r, int g, int b)
+ public Color(float a, int r, int g, int b)
: this(a, (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue))
{ }
@@ -139,7 +140,7 @@ namespace RGB.NET.Core
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
- public Color(int a, double r, double g, double b)
+ public Color(int a, float r, float g, float b)
: this((byte)a.Clamp(0, byte.MaxValue), r, g, b)
{ }
@@ -150,7 +151,7 @@ namespace RGB.NET.Core
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
- public Color(byte a, double r, double g, double b)
+ public Color(byte a, float r, float g, float b)
: this(a.GetPercentageFromByteValue(), r, g, b)
{ }
@@ -161,7 +162,7 @@ namespace RGB.NET.Core
/// The red component value of this .
/// The green component value of this .
/// The blue component value of this .
- public Color(double a, double r, double g, double b)
+ public Color(float a, float r, float g, float b)
{
A = a.Clamp(0, 1);
R = r.Clamp(0, 1);
@@ -174,7 +175,7 @@ namespace RGB.NET.Core
/// Initializes a new instance of the struct by cloning a existing .
///
/// The the values are copied from.
- public Color(Color color)
+ public Color(in Color color)
: this(color.A, color.R, color.G, color.B)
{ }
@@ -206,7 +207,7 @@ namespace RGB.NET.Core
/// Blends a over this color, as defined by the current .
///
/// The to blend.
- public Color Blend(Color color) => Behavior.Blend(this, color);
+ public Color Blend(in Color color) => Behavior.Blend(this, color);
#endregion
@@ -218,7 +219,7 @@ namespace RGB.NET.Core
/// The base color.
/// The color to blend.
/// The blended color.
- public static Color operator +(Color color1, Color color2) => color1.Blend(color2);
+ public static Color operator +(in Color color1, in Color color2) => color1.Blend(color2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -226,7 +227,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are equal; otherwise, false.
- public static bool operator ==(Color color1, Color color2) => color1.Equals(color2);
+ public static bool operator ==(in Color color1, in Color color2) => color1.Equals(color2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -234,7 +235,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are not equal; otherwise, false.
- public static bool operator !=(Color color1, Color color2) => !(color1 == color2);
+ public static bool operator !=(in Color color1, in Color color2) => !(color1 == color2);
///
/// Converts a of ARGB-components to a .
@@ -269,14 +270,14 @@ namespace RGB.NET.Core
///
/// The containing the components.
/// The color.
- public static implicit operator Color((double r, double g, double b) components) => new(components.r, components.g, components.b);
+ public static implicit operator Color((float r, float g, float b) components) => new(components.r, components.g, components.b);
///
/// Converts a of ARGB-components to a .
///
/// The containing the components.
/// The color.
- public static implicit operator Color((double a, double r, double g, double b) components) => new(components.a, components.r, components.g, components.b);
+ public static implicit operator Color((float a, float r, float g, float b) components) => new(components.a, components.r, components.g, components.b);
#endregion
}
diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs
index 741a654..492742f 100644
--- a/RGB.NET.Core/Color/HSVColor.cs
+++ b/RGB.NET.Core/Color/HSVColor.cs
@@ -13,21 +13,21 @@ namespace RGB.NET.Core
///
///
///
- public static double GetHue(this Color color) => color.GetHSV().hue;
+ public static float GetHue(this in Color color) => color.GetHSV().hue;
///
/// Gets the saturation component value (HSV-color space) of this in the range [0..1].
///
///
///
- public static double GetSaturation(this Color color) => color.GetHSV().saturation;
+ public static float GetSaturation(this in Color color) => color.GetHSV().saturation;
///
/// Gets the value component value (HSV-color space) of this in the range [0..1].
///
///
///
- public static double GetValue(this Color color) => color.GetHSV().value;
+ public static float GetValue(this in Color color) => color.GetHSV().value;
///
/// Gets the hue, saturation and value component values (HSV-color space) of this .
@@ -37,7 +37,7 @@ namespace RGB.NET.Core
///
///
///
- public static (double hue, double saturation, double value) GetHSV(this Color color)
+ public static (float hue, float saturation, float value) GetHSV(this in Color color)
=> CaclulateHSVFromRGB(color.R, color.G, color.B);
#endregion
@@ -51,9 +51,9 @@ namespace RGB.NET.Core
/// The saturation value to add.
/// The value value to add.
/// The new color after the modification.
- public static Color AddHSV(this Color color, double hue = 0, double saturation = 0, double value = 0)
+ public static Color AddHSV(this in Color color, float hue = 0, float saturation = 0, float value = 0)
{
- (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ (float cHue, float cSaturation, float cValue) = color.GetHSV();
return Create(color.A, cHue + hue, cSaturation + saturation, cValue + value);
}
@@ -64,9 +64,9 @@ namespace RGB.NET.Core
/// The saturation value to subtract.
/// The value value to subtract.
/// The new color after the modification.
- public static Color SubtractHSV(this Color color, double hue = 0, double saturation = 0, double value = 0)
+ public static Color SubtractHSV(this in Color color, float hue = 0, float saturation = 0, float value = 0)
{
- (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ (float cHue, float cSaturation, float cValue) = color.GetHSV();
return Create(color.A, cHue - hue, cSaturation - saturation, cValue - value);
}
@@ -77,9 +77,9 @@ namespace RGB.NET.Core
/// The saturation value to multiply.
/// The value value to multiply.
/// The new color after the modification.
- public static Color MultiplyHSV(this Color color, double hue = 1, double saturation = 1, double value = 1)
+ public static Color MultiplyHSV(this in Color color, float hue = 1, float saturation = 1, float value = 1)
{
- (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ (float cHue, float cSaturation, float cValue) = color.GetHSV();
return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value);
}
@@ -90,9 +90,9 @@ namespace RGB.NET.Core
/// The saturation value to divide.
/// The value value to divide.
/// The new color after the modification.
- public static Color DivideHSV(this Color color, double hue = 1, double saturation = 1, double value = 1)
+ public static Color DivideHSV(this in Color color, float hue = 1, float saturation = 1, float value = 1)
{
- (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ (float cHue, float cSaturation, float cValue) = color.GetHSV();
return Create(color.A, cHue / hue, cSaturation / saturation, cValue / value);
}
@@ -103,9 +103,9 @@ namespace RGB.NET.Core
/// The saturation value to set.
/// The value value to set.
/// The new color after the modification.
- public static Color SetHSV(this Color color, double? hue = null, double? saturation = null, double? value = null)
+ public static Color SetHSV(this in Color color, float? hue = null, float? saturation = null, float? value = null)
{
- (double cHue, double cSaturation, double cValue) = color.GetHSV();
+ (float cHue, float cSaturation, float cValue) = color.GetHSV();
return Create(color.A, hue ?? cHue, saturation ?? cSaturation, value ?? cValue);
}
@@ -120,8 +120,8 @@ namespace RGB.NET.Core
/// The saturation component value of this .
/// The value component value of this .
/// The color created from the values.
- public static Color Create(double hue, double saturation, double value)
- => Create(1.0, hue, saturation, value);
+ public static Color Create(float hue, float saturation, float value)
+ => Create(1.0f, hue, saturation, value);
///
/// Creates a new instance of the struct using AHSV-Values.
@@ -131,8 +131,8 @@ namespace RGB.NET.Core
/// The saturation component value of this .
/// The value component value of this .
/// The color created from the values.
- public static Color Create(byte a, double hue, double saturation, double value)
- => Create((double)a / byte.MaxValue, hue, saturation, value);
+ public static Color Create(byte a, float hue, float saturation, float value)
+ => Create((float)a / byte.MaxValue, hue, saturation, value);
///
/// Creates a new instance of the struct using AHSV-Values.
@@ -142,8 +142,8 @@ namespace RGB.NET.Core
/// The saturation component value of this .
/// The value component value of this .
/// The color created from the values.
- public static Color Create(int a, double hue, double saturation, double value)
- => Create((double)a / byte.MaxValue, hue, saturation, value);
+ public static Color Create(int a, float hue, float saturation, float value)
+ => Create((float)a / byte.MaxValue, hue, saturation, value);
///
/// Creates a new instance of the struct using AHSV-Values.
@@ -153,9 +153,9 @@ namespace RGB.NET.Core
/// The saturation component value of this .
/// The value component value of this .
/// The color created from the values.
- public static Color Create(double a, double hue, double saturation, double value)
+ public static Color Create(float a, float hue, float saturation, float value)
{
- (double r, double g, double b) = CalculateRGBFromHSV(hue, saturation, value);
+ (float r, float g, float b) = CalculateRGBFromHSV(hue, saturation, value);
return new Color(a, r, g, b);
}
@@ -163,33 +163,33 @@ namespace RGB.NET.Core
#region Helper
- private static (double h, double s, double v) CaclulateHSVFromRGB(double r, double g, double b)
+ private static (float h, float s, float v) CaclulateHSVFromRGB(float r, float g, float b)
{
if (r.EqualsInTolerance(g) && g.EqualsInTolerance(b)) return (0, 0, r);
- double min = Math.Min(Math.Min(r, g), b);
- double max = Math.Max(Math.Max(r, g), b);
+ float min = Math.Min(Math.Min(r, g), b);
+ float max = Math.Max(Math.Max(r, g), b);
- double hue;
+ float hue;
if (max.EqualsInTolerance(min))
hue = 0;
else if (max.EqualsInTolerance(r)) // r is max
hue = (g - b) / (max - min);
else if (max.EqualsInTolerance(g)) // g is max
- hue = 2.0 + ((b - r) / (max - min));
+ hue = 2.0f + ((b - r) / (max - min));
else // b is max
- hue = 4.0 + ((r - g) / (max - min));
+ hue = 4.0f + ((r - g) / (max - min));
- hue *= 60.0;
+ hue *= 60.0f;
hue = hue.Wrap(0, 360);
- double saturation = max.EqualsInTolerance(0) ? 0 : 1.0 - (min / max);
- double value = Math.Max(r, Math.Max(g, b));
+ float saturation = max.EqualsInTolerance(0) ? 0 : 1.0f - (min / max);
+ float value = Math.Max(r, Math.Max(g, b));
return (hue, saturation, value);
}
- private static (double r, double g, double b) CalculateRGBFromHSV(double h, double s, double v)
+ private static (float r, float g, float b) CalculateRGBFromHSV(float h, float s, float v)
{
h = h.Wrap(0, 360);
s = s.Clamp(0, 1);
@@ -198,12 +198,12 @@ namespace RGB.NET.Core
if (s <= 0.0)
return (v, v, v);
- double hh = h / 60.0;
+ float hh = h / 60.0f;
int i = (int)hh;
- double ff = hh - i;
- double p = v * (1.0 - s);
- double q = v * (1.0 - (s * ff));
- double t = v * (1.0 - (s * (1.0 - ff)));
+ float ff = hh - i;
+ float p = v * (1.0f - s);
+ float q = v * (1.0f - (s * ff));
+ float t = v * (1.0f - (s * (1.0f - ff)));
return i switch
{
diff --git a/RGB.NET.Core/Color/HclColor.cs b/RGB.NET.Core/Color/HclColor.cs
new file mode 100644
index 0000000..368ae8d
--- /dev/null
+++ b/RGB.NET.Core/Color/HclColor.cs
@@ -0,0 +1,203 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+using System;
+
+namespace RGB.NET.Core
+{
+ public static class HclColor
+ {
+ #region Getter
+
+ ///
+ /// Gets the H component value (Hcl-color space) of this in the range [0..360].
+ ///
+ ///
+ ///
+ public static float GetHclH(this in Color color) => color.GetHcl().l;
+
+ ///
+ /// Gets the c component value (Hcl-color space) of this in the range [0..1].
+ ///
+ ///
+ ///
+ public static float GetHclC(this in Color color) => color.GetHcl().c;
+
+ ///
+ /// Gets the l component value (Hcl-color space) of this in the range [0..1].
+ ///
+ ///
+ ///
+ public static float GetHclL(this in Color color) => color.GetHcl().h;
+
+ ///
+ /// Gets the H, c and l component values (Hcl-color space) of this .
+ /// H in the range [0..360].
+ /// c in the range [0..1].
+ /// l in the range [0..1].
+ ///
+ ///
+ ///
+ public static (float h, float c, float l) GetHcl(this in Color color)
+ => CalculateHclFromRGB(color.R, color.G, color.B);
+
+ #endregion
+
+ #region Manipulation
+
+ ///
+ /// Adds the given Hcl values to this color.
+ ///
+ /// The H value to add.
+ /// The c value to add.
+ /// The l value to add.
+ /// The new color after the modification.
+ public static Color AddHcl(this in Color color, float h = 0, float c = 0, float l = 0)
+ {
+ (float cH, float cC, float cL) = color.GetHcl();
+ return Create(color.A, cH + h, cC + c, cL + l);
+ }
+
+ ///
+ /// Subtracts the given Hcl values to this color.
+ ///
+ /// The H value to subtract.
+ /// The c value to subtract.
+ /// The l value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractHcl(this in Color color, float h = 0, float c = 0, float l = 0)
+ {
+ (float cH, float cC, float cL) = color.GetHcl();
+ return Create(color.A, cH - h, cC - c, cL - l);
+ }
+
+ ///
+ /// Multiplies the given Hcl values to this color.
+ ///
+ /// The H value to multiply.
+ /// The c value to multiply.
+ /// The l value to multiply.
+ /// The new color after the modification.
+ public static Color MultiplyHcl(this in Color color, float h = 1, float c = 1, float l = 1)
+ {
+ (float cH, float cC, float cL) = color.GetHcl();
+ return Create(color.A, cH * h, cC * c, cL * l);
+ }
+
+ ///
+ /// Divides the given Hcl values to this color.
+ ///
+ /// The H value to divide.
+ /// The c value to divide.
+ /// The l value to divide.
+ /// The new color after the modification.
+ public static Color DivideHcl(this in Color color, float h = 1, float c = 1, float l = 1)
+ {
+ (float cH, float cC, float cL) = color.GetHcl();
+ return Create(color.A, cH / h, cC / c, cL / l);
+ }
+
+ ///
+ /// Sets the given X value of this color.
+ ///
+ /// The H value to set.
+ /// The c value to set.
+ /// The l value to set.
+ /// The new color after the modification.
+ public static Color SetHcl(this in Color color, float? h = null, float? c = null, float? l = null)
+ {
+ (float cH, float cC, float cL) = color.GetHcl();
+ return Create(color.A, h ?? cH, c ?? cC, l ?? cL);
+ }
+
+ #endregion
+
+ #region Factory
+
+ ///
+ /// Creates a new instance of the struct using Hcl-Values.
+ ///
+ /// The H component value of this .
+ /// The c component value of this .
+ /// The l component value of this .
+ /// The color created from the values.
+ public static Color Create(float h, float c, float l)
+ => Create(1.0f, h, c, l);
+
+ ///
+ /// Creates a new instance of the struct using alpha and Hcl-Values.
+ ///
+ /// The alphc component value of this .
+ /// The H component value of this .
+ /// The c component value of this .
+ /// The l component value of this .
+ /// The color created from the values.
+ public static Color Create(byte alpha, float h, float c, float l)
+ => Create((float)alpha / byte.MaxValue, h, c, l);
+
+ ///
+ /// Creates a new instance of the struct using alpha and Hcl-Values.
+ ///
+ /// The alphc component value of this .
+ /// The H component value of this .
+ /// The c component value of this .
+ /// The l component value of this .
+ /// The color created from the values.
+ public static Color Create(int alpha, float h, float c, float l)
+ => Create((float)alpha / byte.MaxValue, h, c, l);
+
+ ///
+ /// Creates a new instance of the struct using alpha and Hcl-Values.
+ ///
+ /// The alphc component value of this .
+ /// The H component value of this .
+ /// The c component value of this .
+ /// The l component value of this .
+ /// The color created from the values.
+ public static Color Create(float alpha, float h, float c, float l)
+ {
+ (float r, float g, float _b) = CalculateRGBFromHcl(h, c, l);
+ return new Color(alpha, r, g, _b);
+ }
+
+ #endregion
+
+ #region Helper
+
+ private static (float h, float c, float l) CalculateHclFromRGB(float r, float g, float b)
+ {
+ const float RADIANS_DEGREES_CONVERSION = 180.0f / MathF.PI;
+
+ (float l, float a, float _b) = LabColor.CalculateLabFromRGB(r, g, b);
+
+ float h, c;
+ if (r.EqualsInTolerance(g) && r.EqualsInTolerance(b)) //DarthAffe 26.02.2021: The cumulated rounding errors are big enough to cause problems in that case
+ {
+ h = 0;
+ c = 0;
+ }
+ else
+ {
+ h = MathF.Atan2(_b, a);
+ if (h >= 0) h *= RADIANS_DEGREES_CONVERSION;
+ else h = 360 - (-h * RADIANS_DEGREES_CONVERSION);
+
+ c = MathF.Sqrt((a * a) + (_b * _b));
+ }
+
+ return (h, c, l);
+ }
+
+ private static (float r, float g, float b) CalculateRGBFromHcl(float h, float c, float l)
+ {
+ const float DEGREES_RADIANS_CONVERSION = MathF.PI / 180.0f;
+
+ h *= DEGREES_RADIANS_CONVERSION;
+ float a = c * MathF.Cos(h);
+ float b = c * MathF.Sin(h);
+
+ return LabColor.CalculateRGBFromLab(l, a, b);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Color/LabColor.cs b/RGB.NET.Core/Color/LabColor.cs
new file mode 100644
index 0000000..5583a79
--- /dev/null
+++ b/RGB.NET.Core/Color/LabColor.cs
@@ -0,0 +1,219 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+using System;
+
+namespace RGB.NET.Core
+{
+ public static class LabColor
+ {
+ #region Getter
+
+ ///
+ /// Gets the L component value (Lab-color space) of this in the range [0..100].
+ ///
+ ///
+ ///
+ public static float GetLabL(this in Color color) => color.GetLab().l;
+
+ ///
+ /// Gets the a component value (Lab-color space) of this in the range [0..1].
+ ///
+ ///
+ ///
+ public static float GetLabA(this in Color color) => color.GetLab().a;
+
+ ///
+ /// Gets the b component value (Lab-color space) of this in the range [0..1].
+ ///
+ ///
+ ///
+ public static float GetLabB(this in Color color) => color.GetLab().b;
+
+ ///
+ /// Gets the L, a and b component values (Lab-color space) of this .
+ /// L in the range [0..100].
+ /// a in the range [0..1].
+ /// b in the range [0..1].
+ ///
+ ///
+ ///
+ public static (float l, float a, float b) GetLab(this in Color color)
+ => CalculateLabFromRGB(color.R, color.G, color.B);
+
+ #endregion
+
+ #region Manipulation
+
+ ///
+ /// Adds the given Lab values to this color.
+ ///
+ /// The L value to add.
+ /// The a value to add.
+ /// The b value to add.
+ /// The new color after the modification.
+ public static Color AddLab(this in Color color, float l = 0, float a = 0, float b = 0)
+ {
+ (float cL, float cA, float cB) = color.GetLab();
+ return Create(color.A, cL + l, cA + a, cB + b);
+ }
+
+ ///
+ /// Subtracts the given Lab values to this color.
+ ///
+ /// The L value to subtract.
+ /// The a value to subtract.
+ /// The b value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractLab(this in Color color, float l = 0, float a = 0, float b = 0)
+ {
+ (float cL, float cA, float cB) = color.GetLab();
+ return Create(color.A, cL - l, cA - a, cB - b);
+ }
+
+ ///
+ /// Multiplies the given Lab values to this color.
+ ///
+ /// The L value to multiply.
+ /// The a value to multiply.
+ /// The b value to multiply.
+ /// The new color after the modification.
+ public static Color MultiplyLab(this in Color color, float l = 1, float a = 1, float b = 1)
+ {
+ (float cL, float cA, float cB) = color.GetLab();
+ return Create(color.A, cL * l, cA * a, cB * b);
+ }
+
+ ///
+ /// Divides the given Lab values to this color.
+ ///
+ /// The L value to divide.
+ /// The a value to divide.
+ /// The b value to divide.
+ /// The new color after the modification.
+ public static Color DivideLab(this in Color color, float l = 1, float a = 1, float b = 1)
+ {
+ (float cL, float cA, float cB) = color.GetLab();
+ return Create(color.A, cL / l, cA / a, cB / b);
+ }
+
+ ///
+ /// Sets the given X valueof this color.
+ ///
+ /// The L value to set.
+ /// The a value to set.
+ /// The b value to set.
+ /// The new color after the modification.
+ public static Color SetLab(this in Color color, float? l = null, float? a = null, float? b = null)
+ {
+ (float cL, float cA, float cB) = color.GetLab();
+ return Create(color.A, l ?? cL, a ?? cA, b ?? cB);
+ }
+
+ #endregion
+
+ #region Factory
+
+ ///
+ /// Creates a new instance of the struct using Lab-Values.
+ ///
+ /// The L component value of this .
+ /// The a component value of this .
+ /// The b component value of this .
+ /// The color created from the values.
+ public static Color Create(float l, float a, float b)
+ => Create(1.0f, l, a, b);
+
+ ///
+ /// Creates a new instance of the struct using alpha and Lab-Values.
+ ///
+ /// The alpha component value of this .
+ /// The L component value of this .
+ /// The a component value of this .
+ /// The b component value of this .
+ /// The color created from the values.
+ public static Color Create(byte alpha, float l, float a, float b)
+ => Create((float)alpha / byte.MaxValue, l, a, b);
+
+ ///
+ /// Creates a new instance of the struct using alpha and Lab-Values.
+ ///
+ /// The alpha component value of this .
+ /// The L component value of this .
+ /// The a component value of this .
+ /// The b component value of this .
+ /// The color created from the values.
+ public static Color Create(int alpha, float l, float a, float b)
+ => Create((float)alpha / byte.MaxValue, l, a, b);
+
+ ///
+ /// Creates a new instance of the struct using alpha and Lab-Values.
+ ///
+ /// The alpha component value of this .
+ /// The L component value of this .
+ /// The a component value of this .
+ /// The b component value of this .
+ /// The color created from the values.
+ public static Color Create(float alpha, float l, float a, float b)
+ {
+ (float r, float g, float _b) = CalculateRGBFromLab(l, a, b);
+ return new Color(alpha, r, g, _b);
+ }
+
+ #endregion
+
+ #region Helper
+
+ internal static (float l, float a, float b) CalculateLabFromRGB(float r, float g, float b)
+ {
+ (float x, float y, float z) = XYZColor.CaclulateXYZFromRGB(r, g, b);
+ return CaclulateLabFromXYZ(x, y, z);
+ }
+
+ internal static (float r, float g, float b) CalculateRGBFromLab(float l, float a, float b)
+ {
+ (float x, float y, float z) = CalculateXYZFromLab(l, a, b);
+ return XYZColor.CalculateRGBFromXYZ(x, y, z);
+ }
+
+ private static (float l, float a, float b) CaclulateLabFromXYZ(float x, float y, float z)
+ {
+ const float ONETHRID = 1.0f / 3.0f;
+ const float FACTOR2 = 16.0f / 116.0f;
+
+ x /= 95.047f;
+ y /= 100.0f;
+ z /= 108.883f;
+
+ x = ((x > 0.008856f) ? (MathF.Pow(x, ONETHRID)) : ((7.787f * x) + FACTOR2));
+ y = ((y > 0.008856f) ? (MathF.Pow(y, ONETHRID)) : ((7.787f * y) + FACTOR2));
+ z = ((z > 0.008856f) ? (MathF.Pow(z, ONETHRID)) : ((7.787f * z) + FACTOR2));
+
+ float l = (116.0f * y) - 16.0f;
+ float a = 500.0f * (x - y);
+ float b = 200.0f * (y - z);
+
+ return (l, a, b);
+ }
+
+ private static (float x, float y, float z) CalculateXYZFromLab(float l, float a, float b)
+ {
+ const float FACTOR2 = 16.0f / 116.0f;
+
+ float y = (l + 16.0f) / 116.0f;
+ float x = (a / 500.0f) + y;
+ float z = y - (b / 200.0f);
+
+ float powX = MathF.Pow(x, 3.0f);
+ float powY = MathF.Pow(y, 3.0f);
+ float powZ = MathF.Pow(z, 3.0f);
+
+ x = ((powX > 0.008856f) ? (powX) : ((x - FACTOR2) / 7.787f));
+ y = ((powY > 0.008856f) ? (powY) : ((y - FACTOR2) / 7.787f));
+ z = ((powZ > 0.008856f) ? (powZ) : ((z - FACTOR2) / 7.787f));
+
+ return (x * 95.047f, y * 100.0f, z * 108.883f);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs
index edb3e1f..9f4c2cb 100644
--- a/RGB.NET.Core/Color/RGBColor.cs
+++ b/RGB.NET.Core/Color/RGBColor.cs
@@ -13,35 +13,35 @@ namespace RGB.NET.Core
///
///
///
- public static byte GetA(this Color color) => color.A.GetByteValueFromPercentage();
+ public static byte GetA(this in Color color) => color.A.GetByteValueFromPercentage();
///
/// Gets the R component value of this as byte in the range [0..255].
///
///
///
- public static byte GetR(this Color color) => color.R.GetByteValueFromPercentage();
+ public static byte GetR(this in Color color) => color.R.GetByteValueFromPercentage();
///
/// Gets the G component value of this as byte in the range [0..255].
///
///
///
- public static byte GetG(this Color color) => color.G.GetByteValueFromPercentage();
+ public static byte GetG(this in Color color) => color.G.GetByteValueFromPercentage();
///
/// Gets the B component value of this as byte in the range [0..255].
///
///
///
- public static byte GetB(this Color color) => color.B.GetByteValueFromPercentage();
+ public static byte GetB(this in Color color) => color.B.GetByteValueFromPercentage();
///
/// Gets the A, R, G and B component value of this as byte in the range [0..255].
///
///
///
- public static (byte a, byte r, byte g, byte b) GetRGBBytes(this Color color)
+ public static (byte a, byte r, byte g, byte b) GetRGBBytes(this in Color color)
=> (color.GetA(), color.GetR(), color.GetG(), color.GetB());
///
@@ -49,7 +49,7 @@ namespace RGB.NET.Core
///
///
///
- public static (double a, double r, double g, double b) GetRGB(this Color color)
+ public static (float a, float r, float g, float b) GetRGB(this in Color color)
=> (color.A, color.R, color.G, color.B);
#endregion
@@ -65,7 +65,7 @@ namespace RGB.NET.Core
/// The green value to add.
/// The blue value to add.
/// The new color after the modification.
- public static Color AddRGB(this Color color, int r = 0, int g = 0, int b = 0)
+ public static Color AddRGB(this in Color color, int r = 0, int g = 0, int b = 0)
=> new(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b);
///
@@ -75,7 +75,7 @@ namespace RGB.NET.Core
/// The green value to add.
/// The blue value to add.
/// The new color after the modification.
- public static Color AddRGB(this Color color, double r = 0, double g = 0, double b = 0)
+ public static Color AddRGB(this in Color color, float r = 0, float g = 0, float b = 0)
=> new(color.A, color.R + r, color.G + g, color.B + b);
///
@@ -83,7 +83,7 @@ namespace RGB.NET.Core
///
/// The alpha value to add.
/// The new color after the modification.
- public static Color AddA(this Color color, int a)
+ public static Color AddA(this in Color color, int a)
=> new(color.GetA() + a, color.R, color.G, color.B);
///
@@ -91,7 +91,7 @@ namespace RGB.NET.Core
///
/// The alpha value to add.
/// The new color after the modification.
- public static Color AddA(this Color color, double a)
+ public static Color AddA(this in Color color, float a)
=> new(color.A + a, color.R, color.G, color.B);
#endregion
@@ -105,7 +105,7 @@ namespace RGB.NET.Core
/// The green value to subtract.
/// The blue value to subtract.
/// The new color after the modification.
- public static Color SubtractRGB(this Color color, int r = 0, int g = 0, int b = 0)
+ public static Color SubtractRGB(this in Color color, int r = 0, int g = 0, int b = 0)
=> new(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b);
///
@@ -115,7 +115,7 @@ namespace RGB.NET.Core
/// The green value to subtract.
/// The blue value to subtract.
/// The new color after the modification.
- public static Color SubtractRGB(this Color color, double r = 0, double g = 0, double b = 0)
+ public static Color SubtractRGB(this in Color color, float r = 0, float g = 0, float b = 0)
=> new(color.A, color.R - r, color.G - g, color.B - b);
///
@@ -123,7 +123,7 @@ namespace RGB.NET.Core
///
/// The alpha value to subtract.
/// The new color after the modification.
- public static Color SubtractA(this Color color, int a)
+ public static Color SubtractA(this in Color color, int a)
=> new(color.GetA() - a, color.R, color.G, color.B);
///
@@ -131,7 +131,7 @@ namespace RGB.NET.Core
///
/// The alpha value to subtract.
/// The new color after the modification.
- public static Color SubtractA(this Color color, double aPercent)
+ public static Color SubtractA(this in Color color, float aPercent)
=> new(color.A - aPercent, color.R, color.G, color.B);
#endregion
@@ -145,7 +145,7 @@ namespace RGB.NET.Core
/// The green value to multiply.
/// The blue value to multiply.
/// The new color after the modification.
- public static Color MultiplyRGB(this Color color, double r = 1, double g = 1, double b = 1)
+ public static Color MultiplyRGB(this in Color color, float r = 1, float g = 1, float b = 1)
=> new(color.A, color.R * r, color.G * g, color.B * b);
///
@@ -153,7 +153,7 @@ namespace RGB.NET.Core
///
/// The alpha value to multiply.
/// The new color after the modification.
- public static Color MultiplyA(this Color color, double a)
+ public static Color MultiplyA(this in Color color, float a)
=> new(color.A * a, color.R, color.G, color.B);
#endregion
@@ -167,7 +167,7 @@ namespace RGB.NET.Core
/// The green value to divide.
/// The blue value to divide.
/// The new color after the modification.
- public static Color DivideRGB(this Color color, double r = 1, double g = 1, double b = 1)
+ public static Color DivideRGB(this in Color color, float r = 1, float g = 1, float b = 1)
=> new(color.A, color.R / r, color.G / g, color.B / b);
///
@@ -175,7 +175,7 @@ namespace RGB.NET.Core
///
/// The alpha value to divide.
/// The new color after the modification.
- public static Color DivideA(this Color color, double a)
+ public static Color DivideA(this in Color color, float a)
=> new(color.A / a, color.R, color.G, color.B);
#endregion
@@ -189,7 +189,7 @@ namespace RGB.NET.Core
/// The green value to set.
/// The blue value to set.
/// The new color after the modification.
- public static Color SetRGB(this Color color, byte? r = null, byte? g = null, byte? b = null)
+ public static Color SetRGB(this in Color color, byte? r = null, byte? g = null, byte? b = null)
=> new(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB());
///
@@ -199,7 +199,7 @@ namespace RGB.NET.Core
/// The green value to set.
/// The blue value to set.
/// The new color after the modification.
- public static Color SetRGB(this Color color, int? r = null, int? g = null, int? b = null)
+ public static Color SetRGB(this in Color color, int? r = null, int? g = null, int? b = null)
=> new(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB());
///
@@ -209,7 +209,7 @@ namespace RGB.NET.Core
/// The green value to set.
/// The blue value to set.
/// The new color after the modification.
- public static Color SetRGB(this Color color, double? r = null, double? g = null, double? b = null)
+ public static Color SetRGB(this in Color color, float? r = null, float? g = null, float? b = null)
=> new(color.A, r ?? color.R, g ?? color.G, b ?? color.B);
///
@@ -217,14 +217,14 @@ namespace RGB.NET.Core
///
/// The alpha value to set.
/// The new color after the modification.
- public static Color SetA(this Color color, int a) => new(a, color.R, color.G, color.B);
+ public static Color SetA(this in Color color, int a) => new(a, color.R, color.G, color.B);
///
/// Sets the given alpha value of this color.
///
/// The alpha value to set.
/// The new color after the modification.
- public static Color SetA(this Color color, double a) => new(a, color.R, color.G, color.B);
+ public static Color SetA(this in Color color, float a) => new(a, color.R, color.G, color.B);
#endregion
@@ -236,13 +236,13 @@ namespace RGB.NET.Core
/// Gets the current color as a RGB-HEX-string.
///
/// The RGB-HEX-string.
- public static string AsRGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetR(), color.GetG(), color.GetB());
+ public static string AsRGBHexString(this in Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetR(), color.GetG(), color.GetB());
///
/// Gets the current color as a ARGB-HEX-string.
///
/// The ARGB-HEX-string.
- public static string AsARGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetA(), color.GetR(), color.GetG(), color.GetB());
+ public static string AsARGBHexString(this in Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetA(), color.GetR(), color.GetG(), color.GetB());
#endregion
diff --git a/RGB.NET.Core/Color/XYZColor.cs b/RGB.NET.Core/Color/XYZColor.cs
new file mode 100644
index 0000000..d02329e
--- /dev/null
+++ b/RGB.NET.Core/Color/XYZColor.cs
@@ -0,0 +1,200 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable UnusedMember.Global
+using System;
+
+namespace RGB.NET.Core
+{
+ public static class XYZColor
+ {
+ #region Getter
+
+ ///
+ /// Gets the X component value (XYZ-color space) of this in the range [0..95.047].
+ ///
+ ///
+ ///
+ public static float GetX(this in Color color) => color.GetXYZ().x;
+
+ ///
+ /// Gets the Y component value (XYZ-color space) of this in the range [0..100].
+ ///
+ ///
+ ///
+ public static float GetY(this in Color color) => color.GetXYZ().y;
+
+ ///
+ /// Gets the Z component value (XYZ-color space) of this in the range [0..108.883].
+ ///
+ ///
+ ///
+ public static float GetZ(this in Color color) => color.GetXYZ().z;
+
+ ///
+ /// Gets the X, Y and Z component values (XYZ-color space) of this .
+ /// X in the range [0..95.047].
+ /// Y in the range [0..100].
+ /// Z in the range [0..108.883].
+ ///
+ ///
+ ///
+ public static (float x, float y, float z) GetXYZ(this in Color color)
+ => CaclulateXYZFromRGB(color.R, color.G, color.B);
+
+ #endregion
+
+ #region Manipulation
+
+ ///
+ /// Adds the given XYZ values to this color.
+ ///
+ /// The X value to add.
+ /// The Y value to add.
+ /// The Z value to add.
+ /// The new color after the modification.
+ public static Color AddXYZ(this in Color color, float x = 0, float y = 0, float z = 0)
+ {
+ (float cX, float cY, float cZ) = color.GetXYZ();
+ return Create(color.A, cX + x, cY + y, cZ + z);
+ }
+
+ ///
+ /// Subtracts the given XYZ values to this color.
+ ///
+ /// The X value to subtract.
+ /// The Y value to subtract.
+ /// The Z value to subtract.
+ /// The new color after the modification.
+ public static Color SubtractXYZ(this in Color color, float x = 0, float y = 0, float z = 0)
+ {
+ (float cX, float cY, float cZ) = color.GetXYZ();
+ return Create(color.A, cX - x, cY - y, cZ - z);
+ }
+
+ ///
+ /// Multiplies the given XYZ values to this color.
+ ///
+ /// The X value to multiply.
+ /// The Y value to multiply.
+ /// The Z value to multiply.
+ /// The new color after the modification.
+ public static Color MultiplyXYZ(this in Color color, float x = 1, float y = 1, float z = 1)
+ {
+ (float cX, float cY, float cZ) = color.GetXYZ();
+ return Create(color.A, cX * x, cY * y, cZ * z);
+ }
+
+ ///
+ /// Divides the given XYZ values to this color.
+ ///
+ /// The X value to divide.
+ /// The Y value to divide.
+ /// The Z value to divide.
+ /// The new color after the modification.
+ public static Color DivideXYZ(this in Color color, float x = 1, float y = 1, float z = 1)
+ {
+ (float cX, float cY, float cZ) = color.GetXYZ();
+ return Create(color.A, cX / x, cY / y, cZ / z);
+ }
+
+ ///
+ /// Sets the given X valueof this color.
+ ///
+ /// The X value to set.
+ /// The Y value to set.
+ /// The Z value to set.
+ /// The new color after the modification.
+ public static Color SetXYZ(this in Color color, float? x = null, float? y = null, float? value = null)
+ {
+ (float cX, float cY, float cZ) = color.GetXYZ();
+ return Create(color.A, x ?? cX, y ?? cY, value ?? cZ);
+ }
+
+ #endregion
+
+ #region Factory
+
+ ///
+ /// Creates a new instance of the struct using XYZ-Values.
+ ///
+ /// The X component value of this .
+ /// The Y component value of this .
+ /// The Z component value of this .
+ /// The color created from the values.
+ public static Color Create(float x, float y, float z)
+ => Create(1.0f, x, y, z);
+
+ ///
+ /// Creates a new instance of the struct using alpha and XYZ-Values.
+ ///
+ /// The alpha component value of this .
+ /// The X component value of this .
+ /// The Y component value of this .
+ /// The Z component value of this .
+ /// The color created from the values.
+ public static Color Create(byte a, float x, float y, float z)
+ => Create((float)a / byte.MaxValue, x, y, z);
+
+ ///
+ /// Creates a new instance of the struct using alpha and XYZ-Values.
+ ///
+ /// The alpha component value of this .
+ /// The X component value of this .
+ /// The Y component value of this .
+ /// The Z component value of this .
+ /// The color created from the values.
+ public static Color Create(int a, float x, float y, float z)
+ => Create((float)a / byte.MaxValue, x, y, z);
+
+ ///
+ /// Creates a new instance of the struct using alpha and XYZ-Values.
+ ///
+ /// The alpha component value of this .
+ /// The X component value of this .
+ /// The Y component value of this .
+ /// The Z component value of this .
+ /// The color created from the values.
+ public static Color Create(float a, float x, float y, float z)
+ {
+ (float r, float g, float b) = CalculateRGBFromXYZ(x, y, z);
+ return new Color(a, r, g, b);
+ }
+
+ #endregion
+
+ #region Helper
+
+ internal static (float x, float y, float z) CaclulateXYZFromRGB(float r, float g, float b)
+ {
+ r = ((r > 0.04045f) ? MathF.Pow(((r + 0.055f) / 1.055f), 2.4f) : (r / 12.92f)) * 100.0f;
+ g = ((g > 0.04045f) ? MathF.Pow(((g + 0.055f) / 1.055f), 2.4f) : (g / 12.92f)) * 100.0f;
+ b = ((b > 0.04045f) ? MathF.Pow(((b + 0.055f) / 1.055f), 2.4f) : (b / 12.92f)) * 100.0f;
+
+ float x = (r * 0.4124f) + (g * 0.3576f) + (b * 0.1805f);
+ float y = (r * 0.2126f) + (g * 0.7152f) + (b * 0.0722f);
+ float z = (r * 0.0193f) + (g * 0.1192f) + (b * 0.9505f);
+
+ return (x, y, z);
+ }
+
+ internal static (float r, float g, float b) CalculateRGBFromXYZ(float x, float y, float z)
+ {
+ const float INVERSE_EXPONENT = 1.0f / 2.4f;
+
+ x /= 100.0f;
+ y /= 100.0f;
+ z /= 100.0f;
+
+ float r = (x * 3.2406f) + (y * -1.5372f) + (z * -0.4986f);
+ float g = (x * -0.9689f) + (y * 1.8758f) + (z * 0.0415f);
+ float b = (x * 0.0557f) + (y * -0.2040f) + (z * 1.0570f);
+
+ r = ((r > 0.0031308f) ? ((1.055f * (MathF.Pow(r, INVERSE_EXPONENT))) - 0.055f) : (12.92f * r));
+ g = ((g > 0.0031308f) ? ((1.055f * (MathF.Pow(g, INVERSE_EXPONENT))) - 0.055f) : (12.92f * g));
+ b = ((b > 0.0031308f) ? ((1.055f * (MathF.Pow(b, INVERSE_EXPONENT))) - 0.055f) : (12.92f * b));
+
+ return (r, g, b);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/ColorCorrection/IColorCorrection.cs b/RGB.NET.Core/ColorCorrection/IColorCorrection.cs
index e3e417a..f738f5a 100644
--- a/RGB.NET.Core/ColorCorrection/IColorCorrection.cs
+++ b/RGB.NET.Core/ColorCorrection/IColorCorrection.cs
@@ -11,6 +11,6 @@ namespace RGB.NET.Core
/// Applies the to the given .
///
/// The to correct.
- Color ApplyTo(Color color);
+ void ApplyTo(ref Color color);
}
}
diff --git a/RGB.NET.Core/Decorators/IBrushDecorator.cs b/RGB.NET.Core/Decorators/IBrushDecorator.cs
index 812af24..f7dca23 100644
--- a/RGB.NET.Core/Decorators/IBrushDecorator.cs
+++ b/RGB.NET.Core/Decorators/IBrushDecorator.cs
@@ -12,6 +12,6 @@
/// The rectangle in which the should be drawn.
/// The target (key/point) from which the should be taken.
/// The to be modified.
- Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color);
+ void ManipulateColor(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color);
}
}
diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs
index b88a3dc..db8dba1 100644
--- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs
+++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs
@@ -34,11 +34,14 @@ namespace RGB.NET.Core
}
///
- public abstract TDeviceInfo DeviceInfo { get; }
+ public TDeviceInfo DeviceInfo { get; }
///
IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo;
+ ///
+ public IList ColorCorrections { get; } = new List();
+
///
/// Gets or sets if the device needs to be flushed on every update.
///
@@ -49,6 +52,8 @@ namespace RGB.NET.Core
///
protected Dictionary LedMapping { get; } = new();
+ protected IUpdateQueue UpdateQueue { get; }
+
#region Indexer
///
@@ -65,6 +70,16 @@ namespace RGB.NET.Core
#endregion
+ #region Constructors
+
+ protected AbstractRGBDevice(TDeviceInfo deviceOnfo, IUpdateQueue updateQueue)
+ {
+ this.DeviceInfo = deviceOnfo;
+ this.UpdateQueue = updateQueue;
+ }
+
+ #endregion
+
#region Methods
///
@@ -75,22 +90,51 @@ namespace RGB.NET.Core
// Send LEDs to SDK
List ledsToUpdate = GetLedsToUpdate(flushLeds).ToList();
- foreach (Led ledToUpdate in ledsToUpdate)
- ledToUpdate.Update();
+
+ foreach (Led led in ledsToUpdate)
+ led.Update();
UpdateLeds(ledsToUpdate);
}
- protected virtual IEnumerable GetLedsToUpdate(bool flushLeds) => ((RequiresFlush || flushLeds) ? LedMapping.Values : LedMapping.Values.Where(x => x.IsDirty));
+ protected virtual IEnumerable GetLedsToUpdate(bool flushLeds) => ((RequiresFlush || flushLeds) ? LedMapping.Values : LedMapping.Values.Where(x => x.IsDirty)).Where(led => led.RequestedColor?.A > 0);
+ protected virtual IEnumerable<(object key, Color color)> GetUpdateData(IEnumerable leds)
+ {
+ if (ColorCorrections.Count > 0)
+ {
+ foreach (Led led in leds)
+ {
+ Color color = led.Color;
+ object key = led.CustomData ?? led.Id;
+
+ foreach (IColorCorrection colorCorrection in ColorCorrections)
+ colorCorrection.ApplyTo(ref color);
+
+ yield return (key, color);
+ }
+ }
+ else
+ {
+ foreach (Led led in leds)
+ {
+ Color color = led.Color;
+ object key = led.CustomData ?? led.Id;
+
+ yield return (key, color);
+ }
+ }
+ }
+
+ ///
+ /// Sends all the updated to the device.
+ ///
+ protected virtual void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
///
public virtual void Dispose()
{
- try
- {
- LedMapping.Clear();
- }
- catch { /* this really shouldn't happen */ }
+ try { UpdateQueue.Dispose(); } catch { /* :( */ }
+ try { LedMapping.Clear(); } catch { /* this really shouldn't happen */ }
}
///
@@ -99,11 +143,6 @@ namespace RGB.NET.Core
protected virtual void DeviceUpdate()
{ }
- ///
- /// Sends all the updated to the device.
- ///
- protected abstract void UpdateLeds(IEnumerable ledsToUpdate);
-
///
/// Initializes the with the specified id.
///
@@ -111,7 +150,7 @@ namespace RGB.NET.Core
/// The location of the to initialize.
/// The size of the to initialize.
/// The initialized led.
- public virtual Led? AddLed(LedId ledId, Point location, Size size, object? customData = null)
+ public virtual Led? AddLed(LedId ledId, in Point location, in Size size, object? customData = null)
{
if ((ledId == LedId.Invalid) || LedMapping.ContainsKey(ledId)) return null;
diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs
new file mode 100644
index 0000000..630bf09
--- /dev/null
+++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs
@@ -0,0 +1,121 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+
+namespace RGB.NET.Core
+{
+ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider
+ {
+ #region Properties & Fields
+
+ private readonly double _defaultUpdateRateHardLimit;
+
+ public bool IsInitialized { get; protected set; }
+ public bool ThrowsExceptions { get; protected set; }
+
+ public virtual IEnumerable Devices { get; protected set; } = Enumerable.Empty();
+
+ protected Dictionary UpdateTriggers { get; } = new();
+
+ #endregion
+
+ #region Events
+
+ public event EventHandler? Exception;
+
+ #endregion
+
+ #region Constructors
+
+ protected AbstractRGBDeviceProvider(double defaultUpdateRateHardLimit = 0)
+ {
+ this._defaultUpdateRateHardLimit = defaultUpdateRateHardLimit;
+ }
+
+ #endregion
+
+ #region Methods
+
+ public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ {
+ ThrowsExceptions = throwExceptions;
+
+ try
+ {
+ Reset();
+
+ InitializeSDK();
+
+ Devices = new ReadOnlyCollection(GetLoadedDevices(loadFilter).ToList());
+
+ foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggers.Values)
+ updateTrigger.Start();
+
+ IsInitialized = true;
+ }
+ catch (Exception ex)
+ {
+ Reset();
+ Throw(ex);
+ return false;
+ }
+
+ return true;
+ }
+
+ protected virtual IEnumerable GetLoadedDevices(RGBDeviceType loadFilter)
+ {
+ foreach (IRGBDevice device in LoadDevices())
+ {
+ if (loadFilter.HasFlag(device.DeviceInfo.DeviceType))
+ yield return device;
+ else
+ device.Dispose();
+ }
+ }
+
+ protected abstract void InitializeSDK();
+
+ protected abstract IEnumerable LoadDevices();
+
+ protected virtual IDeviceUpdateTrigger GetUpdateTrigger(int id = -1, double? updateRateHardLimit = null)
+ {
+ if (!UpdateTriggers.TryGetValue(id, out IDeviceUpdateTrigger? updaeTrigger))
+ UpdateTriggers[id] = (updaeTrigger = CreateUpdateTrigger(id, updateRateHardLimit ?? _defaultUpdateRateHardLimit));
+
+ return updaeTrigger;
+ }
+
+ protected virtual IDeviceUpdateTrigger CreateUpdateTrigger(int id, double updateRateHardLimit) => new DeviceUpdateTrigger(updateRateHardLimit);
+
+ protected virtual void Reset()
+ {
+ foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggers.Values)
+ updateTrigger.Dispose();
+
+ Devices = Enumerable.Empty();
+ IsInitialized = false;
+ }
+
+ protected virtual void Throw(Exception ex)
+ {
+ try { OnException(ex); } catch { /* we don't want to throw due to bad event handlers */ }
+
+ if (ThrowsExceptions)
+ throw ex;
+ }
+
+ protected virtual void OnException(Exception ex) => Exception?.Invoke(this, ex);
+
+ public virtual void Dispose()
+ {
+ IEnumerable devices = Devices;
+ Reset();
+ foreach (IRGBDevice device in devices)
+ device.Dispose();
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Devices/IRGBDevice.cs b/RGB.NET.Core/Devices/IRGBDevice.cs
index 15d607e..983d54d 100644
--- a/RGB.NET.Core/Devices/IRGBDevice.cs
+++ b/RGB.NET.Core/Devices/IRGBDevice.cs
@@ -19,7 +19,9 @@ namespace RGB.NET.Core
/// Gets generic information about the .
///
IRGBDeviceInfo DeviceInfo { get; }
-
+
+ IList ColorCorrections { get; }
+
#endregion
#region Indexer
@@ -56,7 +58,7 @@ namespace RGB.NET.Core
/// Specifies whether all (including clean ones) should be updated.
void Update(bool flushLeds = false);
- Led? AddLed(LedId ledId, Point location, Size size, object? customData = null);
+ Led? AddLed(LedId ledId, in Point location, in Size size, object? customData = null);
Led? RemoveLed(LedId ledId);
diff --git a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs
index 6060feb..afa4ab0 100644
--- a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs
+++ b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs
@@ -22,6 +22,15 @@ namespace RGB.NET.Core
#endregion
+ #region Events
+
+ ///
+ /// Occurs when an exception is thrown in the device provider
+ ///
+ event EventHandler? Exception;
+
+ #endregion
+
#region Methods
bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false);
diff --git a/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs b/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs
index 64a91df..e591385 100644
--- a/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs
+++ b/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs
@@ -2,7 +2,6 @@
// ReSharper disable UnusedAutoPropertyAccessor.Global
using System;
-using System.Collections.Generic;
namespace RGB.NET.Core
{
diff --git a/RGB.NET.Core/Extensions/ColorExtensions.cs b/RGB.NET.Core/Extensions/ColorExtensions.cs
index 15d0c80..b905baf 100644
--- a/RGB.NET.Core/Extensions/ColorExtensions.cs
+++ b/RGB.NET.Core/Extensions/ColorExtensions.cs
@@ -13,7 +13,7 @@ namespace RGB.NET.Core
/// The start color of the distance calculation.
/// The end color fot the distance calculation.
///
- public static double DistanceTo(this Color color1, Color color2)
+ public static double DistanceTo(this in Color color1, in Color color2)
{
(_, byte r1, byte g1, byte b1) = color1.GetRGBBytes();
(_, byte r2, byte g2, byte b2) = color2.GetRGBBytes();
diff --git a/RGB.NET.Core/Extensions/MathExtensions.cs b/RGB.NET.Core/Extensions/MathExtensions.cs
index 0a9fb88..ad098bf 100644
--- a/RGB.NET.Core/Extensions/MathExtensions.cs
+++ b/RGB.NET.Core/Extensions/MathExtensions.cs
@@ -4,16 +4,16 @@ using System.Runtime.CompilerServices;
namespace RGB.NET.Core
{
///
- /// Offers some extensions and helper-methods for the work with doubles
+ /// Offers some extensions and helper-methods for the work with floats
///
- public static class DoubleExtensions
+ public static class FloatExtensions
{
#region Constants
///
/// Defines the precision RGB.NET processes floating point comparisons in.
///
- public const double TOLERANCE = 1E-10;
+ public const float TOLERANCE = 1E-7f;
#endregion
@@ -26,7 +26,7 @@ namespace RGB.NET.Core
/// The first value to compare.
/// true if the difference is smaller than the ; otherwise, false.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool EqualsInTolerance(this double value1, double value2) => Math.Abs(value1 - value2) < TOLERANCE;
+ public static bool EqualsInTolerance(this float value1, float value2) => Math.Abs(value1 - value2) < TOLERANCE;
///
/// Clamps the provided value to be bigger or equal min and smaller or equal max.
@@ -36,7 +36,7 @@ namespace RGB.NET.Core
/// The higher value of the range the value is clamped to.
/// The clamped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double Clamp(this double value, double min, double max)
+ public static float Clamp(this float value, float min, float max)
{
// ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10%
if (value < min) return min;
@@ -70,9 +70,9 @@ namespace RGB.NET.Core
/// The higher value of the range the value is wrapped into.
/// The wrapped value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double Wrap(this double value, double min, double max)
+ public static float Wrap(this float value, float min, float max)
{
- double range = max - min;
+ float range = max - min;
while (value >= max)
value -= range;
@@ -84,17 +84,17 @@ namespace RGB.NET.Core
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static byte GetByteValueFromPercentage(this double percentage)
+ public static byte GetByteValueFromPercentage(this float percentage)
{
- if (double.IsNaN(percentage)) return 0;
+ if (float.IsNaN(percentage)) return 0;
- percentage = percentage.Clamp(0, 1.0);
+ percentage = percentage.Clamp(0, 1.0f);
return (byte)(percentage >= 1.0 ? 255 : percentage * 256.0);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double GetPercentageFromByteValue(this byte value)
- => ((double)value) / byte.MaxValue;
+ public static float GetPercentageFromByteValue(this byte value)
+ => ((float)value) / byte.MaxValue;
#endregion
}
diff --git a/RGB.NET.Core/Extensions/PointExtensions.cs b/RGB.NET.Core/Extensions/PointExtensions.cs
index 9766bf3..cdc04f7 100644
--- a/RGB.NET.Core/Extensions/PointExtensions.cs
+++ b/RGB.NET.Core/Extensions/PointExtensions.cs
@@ -13,7 +13,7 @@ namespace RGB.NET.Core
/// The x-ammount to move.
/// The y-ammount to move.
/// The new location of the point.
- public static Point Translate(this Point point, double x = 0, double y = 0) => new(point.X + x, point.Y + y);
+ public static Point Translate(this in Point point, float x = 0, float y = 0) => new(point.X + x, point.Y + y);
///
/// Rotates the specified by the given amuont around the given origin.
@@ -22,14 +22,18 @@ namespace RGB.NET.Core
/// The rotation.
/// The origin to rotate around. [0,0] if not set.
/// The new location of the point.
- public static Point Rotate(this Point point, Rotation rotation, Point origin = new())
+ public static Point Rotate(this in Point point, in Rotation rotation, in Point origin = new())
{
- double sin = Math.Sin(rotation.Radians);
- double cos = Math.Cos(rotation.Radians);
+ float sin = MathF.Sin(rotation.Radians);
+ float cos = MathF.Cos(rotation.Radians);
- point = new Point(point.X - origin.X, point.Y - origin.Y);
- point = new Point((point.X * cos) - (point.Y * sin), (point.X * sin) + (point.Y * cos));
- return new Point(point.X + origin.X, point.Y + origin.Y); ;
+ float x = point.X - origin.X;
+ float y = point.Y - origin.Y;
+
+ x = (x * cos) - (y * sin);
+ y = (x * sin) + (y * cos);
+
+ return new Point(x + origin.X, y + origin.Y); ;
}
#endregion
diff --git a/RGB.NET.Core/Extensions/RectangleExtensions.cs b/RGB.NET.Core/Extensions/RectangleExtensions.cs
index de09fc0..ce5745e 100644
--- a/RGB.NET.Core/Extensions/RectangleExtensions.cs
+++ b/RGB.NET.Core/Extensions/RectangleExtensions.cs
@@ -12,7 +12,7 @@ namespace RGB.NET.Core
/// The rectangle to modify.
/// The new location of the rectangle.
/// The modified .
- public static Rectangle SetLocation(this Rectangle rect, Point location) => new(location, rect.Size);
+ public static Rectangle SetLocation(this in Rectangle rect, in Point location) => new(location, rect.Size);
///
/// Sets the of the of the given rectangle.
@@ -20,7 +20,7 @@ namespace RGB.NET.Core
/// The rectangle to modify.
/// The new x-location of the rectangle.
/// The modified .
- public static Rectangle SetX(this Rectangle rect, double x) => new(new Point(x, rect.Location.Y), rect.Size);
+ public static Rectangle SetX(this in Rectangle rect, float x) => new(new Point(x, rect.Location.Y), rect.Size);
///
/// Sets the of the of the given rectangle.
@@ -28,7 +28,7 @@ namespace RGB.NET.Core
/// The rectangle to modify.
/// The new y-location of the rectangle.
/// The modified .
- public static Rectangle SetY(this Rectangle rect, double y) => new(new Point(rect.Location.X, y), rect.Size);
+ public static Rectangle SetY(this in Rectangle rect, float y) => new(new Point(rect.Location.X, y), rect.Size);
///
/// Sets the of the given rectangle.
@@ -36,7 +36,7 @@ namespace RGB.NET.Core
/// The rectangle to modify.
/// The new size of the rectangle.
/// The modified .
- public static Rectangle SetSize(this Rectangle rect, Size size) => new(rect.Location, size);
+ public static Rectangle SetSize(this in Rectangle rect, in Size size) => new(rect.Location, size);
///
/// Sets the of the of the given rectangle.
@@ -44,7 +44,7 @@ namespace RGB.NET.Core
/// The rectangle to modify.
/// The new width of the rectangle.
/// The modified .
- public static Rectangle SetWidth(this Rectangle rect, double width) => new(rect.Location, new Size(width, rect.Size.Height));
+ public static Rectangle SetWidth(this in Rectangle rect, float width) => new(rect.Location, new Size(width, rect.Size.Height));
///
/// Sets the of the of the given rectangle.
@@ -52,14 +52,14 @@ namespace RGB.NET.Core
/// The rectangle to modify.
/// The new height of the rectangle.
/// The modified .
- public static Rectangle SetHeight(this Rectangle rect, double height) => new(rect.Location, new Size(rect.Size.Width, height));
+ public static Rectangle SetHeight(this in Rectangle rect, float height) => new(rect.Location, new Size(rect.Size.Width, height));
///
/// Calculates the percentage of intersection of a rectangle.
///
/// The intersecting rectangle.
/// The percentage of intersection.
- public static double CalculateIntersectPercentage(this Rectangle rect, Rectangle intersectingRect)
+ public static float CalculateIntersectPercentage(this in Rectangle rect, in Rectangle intersectingRect)
{
if (rect.IsEmpty || intersectingRect.IsEmpty) return 0;
@@ -72,13 +72,13 @@ namespace RGB.NET.Core
///
/// The intersecting
/// A new representing the intersection this and the one provided as parameter.
- public static Rectangle CalculateIntersection(this Rectangle rect, Rectangle intersectingRectangle)
+ public static Rectangle CalculateIntersection(this in Rectangle rect, in Rectangle intersectingRectangle)
{
- double x1 = Math.Max(rect.Location.X, intersectingRectangle.Location.X);
- double x2 = Math.Min(rect.Location.X + rect.Size.Width, intersectingRectangle.Location.X + intersectingRectangle.Size.Width);
+ float x1 = Math.Max(rect.Location.X, intersectingRectangle.Location.X);
+ float x2 = Math.Min(rect.Location.X + rect.Size.Width, intersectingRectangle.Location.X + intersectingRectangle.Size.Width);
- double y1 = Math.Max(rect.Location.Y, intersectingRectangle.Location.Y);
- double y2 = Math.Min(rect.Location.Y + rect.Size.Height, intersectingRectangle.Location.Y + intersectingRectangle.Size.Height);
+ float y1 = Math.Max(rect.Location.Y, intersectingRectangle.Location.Y);
+ float y2 = Math.Min(rect.Location.Y + rect.Size.Height, intersectingRectangle.Location.Y + intersectingRectangle.Size.Height);
if ((x2 >= x1) && (y2 >= y1))
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
@@ -91,7 +91,7 @@ namespace RGB.NET.Core
///
/// The to test.
/// true if the rectangle contains the given point; otherwise false.
- public static bool Contains(this Rectangle rect, Point point) => rect.Contains(point.X, point.Y);
+ public static bool Contains(this in Rectangle rect, in Point point) => rect.Contains(point.X, point.Y);
///
/// Determines if the specified location is contained within this .
@@ -99,7 +99,7 @@ namespace RGB.NET.Core
/// The X-location to test.
/// The Y-location to test.
/// true if the rectangle contains the given coordinates; otherwise false.
- public static bool Contains(this Rectangle rect, double x, double y) => (rect.Location.X <= x) && (x < (rect.Location.X + rect.Size.Width))
+ public static bool Contains(this in Rectangle rect, float x, float y) => (rect.Location.X <= x) && (x < (rect.Location.X + rect.Size.Width))
&& (rect.Location.Y <= y) && (y < (rect.Location.Y + rect.Size.Height));
///
@@ -107,7 +107,7 @@ namespace RGB.NET.Core
///
/// The to test.
/// true if the rectangle contains the given rect; otherwise false.
- public static bool Contains(this Rectangle rect, Rectangle rect2) => (rect.Location.X <= rect2.Location.X) && ((rect2.Location.X + rect2.Size.Width) <= (rect.Location.X + rect.Size.Width))
+ public static bool Contains(this in Rectangle rect, in Rectangle rect2) => (rect.Location.X <= rect2.Location.X) && ((rect2.Location.X + rect2.Size.Width) <= (rect.Location.X + rect.Size.Width))
&& (rect.Location.Y <= rect2.Location.Y) && ((rect2.Location.Y + rect2.Size.Height) <= (rect.Location.Y + rect.Size.Height));
///
@@ -116,7 +116,7 @@ namespace RGB.NET.Core
/// The to move.
/// The amount to move.
/// The moved rectangle.
- public static Rectangle Translate(this Rectangle rect, Point point) => rect.Translate(point.X, point.Y);
+ public static Rectangle Translate(this in Rectangle rect, in Point point) => rect.Translate(point.X, point.Y);
///
/// Moves the specified by the given amount.
@@ -125,7 +125,7 @@ namespace RGB.NET.Core
/// The x-ammount to move.
/// The y-ammount to move.
/// The moved rectangle.
- public static Rectangle Translate(this Rectangle rect, double x = 0, double y = 0) => new(rect.Location.Translate(x, y), rect.Size);
+ public static Rectangle Translate(this in Rectangle rect, float x = 0, float y = 0) => new(rect.Location.Translate(x, y), rect.Size);
///
/// Rotates the specified by the given amuont around the given origin.
@@ -141,7 +141,7 @@ namespace RGB.NET.Core
/// The rotation.
/// The origin to rotate around. [0,0] if not set.
/// A array of containing the new locations of the corners of the original rectangle.
- public static Point[] Rotate(this Rectangle rect, Rotation rotation, Point origin = new())
+ public static Point[] Rotate(this in Rectangle rect, in Rotation rotation, in Point origin = new())
{
Point[] points = {
rect.Location, // top left
@@ -150,8 +150,8 @@ namespace RGB.NET.Core
new(rect.Location.X, rect.Location.Y + rect.Size.Height), // bottom right
};
- double sin = Math.Sin(rotation.Radians);
- double cos = Math.Cos(rotation.Radians);
+ float sin = MathF.Sin(rotation.Radians);
+ float cos = MathF.Cos(rotation.Radians);
for (int i = 0; i < points.Length; i++)
{
diff --git a/RGB.NET.Core/Extensions/SurfaceExtensions.cs b/RGB.NET.Core/Extensions/SurfaceExtensions.cs
new file mode 100644
index 0000000..fb53fc0
--- /dev/null
+++ b/RGB.NET.Core/Extensions/SurfaceExtensions.cs
@@ -0,0 +1,65 @@
+// ReSharper disable UnusedMember.Global
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace RGB.NET.Core
+{
+ public static class SurfaceExtensions
+ {
+ #region Methods
+
+ public static void Load(this RGBSurface surface, IRGBDeviceProvider deviceProvider, RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ {
+ if (!deviceProvider.IsInitialized)
+ deviceProvider.Initialize(loadFilter, throwExceptions);
+
+ surface.Attach(deviceProvider.Devices);
+ }
+
+
+ public static void Attach(this RGBSurface surface, IEnumerable devices)
+ {
+ foreach (IRGBDevice device in devices)
+ surface.Attach(device);
+ }
+
+ public static void Detach(this RGBSurface surface, IEnumerable devices)
+ {
+ foreach (IRGBDevice device in devices)
+ surface.Detach(device);
+ }
+
+ ///
+ /// Gets all devices of a specific type.
+ ///
+ /// The type of devices to get.
+ /// A collection of devices with the specified type.
+ public static IEnumerable GetDevices(this RGBSurface surface)
+ where T : class
+ => surface.Devices.Where(x => x is T).Cast();
+
+ ///
+ /// Gets all devices of the specified .
+ ///
+ /// The of the devices to get.
+ /// A collection of devices matching the specified .
+ public static IEnumerable GetDevices(this RGBSurface surface, RGBDeviceType deviceType)
+ => surface.Devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType));
+
+ ///
+ /// Automatically aligns all devices to prevent overlaps.
+ ///
+ public static void AlignDevices(this RGBSurface surface)
+ {
+ float posX = 0;
+ foreach (IRGBDevice device in surface.Devices)
+ {
+ device.Location += new Point(posX, 0);
+ posX += device.ActualSize.Width + 1;
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Groups/AbstractLedGroup.cs b/RGB.NET.Core/Groups/AbstractLedGroup.cs
index 3720302..c035937 100644
--- a/RGB.NET.Core/Groups/AbstractLedGroup.cs
+++ b/RGB.NET.Core/Groups/AbstractLedGroup.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System.Collections;
+using System.Collections.Generic;
namespace RGB.NET.Core
{
@@ -11,7 +12,8 @@ namespace RGB.NET.Core
{
#region Properties & Fields
- public RGBSurface? Surface { get; private set; }
+ RGBSurface? ILedGroup.Surface { get; set; }
+ public RGBSurface? Surface => ((ILedGroup)this).Surface;
///
public IBrush? Brush { get; set; }
@@ -28,21 +30,26 @@ namespace RGB.NET.Core
///
protected AbstractLedGroup(RGBSurface? attachTo)
{
- attachTo?.AttachLedGroup(this);
+ attachTo?.Attach(this);
}
#endregion
#region Methods
- ///
- public abstract IList GetLeds();
+ protected abstract IEnumerable GetLeds();
///
- public virtual void OnAttach(RGBSurface surface) => Surface = surface;
+ public virtual void OnAttach() { }
///
- public virtual void OnDetach(RGBSurface surface) => Surface = null;
+ public virtual void OnDetach() { }
+
+ ///
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ ///
+ public IEnumerator GetEnumerator() => GetLeds().GetEnumerator();
#endregion
}
diff --git a/RGB.NET.Core/Groups/ILedGroup.cs b/RGB.NET.Core/Groups/ILedGroup.cs
index 3985f8a..adcf9b7 100644
--- a/RGB.NET.Core/Groups/ILedGroup.cs
+++ b/RGB.NET.Core/Groups/ILedGroup.cs
@@ -5,13 +5,14 @@ using System.Collections.Generic;
namespace RGB.NET.Core
{
- ///
///
/// Represents a generic ledgroup.
///
- public interface ILedGroup : IDecoratable
+ public interface ILedGroup : IDecoratable, IEnumerable
{
- public RGBSurface? Surface { get; }
+ RGBSurface? Surface { get; internal set; }
+
+ bool IsAttached => Surface != null;
///
/// Gets or sets the which should be drawn over this .
@@ -23,20 +24,14 @@ namespace RGB.NET.Core
///
int ZIndex { get; set; }
- ///
- /// Gets a list containing all of this .
- ///
- /// The list containing all of this .
- IList GetLeds();
-
///
/// Called when the is attached to the .
///
- void OnAttach(RGBSurface surface);
+ void OnAttach();
///
/// Called when the is detached from the .
///
- void OnDetach(RGBSurface surface);
+ void OnDetach();
}
}
diff --git a/RGB.NET.Groups/Extensions/LedGroupExtension.cs b/RGB.NET.Core/Groups/LedGroupExtension.cs
similarity index 84%
rename from RGB.NET.Groups/Extensions/LedGroupExtension.cs
rename to RGB.NET.Core/Groups/LedGroupExtension.cs
index 4391131..3d29d4c 100644
--- a/RGB.NET.Groups/Extensions/LedGroupExtension.cs
+++ b/RGB.NET.Core/Groups/LedGroupExtension.cs
@@ -1,9 +1,7 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
-using RGB.NET.Core;
-
-namespace RGB.NET.Groups
+namespace RGB.NET.Core
{
///
/// Offers some extensions and helper-methods for related things.
@@ -18,11 +16,11 @@ namespace RGB.NET.Groups
public static ListLedGroup ToListLedGroup(this ILedGroup ledGroup)
{
// ReSharper disable once InvertIf
- if (!(ledGroup is ListLedGroup listLedGroup))
+ if (ledGroup is not ListLedGroup listLedGroup)
{
- if (ledGroup.Surface != null)
- ledGroup.Detach(ledGroup.Surface);
- listLedGroup = new ListLedGroup(ledGroup.Surface, ledGroup.GetLeds()) { Brush = ledGroup.Brush };
+ if (ledGroup.IsAttached)
+ ledGroup.Detach();
+ listLedGroup = new ListLedGroup(ledGroup.Surface, ledGroup) { Brush = ledGroup.Brush, ZIndex = ledGroup.ZIndex };
}
return listLedGroup;
}
@@ -47,13 +45,13 @@ namespace RGB.NET.Groups
///
/// The to attach.
/// true if the could be attached; otherwise, false.
- public static bool Attach(this ILedGroup ledGroup, RGBSurface surface) => surface.AttachLedGroup(ledGroup);
+ public static bool Attach(this ILedGroup ledGroup, RGBSurface surface) => surface.Attach(ledGroup);
///
/// Detaches the given from the .
///
/// The to attach.
/// true if the could be detached; otherwise, false.
- public static bool Detach(this ILedGroup ledGroup, RGBSurface surface) => surface.DetachLedGroup(ledGroup);
+ public static bool Detach(this ILedGroup ledGroup) => ledGroup.Surface?.Detach(ledGroup) ?? false;
}
}
diff --git a/RGB.NET.Groups/Groups/ListLedGroup.cs b/RGB.NET.Core/Groups/ListLedGroup.cs
similarity index 97%
rename from RGB.NET.Groups/Groups/ListLedGroup.cs
rename to RGB.NET.Core/Groups/ListLedGroup.cs
index 06d15b8..b6be55b 100644
--- a/RGB.NET.Groups/Groups/ListLedGroup.cs
+++ b/RGB.NET.Core/Groups/ListLedGroup.cs
@@ -2,9 +2,8 @@
// ReSharper disable UnusedMember.Global
using System.Collections.Generic;
-using RGB.NET.Core;
-namespace RGB.NET.Groups
+namespace RGB.NET.Core
{
///
///
@@ -114,7 +113,7 @@ namespace RGB.NET.Groups
public void MergeLeds(ILedGroup groupToMerge)
{
lock (GroupLeds)
- foreach (Led led in groupToMerge.GetLeds())
+ foreach (Led led in groupToMerge)
if (!GroupLeds.Contains(led))
GroupLeds.Add(led);
}
@@ -124,7 +123,7 @@ namespace RGB.NET.Groups
/// Gets a list containing the from this group.
///
/// The list containing the .
- public override IList GetLeds()
+ protected override IEnumerable GetLeds()
{
lock (GroupLeds)
return new List(GroupLeds);
diff --git a/RGB.NET.Core/Leds/Led.cs b/RGB.NET.Core/Leds/Led.cs
index 7c39c45..33ea3da 100644
--- a/RGB.NET.Core/Leds/Led.cs
+++ b/RGB.NET.Core/Leds/Led.cs
@@ -151,18 +151,6 @@ namespace RGB.NET.Core
OnPropertyChanged(nameof(Color));
}
- ///
- /// Resets the back to default.
- ///
- internal void Reset()
- {
- _color = Color.Transparent;
- RequestedColor = null;
-
- // ReSharper disable once ExplicitCallerInfoArgument
- OnPropertyChanged(nameof(Color));
- }
-
#endregion
#region Operators
diff --git a/RGB.NET.Core/Positioning/Point.cs b/RGB.NET.Core/Positioning/Point.cs
index d546994..5f04a76 100644
--- a/RGB.NET.Core/Positioning/Point.cs
+++ b/RGB.NET.Core/Positioning/Point.cs
@@ -13,10 +13,11 @@ namespace RGB.NET.Core
{
#region Constants
+ private static readonly Point INVALID = new(float.NaN, float.NaN);
///
/// Gets a [NaN,NaN]-Point.
///
- public static Point Invalid => new(double.NaN, double.NaN);
+ public static ref readonly Point Invalid => ref INVALID;
#endregion
@@ -25,12 +26,12 @@ namespace RGB.NET.Core
///
/// Gets the X-position of this .
///
- public double X { get; }
+ public float X { get; }
///
/// Gets the Y-position of this .
///
- public double Y { get; }
+ public float Y { get; }
#endregion
@@ -41,7 +42,7 @@ namespace RGB.NET.Core
///
/// The value used for the X-position.
/// The value used for the Y-position.
- public Point(double x, double y)
+ public Point(float x, float y)
{
this.X = x;
this.Y = y;
@@ -67,8 +68,8 @@ namespace RGB.NET.Core
if (!(obj is Point)) return false;
Point comparePoint = (Point)obj;
- return ((double.IsNaN(X) && double.IsNaN(comparePoint.X)) || X.EqualsInTolerance(comparePoint.X))
- && ((double.IsNaN(Y) && double.IsNaN(comparePoint.Y)) || Y.EqualsInTolerance(comparePoint.Y));
+ return ((float.IsNaN(X) && float.IsNaN(comparePoint.X)) || X.EqualsInTolerance(comparePoint.X))
+ && ((float.IsNaN(Y) && float.IsNaN(comparePoint.Y)) || Y.EqualsInTolerance(comparePoint.Y));
}
///
@@ -95,7 +96,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are equal; otherwise, false.
- public static bool operator ==(Point point1, Point point2) => point1.Equals(point2);
+ public static bool operator ==(in Point point1, in Point point2) => point1.Equals(point2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -103,7 +104,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are not equal; otherwise, false.
- public static bool operator !=(Point point1, Point point2) => !(point1 == point2);
+ public static bool operator !=(in Point point1, in Point point2) => !(point1 == point2);
///
/// Returns a new representing the addition of the two provided .
@@ -111,7 +112,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the addition of the two provided .
- public static Point operator +(Point point1, Point point2) => new(point1.X + point2.X, point1.Y + point2.Y);
+ public static Point operator +(in Point point1, in Point point2) => new(point1.X + point2.X, point1.Y + point2.Y);
///
/// Returns a new created from the provided and .
@@ -119,7 +120,7 @@ namespace RGB.NET.Core
/// The of the rectangle.
/// The of the rectangle.
/// The rectangle created from the provided and .
- public static Rectangle operator +(Point point, Size size) => new(point, size);
+ public static Rectangle operator +(in Point point, in Size size) => new(point, size);
///
/// Returns a new representing the subtraction of the two provided .
@@ -127,7 +128,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the subtraction of the two provided .
- public static Point operator -(Point point1, Point point2) => new(point1.X - point2.X, point1.Y - point2.Y);
+ public static Point operator -(in Point point1, in Point point2) => new(point1.X - point2.X, point1.Y - point2.Y);
///
/// Returns a new representing the multiplication of the two provided .
@@ -135,7 +136,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the multiplication of the two provided .
- public static Point operator *(Point point1, Point point2) => new(point1.X * point2.X, point1.Y * point2.Y);
+ public static Point operator *(in Point point1, in Point point2) => new(point1.X * point2.X, point1.Y * point2.Y);
///
/// Returns a new representing the division of the two provided .
@@ -143,7 +144,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the division of the two provided .
- public static Point operator /(Point point1, Point point2)
+ public static Point operator /(in Point point1, in Point point2)
{
if (point2.X.EqualsInTolerance(0) || point2.Y.EqualsInTolerance(0)) return Invalid;
return new Point(point1.X / point2.X, point1.Y / point2.Y);
@@ -155,7 +156,7 @@ namespace RGB.NET.Core
/// The .
/// The .
/// A new representing the multiplication of the and the provided .
- public static Point operator *(Point point, Scale scale) => new(point.X * scale.Horizontal, point.Y * scale.Vertical);
+ public static Point operator *(in Point point, in Scale scale) => new(point.X * scale.Horizontal, point.Y * scale.Vertical);
#endregion
}
diff --git a/RGB.NET.Core/Positioning/Rectangle.cs b/RGB.NET.Core/Positioning/Rectangle.cs
index cbf80ab..3c545e6 100644
--- a/RGB.NET.Core/Positioning/Rectangle.cs
+++ b/RGB.NET.Core/Positioning/Rectangle.cs
@@ -35,7 +35,7 @@ namespace RGB.NET.Core
/// Gets a bool indicating if both, the width and the height of the rectangle is greater than zero.
/// True if the rectangle has a width or a height of zero; otherwise, false.
///
- public bool IsEmpty => (Size.Width <= DoubleExtensions.TOLERANCE) || (Size.Height <= DoubleExtensions.TOLERANCE);
+ public bool IsEmpty => (Size.Width <= FloatExtensions.TOLERANCE) || (Size.Height <= FloatExtensions.TOLERANCE);
#endregion
@@ -49,7 +49,7 @@ namespace RGB.NET.Core
/// The y-value of the -position of this .
/// The width of the of this .
/// The height of the of this .
- public Rectangle(double x, double y, double width, double height)
+ public Rectangle(float x, float y, float width, float height)
: this(new Point(x, y), new Size(width, height))
{ }
@@ -70,7 +70,7 @@ namespace RGB.NET.Core
this.Location = location;
this.Size = size;
- Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0));
+ Center = new Point(Location.X + (Size.Width / 2.0f), Location.Y + (Size.Height / 2.0f));
}
///
@@ -91,10 +91,10 @@ namespace RGB.NET.Core
public Rectangle(IEnumerable rectangles)
{
bool hasPoint = false;
- double posX = double.MaxValue;
- double posY = double.MaxValue;
- double posX2 = double.MinValue;
- double posY2 = double.MinValue;
+ float posX = float.MaxValue;
+ float posY = float.MaxValue;
+ float posX2 = float.MinValue;
+ float posY2 = float.MinValue;
foreach (Rectangle rectangle in rectangles)
{
@@ -108,7 +108,7 @@ namespace RGB.NET.Core
(Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0));
Location = location;
Size = size;
- Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0));
+ Center = new Point(Location.X + (Size.Width / 2.0f), Location.Y + (Size.Height / 2.0f));
}
///
@@ -131,10 +131,10 @@ namespace RGB.NET.Core
: this()
{
bool hasPoint = false;
- double posX = double.MaxValue;
- double posY = double.MaxValue;
- double posX2 = double.MinValue;
- double posY2 = double.MinValue;
+ float posX = float.MaxValue;
+ float posY = float.MaxValue;
+ float posX2 = float.MinValue;
+ float posY2 = float.MinValue;
foreach (Point point in points)
{
@@ -149,19 +149,19 @@ namespace RGB.NET.Core
Location = location;
Size = size;
- Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0));
+ Center = new Point(Location.X + (Size.Width / 2.0f), Location.Y + (Size.Height / 2.0f));
}
#endregion
#region Methods
- private static (Point location, Size size) InitializeFromPoints(Point point1, Point point2)
+ private static (Point location, Size size) InitializeFromPoints(in Point point1, in Point point2)
{
- double posX = Math.Min(point1.X, point2.X);
- double posY = Math.Min(point1.Y, point2.Y);
- double width = Math.Max(point1.X, point2.X) - posX;
- double height = Math.Max(point1.Y, point2.Y) - posY;
+ float posX = Math.Min(point1.X, point2.X);
+ float posY = Math.Min(point1.Y, point2.Y);
+ float width = Math.Max(point1.X, point2.X) - posX;
+ float height = Math.Max(point1.Y, point2.Y) - posY;
return (new Point(posX, posY), new Size(width, height));
}
@@ -179,7 +179,7 @@ namespace RGB.NET.Core
/// true if is a equivalent to this ; otherwise, false.
public override bool Equals(object? obj)
{
- if (!(obj is Rectangle compareRect))
+ if (obj is not Rectangle compareRect)
return false;
if (GetType() != compareRect.GetType())
@@ -212,7 +212,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are equal; otherwise, false.
- public static bool operator ==(Rectangle rectangle1, Rectangle rectangle2) => rectangle1.Equals(rectangle2);
+ public static bool operator ==(in Rectangle rectangle1, in Rectangle rectangle2) => rectangle1.Equals(rectangle2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -220,7 +220,16 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are not equal; otherwise, false.
- public static bool operator !=(Rectangle rectangle1, Rectangle rectangle2) => !(rectangle1 == rectangle2);
+ public static bool operator !=(in Rectangle rectangle1, in Rectangle rectangle2) => !(rectangle1 == rectangle2);
+
+ // DarthAffe 20.02.2021: Used for normalization
+ public static Rectangle operator /(in Rectangle rectangle1, in Rectangle rectangle2)
+ {
+ float x = rectangle1.Location.X / (rectangle2.Size.Width - rectangle2.Location.X);
+ float y = rectangle1.Location.Y / (rectangle2.Size.Height - rectangle2.Location.Y);
+ Size size = rectangle1.Size / rectangle2.Size;
+ return new Rectangle(new Point(x, y), size);
+ }
#endregion
}
diff --git a/RGB.NET.Core/Positioning/Rotation.cs b/RGB.NET.Core/Positioning/Rotation.cs
index 623f64a..39a5315 100644
--- a/RGB.NET.Core/Positioning/Rotation.cs
+++ b/RGB.NET.Core/Positioning/Rotation.cs
@@ -14,9 +14,9 @@ namespace RGB.NET.Core
{
#region Constants
- private const double TWO_PI = Math.PI * 2.0;
- private const double RADIANS_DEGREES_CONVERSION = 180.0 / Math.PI;
- private const double DEGREES_RADIANS_CONVERSION = Math.PI / 180.0;
+ private const float TWO_PI = MathF.PI * 2.0f;
+ private const float RADIANS_DEGREES_CONVERSION = 180.0f / MathF.PI;
+ private const float DEGREES_RADIANS_CONVERSION = MathF.PI / 180.0f;
#endregion
@@ -25,12 +25,12 @@ namespace RGB.NET.Core
///
/// Gets the angle in degrees.
///
- public double Degrees { get; }
+ public float Degrees { get; }
///
/// Gets the angle in radians.
///
- public double Radians { get; }
+ public float Radians { get; }
///
/// Gets a bool indicating if the rotation is > 0.
@@ -45,13 +45,13 @@ namespace RGB.NET.Core
/// Initializes a new instance of the class using the provided values.
///
/// The rotation in degrees.
- public Rotation(double degrees)
+ public Rotation(float degrees)
: this(degrees, degrees * DEGREES_RADIANS_CONVERSION)
{ }
- private Rotation(double degrees, double radians)
+ private Rotation(float degrees, float radians)
{
- this.Degrees = degrees % 360.0;
+ this.Degrees = degrees % 360.0f;
this.Radians = radians % TWO_PI;
}
@@ -64,14 +64,14 @@ namespace RGB.NET.Core
///
/// The angle in degrees.
/// The new rotation.
- public static Rotation FromDegrees(double degrees) => new(degrees);
+ public static Rotation FromDegrees(float degrees) => new(degrees);
///
/// Creates a new Rotation out of the given radian-angle.
///
/// The angle in radians.
/// The new rotation.
- public static Rotation FromRadians(double radians) => new(radians * RADIANS_DEGREES_CONVERSION, radians);
+ public static Rotation FromRadians(float radians) => new(radians * RADIANS_DEGREES_CONVERSION, radians);
///
/// Tests whether the specified is equivalent to this .
@@ -103,7 +103,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are equal; otherwise, false.
- public static bool operator ==(Rotation rotation1, Rotation rotation2) => rotation1.Equals(rotation2);
+ public static bool operator ==(in Rotation rotation1, in Rotation rotation2) => rotation1.Equals(rotation2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -111,7 +111,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are not equal; otherwise, false.
- public static bool operator !=(Rotation rotation1, Rotation rotation2) => !(rotation1 == rotation2);
+ public static bool operator !=(in Rotation rotation1, in Rotation rotation2) => !(rotation1 == rotation2);
///
/// Returns a new representing the addition of the and the provided value.
@@ -119,7 +119,7 @@ namespace RGB.NET.Core
/// The .
/// The value to add.
/// A new representing the addition of the and the provided value.
- public static Rotation operator +(Rotation rotation, double value) => new(rotation.Degrees + value);
+ public static Rotation operator +(in Rotation rotation, float value) => new(rotation.Degrees + value);
///
/// Returns a new representing the subtraction of the and the provided value.
@@ -127,7 +127,7 @@ namespace RGB.NET.Core
/// The .
/// The value to substract.
/// A new representing the subtraction of the and the provided value.
- public static Rotation operator -(Rotation rotation, double value) => new(rotation.Degrees - value);
+ public static Rotation operator -(in Rotation rotation, float value) => new(rotation.Degrees - value);
///
/// Returns a new representing the multiplication of the and the provided value.
@@ -135,7 +135,7 @@ namespace RGB.NET.Core
/// The .
/// The value to multiply with.
/// A new representing the multiplication of the and the provided value.
- public static Rotation operator *(Rotation rotation, double value) => new(rotation.Degrees * value);
+ public static Rotation operator *(in Rotation rotation, float value) => new(rotation.Degrees * value);
///
/// Returns a new representing the division of the and the provided value.
@@ -143,19 +143,19 @@ namespace RGB.NET.Core
/// The .
/// The value to device with.
/// A new representing the division of the and the provided value.
- public static Rotation operator /(Rotation rotation, double value) => value.EqualsInTolerance(0) ? new Rotation(0) : new Rotation(rotation.Degrees / value);
+ public static Rotation operator /(in Rotation rotation, float value) => value.EqualsInTolerance(0) ? new Rotation(0) : new Rotation(rotation.Degrees / value);
///
- /// Converts a double to a .
+ /// Converts a float to a .
///
/// The rotation in degrees to convert.
- public static implicit operator Rotation(double rotation) => new(rotation);
+ public static implicit operator Rotation(float rotation) => new(rotation);
///
- /// Converts to a double representing the rotation in degrees.
+ /// Converts to a float representing the rotation in degrees.
///
/// The rotatio to convert.
- public static implicit operator double(Rotation rotation) => rotation.Degrees;
+ public static implicit operator float(in Rotation rotation) => rotation.Degrees;
#endregion
}
diff --git a/RGB.NET.Core/Positioning/Scale.cs b/RGB.NET.Core/Positioning/Scale.cs
index b12af17..1923bf7 100644
--- a/RGB.NET.Core/Positioning/Scale.cs
+++ b/RGB.NET.Core/Positioning/Scale.cs
@@ -16,12 +16,12 @@ namespace RGB.NET.Core
///
/// Gets the horizontal scaling value.
///
- public double Horizontal { get; }
+ public float Horizontal { get; }
///
/// Gets the vertical scaling value.
///
- public double Vertical { get; }
+ public float Vertical { get; }
#endregion
@@ -31,7 +31,7 @@ namespace RGB.NET.Core
/// Initializes a new instance of the class using the provided values.
///
/// The value used for horizontal and vertical scaling. 0 if not set.
- public Scale(double scale = 1.0) : this(scale, scale)
+ public Scale(float scale = 1.0f) : this(scale, scale)
{ }
///
@@ -39,7 +39,7 @@ namespace RGB.NET.Core
///
/// The value used for horizontal scaling.
/// The value used for vertical scaling.
- public Scale(double horizontal, double vertical)
+ public Scale(float horizontal, float vertical)
{
this.Horizontal = horizontal;
this.Vertical = vertical;
@@ -74,7 +74,7 @@ namespace RGB.NET.Core
///
/// The horizontal scaling value.
/// The vertical scaling value.
- public void Deconstruct(out double horizontalScale, out double verticalScale)
+ public void Deconstruct(out float horizontalScale, out float verticalScale)
{
horizontalScale = Horizontal;
verticalScale = Vertical;
@@ -106,7 +106,7 @@ namespace RGB.NET.Core
/// The .
/// The value to add.
/// A new representing the addition of the and the provided value.
- public static Scale operator +(Scale scale, double value) => new(scale.Horizontal + value, scale.Vertical + value);
+ public static Scale operator +(Scale scale, float value) => new(scale.Horizontal + value, scale.Vertical + value);
///
/// Returns a new representing the subtraction of the and the provided value.
@@ -114,7 +114,7 @@ namespace RGB.NET.Core
/// The .
/// The value to substract.
/// A new representing the subtraction of the and the provided value.
- public static Scale operator -(Scale scale, double value) => new(scale.Horizontal - value, scale.Vertical - value);
+ public static Scale operator -(Scale scale, float value) => new(scale.Horizontal - value, scale.Vertical - value);
///
/// Returns a new representing the multiplication of the and the provided value.
@@ -122,7 +122,7 @@ namespace RGB.NET.Core
/// The .
/// The value to multiply with.
/// A new representing the multiplication of the and the provided value.
- public static Scale operator *(Scale scale, double value) => new(scale.Horizontal * value, scale.Vertical * value);
+ public static Scale operator *(Scale scale, float value) => new(scale.Horizontal * value, scale.Vertical * value);
///
/// Returns a new representing the division of the and the provided value.
@@ -130,14 +130,14 @@ namespace RGB.NET.Core
/// The .
/// The value to device with.
/// A new representing the division of the and the provided value.
- public static Scale operator /(Scale scale, double value) => value.EqualsInTolerance(0) ? new Scale(0) : new Scale(scale.Horizontal / value, scale.Vertical / value);
+ public static Scale operator /(Scale scale, float value) => value.EqualsInTolerance(0) ? new Scale(0) : new Scale(scale.Horizontal / value, scale.Vertical / value);
///
- /// Converts a double to a .
+ /// Converts a float to a .
///
/// The scale value to convert.
- public static implicit operator Scale(double scale) => new(scale);
+ public static implicit operator Scale(float scale) => new(scale);
#endregion
}
diff --git a/RGB.NET.Core/Positioning/Size.cs b/RGB.NET.Core/Positioning/Size.cs
index 7ed7887..3a8c279 100644
--- a/RGB.NET.Core/Positioning/Size.cs
+++ b/RGB.NET.Core/Positioning/Size.cs
@@ -13,10 +13,11 @@ namespace RGB.NET.Core
{
#region Constants
+ private static readonly Size INVALID = new(float.NaN, float.NaN);
///
/// Gets a [NaN,NaN]-Size.
///
- public static Size Invalid => new(double.NaN, double.NaN);
+ public static ref readonly Size Invalid => ref INVALID;
#endregion
@@ -25,12 +26,12 @@ namespace RGB.NET.Core
///
/// Gets or sets the width component value of this .
///
- public double Width { get; }
+ public float Width { get; }
///
/// Gets or sets the height component value of this .
///
- public double Height { get; }
+ public float Height { get; }
#endregion
@@ -41,7 +42,7 @@ namespace RGB.NET.Core
/// Initializes a new instance of the using the provided size to define a square.
///
/// The size used for the component value and the component value.
- public Size(double size)
+ public Size(float size)
: this(size, size)
{ }
@@ -50,7 +51,7 @@ namespace RGB.NET.Core
///
/// The size used for the component value.
/// The size used for the component value.
- public Size(double width, double height)
+ public Size(float width, float height)
{
this.Width = width;
this.Height = height;
@@ -75,9 +76,9 @@ namespace RGB.NET.Core
{
if (!(obj is Size size)) return false;
- (double width, double height) = size;
- return ((double.IsNaN(Width) && double.IsNaN(width)) || Width.EqualsInTolerance(width))
- && ((double.IsNaN(Height) && double.IsNaN(height)) || Height.EqualsInTolerance(height));
+ (float width, float height) = size;
+ return ((float.IsNaN(Width) && float.IsNaN(width)) || Width.EqualsInTolerance(width))
+ && ((float.IsNaN(Height) && float.IsNaN(height)) || Height.EqualsInTolerance(height));
}
///
@@ -99,7 +100,7 @@ namespace RGB.NET.Core
///
/// The width.
/// The height.
- public void Deconstruct(out double width, out double height)
+ public void Deconstruct(out float width, out float height)
{
width = Width;
height = Height;
@@ -115,7 +116,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are equal; otherwise, false.
- public static bool operator ==(Size size1, Size size2) => size1.Equals(size2);
+ public static bool operator ==(in Size size1, in Size size2) => size1.Equals(size2);
///
/// Returns a value that indicates whether two specified are equal.
@@ -123,7 +124,7 @@ namespace RGB.NET.Core
/// The first to compare.
/// The second to compare.
/// true if and are not equal; otherwise, false.
- public static bool operator !=(Size size1, Size size2) => !(size1 == size2);
+ public static bool operator !=(in Size size1, in Size size2) => !(size1 == size2);
///
/// Returns a new representing the addition of the two provided .
@@ -131,7 +132,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the addition of the two provided .
- public static Size operator +(Size size1, Size size2) => new(size1.Width + size2.Width, size1.Height + size2.Height);
+ public static Size operator +(in Size size1, in Size size2) => new(size1.Width + size2.Width, size1.Height + size2.Height);
///
/// Returns a new created from the provided and .
@@ -139,7 +140,7 @@ namespace RGB.NET.Core
/// The of the rectangle.
/// The of the rectangle.
/// The rectangle created from the provided and .
- public static Rectangle operator +(Size size, Point point) => new(point, size);
+ public static Rectangle operator +(in Size size, in Point point) => new(point, size);
///
/// Returns a new representing the subtraction of the two provided .
@@ -147,7 +148,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the subtraction of the two provided .
- public static Size operator -(Size size1, Size size2) => new(size1.Width - size2.Width, size1.Height - size2.Height);
+ public static Size operator -(in Size size1, in Size size2) => new(size1.Width - size2.Width, size1.Height - size2.Height);
///
/// Returns a new representing the multiplication of the two provided .
@@ -155,7 +156,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the multiplication of the two provided .
- public static Size operator *(Size size1, Size size2) => new(size1.Width * size2.Width, size1.Height * size2.Height);
+ public static Size operator *(in Size size1, in Size size2) => new(size1.Width * size2.Width, size1.Height * size2.Height);
///
/// Returns a new representing the multiplication of the and the provided factor.
@@ -163,7 +164,7 @@ namespace RGB.NET.Core
/// The .
/// The factor by which the should be multiplied.
/// A new representing the multiplication of the and the provided factor.
- public static Size operator *(Size size, double factor) => new(size.Width * factor, size.Height * factor);
+ public static Size operator *(in Size size, float factor) => new(size.Width * factor, size.Height * factor);
///
/// Returns a new representing the division of the two provided .
@@ -171,7 +172,7 @@ namespace RGB.NET.Core
/// The first .
/// The second .
/// A new representing the division of the two provided .
- public static Size operator /(Size size1, Size size2)
+ public static Size operator /(in Size size1, in Size size2)
=> size2.Width.EqualsInTolerance(0) || size2.Height.EqualsInTolerance(0)
? Invalid : new Size(size1.Width / size2.Width, size1.Height / size2.Height);
@@ -181,7 +182,7 @@ namespace RGB.NET.Core
/// The .
/// The factor by which the should be divided.
/// A new representing the division of the and the provided factor.
- public static Size operator /(Size size, double factor) => factor.EqualsInTolerance(0) ? Invalid : new Size(size.Width / factor, size.Height / factor);
+ public static Size operator /(in Size size, float factor) => factor.EqualsInTolerance(0) ? Invalid : new Size(size.Width / factor, size.Height / factor);
///
/// Returns a new representing the multiplication of the and the given .
@@ -189,7 +190,7 @@ namespace RGB.NET.Core
/// The to scale.
/// The scaling factor.
/// A new representing the multiplication of the and the given .
- public static Size operator *(Size size, Scale scale) => new(size.Width * scale.Horizontal, size.Height * scale.Vertical);
+ public static Size operator *(in Size size, in Scale scale) => new(size.Width * scale.Horizontal, size.Height * scale.Vertical);
#endregion
}
diff --git a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings
index 8f59663..59c26c0 100644
--- a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings
+++ b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings
@@ -17,6 +17,10 @@
True
True
True
+ True
+ True
+ True
+ True
True
True
True
\ No newline at end of file
diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs
index e45f0f9..692e158 100644
--- a/RGB.NET.Core/RGBSurface.cs
+++ b/RGB.NET.Core/RGBSurface.cs
@@ -14,20 +14,15 @@ namespace RGB.NET.Core
///
/// Represents a RGB-surface containing multiple devices.
///
- public class RGBSurface : AbstractBindable, IDisposable
+ public sealed class RGBSurface : AbstractBindable, IDisposable
{
#region Properties & Fields
private Stopwatch _deltaTimeCounter;
- private IList _devices = new List();
- private IList _updateTriggers = new List();
-
- // ReSharper disable InconsistentNaming
-
- private readonly LinkedList _ledGroups = new();
-
- // ReSharper restore InconsistentNaming
+ private readonly IList _devices = new List();
+ private readonly IList _updateTriggers = new List();
+ private readonly List _ledGroups = new List();
///
/// Gets a readonly list containing all loaded .
@@ -160,7 +155,7 @@ namespace RGB.NET.Core
lock (_ledGroups)
{
// Render brushes
- foreach (ILedGroup ledGroup in _ledGroups.OrderBy(x => x.ZIndex))
+ foreach (ILedGroup ledGroup in _ledGroups)
try { Render(ledGroup); }
catch (Exception ex) { OnException(ex); }
}
@@ -201,33 +196,32 @@ namespace RGB.NET.Core
/// Renders a ledgroup.
///
/// The led group to render.
+ /// Thrown if the of the Brush is not valid.
private void Render(ILedGroup ledGroup)
{
- IList leds = ledGroup.GetLeds().ToList();
+ IList leds = ledGroup.ToList();
IBrush? brush = ledGroup.Brush;
if ((brush == null) || !brush.IsEnabled) return;
- switch (brush.BrushCalculationMode)
+ IEnumerable<(RenderTarget renderTarget, Color color)> render;
+ switch (brush.CalculationMode)
{
- case BrushCalculationMode.Relative:
+ case RenderMode.Relative:
Rectangle brushRectangle = new(leds.Select(led => led.AbsoluteBoundary));
Point offset = new(-brushRectangle.Location.X, -brushRectangle.Location.Y);
brushRectangle = brushRectangle.SetLocation(new Point(0, 0));
- brush.PerformRender(brushRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteBoundary.Translate(offset))));
+ render = brush.Render(brushRectangle, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary.Translate(offset))));
break;
- case BrushCalculationMode.Absolute:
- brush.PerformRender(Boundary, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteBoundary)));
+ case RenderMode.Absolute:
+ render = brush.Render(Boundary, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary)));
break;
default:
- throw new ArgumentException();
+ throw new ArgumentException($"The CalculationMode '{brush.CalculationMode}' is not valid.");
}
- //brush.UpdateEffects();
- brush.PerformFinalize();
-
- foreach (KeyValuePair renders in brush.RenderedTargets)
- renders.Key.Led.Color = renders.Value;
+ foreach ((RenderTarget renderTarget, Color c) in render)
+ renderTarget.Led.Color = c;
}
///
@@ -235,14 +229,16 @@ namespace RGB.NET.Core
///
/// The to attach.
/// true if the could be attached; otherwise, false.
- public bool AttachLedGroup(ILedGroup ledGroup)
+ public bool Attach(ILedGroup ledGroup)
{
lock (_ledGroups)
{
- if (_ledGroups.Contains(ledGroup)) return false;
+ if (ledGroup.Surface != null) return false;
- _ledGroups.AddLast(ledGroup);
- ledGroup.OnAttach(this);
+ ledGroup.Surface = this;
+ _ledGroups.Add(ledGroup);
+ _ledGroups.Sort((group1, group2) => group1.ZIndex.CompareTo(group2.ZIndex));
+ ledGroup.OnAttach();
return true;
}
@@ -253,29 +249,18 @@ namespace RGB.NET.Core
///
/// The to detached.
/// true if the could be detached; otherwise, false.
- public bool DetachLedGroup(ILedGroup ledGroup)
+ public bool Detach(ILedGroup ledGroup)
{
lock (_ledGroups)
{
- LinkedListNode? node = _ledGroups.Find(ledGroup);
- if (node == null) return false;
-
- _ledGroups.Remove(node);
- node.Value.OnDetach(this);
+ if (!_ledGroups.Remove(ledGroup)) return false;
+ ledGroup.OnDetach();
+ ledGroup.Surface = null;
return true;
}
}
- public void Attach(IEnumerable devices)
- {
- lock (_devices)
- {
- foreach (IRGBDevice device in devices)
- Attach(device);
- }
- }
-
public void Attach(IRGBDevice device)
{
lock (_devices)
@@ -290,20 +275,11 @@ namespace RGB.NET.Core
}
}
- public void Detach(IEnumerable devices)
- {
- lock (_devices)
- {
- foreach (IRGBDevice device in devices)
- Detach(device);
- }
- }
-
public void Detach(IRGBDevice device)
{
lock (_devices)
{
- if (!_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' isn't not attached to this surface.");
+ if (!_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' is not attached to this surface.");
device.BoundaryChanged -= DeviceOnBoundaryChanged;
device.Surface = null;
@@ -314,19 +290,6 @@ namespace RGB.NET.Core
}
}
- ///
- /// Automatically aligns all devices to prevent overlaps.
- ///
- public void AlignDevices()
- {
- double posX = 0;
- foreach (IRGBDevice device in Devices)
- {
- device.Location += new Point(posX, 0);
- posX += device.ActualSize.Width + 1;
- }
- }
-
// ReSharper restore UnusedMember.Global
private void DeviceOnBoundaryChanged(object? sender, EventArgs args)
@@ -348,29 +311,6 @@ namespace RGB.NET.Core
}
}
- ///
- /// Gets all devices of a specific type.
- ///
- /// The type of devices to get.
- /// A list of devices with the specified type.
- public IList GetDevices()
- where T : class
- {
- lock (_devices)
- return new ReadOnlyCollection(_devices.Where(x => x is T).Cast().ToList());
- }
-
- ///
- /// Gets all devices of the specified .
- ///
- /// The of the devices to get.
- /// a list of devices matching the specified .
- public IList GetDevices(RGBDeviceType deviceType)
- {
- lock (_devices)
- return new ReadOnlyCollection(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList());
- }
-
///
/// Registers the provided .
///
diff --git a/RGB.NET.Core/Brushes/AbstractBrush.cs b/RGB.NET.Core/Rendering/Brushes/AbstractBrush.cs
similarity index 59%
rename from RGB.NET.Core/Brushes/AbstractBrush.cs
rename to RGB.NET.Core/Rendering/Brushes/AbstractBrush.cs
index 541b6ac..e4d7274 100644
--- a/RGB.NET.Core/Brushes/AbstractBrush.cs
+++ b/RGB.NET.Core/Rendering/Brushes/AbstractBrush.cs
@@ -3,7 +3,6 @@
// ReSharper disable VirtualMemberNeverOverridden.Global
using System.Collections.Generic;
-using System.Linq;
namespace RGB.NET.Core
{
@@ -20,22 +19,13 @@ namespace RGB.NET.Core
public bool IsEnabled { get; set; } = true;
///
- public BrushCalculationMode BrushCalculationMode { get; set; } = BrushCalculationMode.Relative;
+ public RenderMode CalculationMode { get; set; } = RenderMode.Relative;
///
- public double Brightness { get; set; }
+ public float Brightness { get; set; }
///
- public double Opacity { get; set; }
-
- ///
- public IList ColorCorrections { get; } = new List();
-
- ///
- public Rectangle RenderedRectangle { get; protected set; }
-
- ///
- public Dictionary RenderedTargets { get; } = new();
+ public float Opacity { get; set; }
#endregion
@@ -46,7 +36,7 @@ namespace RGB.NET.Core
///
/// The overall percentage brightness of the brush. (default: 1.0)
/// The overall percentage opacity of the brush. (default: 1.0)
- protected AbstractBrush(double brightness = 1, double opacity = 1)
+ protected AbstractBrush(float brightness = 1, float opacity = 1)
{
this.Brightness = brightness;
this.Opacity = opacity;
@@ -56,17 +46,14 @@ namespace RGB.NET.Core
#region Methods
- ///
- public virtual void PerformRender(Rectangle rectangle, IEnumerable renderTargets)
+ public virtual IEnumerable<(RenderTarget renderTarget, Color color)> Render(Rectangle rectangle, IEnumerable renderTargets)
{
- RenderedRectangle = rectangle;
- RenderedTargets.Clear();
-
- foreach (BrushRenderTarget renderTarget in renderTargets)
+ foreach (RenderTarget renderTarget in renderTargets)
{
Color color = GetColorAtPoint(rectangle, renderTarget);
- color = ApplyDecorators(rectangle, renderTarget, color);
- RenderedTargets[renderTarget] = color;
+ ApplyDecorators(rectangle, renderTarget, ref color);
+ FinalizeColor(ref color);
+ yield return (renderTarget, color);
}
}
@@ -76,22 +63,14 @@ namespace RGB.NET.Core
/// The rectangle in which the brush should be drawn.
/// The target (key/point) from which the color should be taken.
/// The to be modified.
- protected virtual Color ApplyDecorators(Rectangle rectangle, BrushRenderTarget renderTarget, Color color)
+ protected virtual void ApplyDecorators(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color)
{
+ if (Decorators.Count == 0) return;
+
lock (Decorators)
foreach (IBrushDecorator decorator in Decorators)
if (decorator.IsEnabled)
- color = decorator.ManipulateColor(rectangle, renderTarget, color);
-
- return color;
- }
-
- ///
- public virtual void PerformFinalize()
- {
- List renderTargets = RenderedTargets.Keys.ToList();
- foreach (BrushRenderTarget renderTarget in renderTargets)
- RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]);
+ decorator.ManipulateColor(rectangle, renderTarget, ref color);
}
///
@@ -100,20 +79,15 @@ namespace RGB.NET.Core
/// The rectangle in which the brush should be drawn.
/// The target (key/point) from which the color should be taken.
/// The color at the specified point.
- protected abstract Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget);
+ protected abstract Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget);
///
/// Finalizes the color by appliing the overall brightness and opacity.
- /// This method should always be the last call of a implementation.
///
/// The color to finalize.
/// The finalized color.
- protected virtual Color FinalizeColor(Color color)
+ protected virtual void FinalizeColor(ref Color color)
{
- if (ColorCorrections.Count > 0)
- foreach (IColorCorrection colorCorrection in ColorCorrections)
- color = colorCorrection.ApplyTo(color);
-
// Since we use HSV to calculate there is no way to make a color 'brighter' than 100%
// Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness'
// THIS IS NOT A HSB CALCULATION!!!
@@ -122,8 +96,6 @@ namespace RGB.NET.Core
if (Opacity < 1)
color = color.MultiplyA(Opacity.Clamp(0, 1));
-
- return color;
}
#endregion
diff --git a/RGB.NET.Core/Rendering/Brushes/IBrush.cs b/RGB.NET.Core/Rendering/Brushes/IBrush.cs
new file mode 100644
index 0000000..f2509af
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Brushes/IBrush.cs
@@ -0,0 +1,41 @@
+// ReSharper disable UnusedMemberInSuper.Global
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ReturnTypeCanBeEnumerable.Global
+
+using System.Collections.Generic;
+
+namespace RGB.NET.Core
+{
+ ///
+ /// Represents a basic brush.
+ ///
+ public interface IBrush : IDecoratable
+ {
+ ///
+ /// Gets or sets if the is enabled and will be drawn on an update.
+ ///
+ bool IsEnabled { get; set; }
+
+ ///
+ /// Gets or sets the calculation mode used for the rectangle/points used for color-selection in brushes.
+ ///
+ RenderMode CalculationMode { get; set; }
+
+ ///
+ /// Gets or sets the overall percentage brightness of the .
+ ///
+ float Brightness { get; set; }
+
+ ///
+ /// Gets or sets the overall percentage opacity of the .
+ ///
+ float Opacity { get; set; }
+
+ ///
+ /// Performs the render pass of the and calculates the raw for all requested .
+ ///
+ /// The in which the brush should be drawn.
+ /// The (keys/points) of which the color should be calculated.
+ IEnumerable<(RenderTarget renderTarget, Color color)> Render(Rectangle rectangle, IEnumerable renderTargets);
+ }
+}
\ No newline at end of file
diff --git a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs b/RGB.NET.Core/Rendering/Brushes/SolidColorBrush.cs
similarity index 81%
rename from RGB.NET.Brushes/Brushes/SolidColorBrush.cs
rename to RGB.NET.Core/Rendering/Brushes/SolidColorBrush.cs
index 8bbd68b..aaf9409 100644
--- a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs
+++ b/RGB.NET.Core/Rendering/Brushes/SolidColorBrush.cs
@@ -1,9 +1,7 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
-using RGB.NET.Core;
-
-namespace RGB.NET.Brushes
+namespace RGB.NET.Core
{
///
///
@@ -29,9 +27,9 @@ namespace RGB.NET.Brushes
///
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- /// The drawn by this .
+ /// The drawn by this .
public SolidColorBrush(Color color)
{
this.Color = color;
@@ -42,7 +40,7 @@ namespace RGB.NET.Brushes
#region Methods
///
- protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget) => Color;
+ protected override Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget) => Color;
#endregion
diff --git a/RGB.NET.Core/Rendering/Brushes/TextureBrush.cs b/RGB.NET.Core/Rendering/Brushes/TextureBrush.cs
new file mode 100644
index 0000000..2ec8f05
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Brushes/TextureBrush.cs
@@ -0,0 +1,35 @@
+namespace RGB.NET.Core
+{
+ public class TextureBrush : AbstractBrush
+ {
+ #region Properties & Fields
+
+ private ITexture _texture = ITexture.Empty;
+ public ITexture Texture
+ {
+ get => _texture;
+ set => SetProperty(ref _texture, value);
+ }
+
+ #endregion
+
+ #region Constructors
+
+ public TextureBrush(ITexture texture)
+ {
+ this.Texture = texture;
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget)
+ {
+ Rectangle normalizedRect = renderTarget.Rectangle / rectangle;
+ return Texture[normalizedRect];
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Brushes/BrushCalculationMode.cs b/RGB.NET.Core/Rendering/RenderMode.cs
similarity index 79%
rename from RGB.NET.Core/Brushes/BrushCalculationMode.cs
rename to RGB.NET.Core/Rendering/RenderMode.cs
index 310f563..8908d69 100644
--- a/RGB.NET.Core/Brushes/BrushCalculationMode.cs
+++ b/RGB.NET.Core/Rendering/RenderMode.cs
@@ -5,7 +5,7 @@ namespace RGB.NET.Core
///
/// Contains a list of all brush calculation modes.
///
- public enum BrushCalculationMode
+ public enum RenderMode
{
///
/// The calculation for will be the rectangle around the the is applied to.
@@ -13,7 +13,7 @@ namespace RGB.NET.Core
Relative,
///
- /// The calculation for will always be the rectangle completly containing all affected .
+ /// The calculation for will always be the whole .
///
Absolute
}
diff --git a/RGB.NET.Core/Brushes/BrushRenderTarget.cs b/RGB.NET.Core/Rendering/RenderTarget.cs
similarity index 81%
rename from RGB.NET.Core/Brushes/BrushRenderTarget.cs
rename to RGB.NET.Core/Rendering/RenderTarget.cs
index e4934e8..4d41827 100644
--- a/RGB.NET.Core/Brushes/BrushRenderTarget.cs
+++ b/RGB.NET.Core/Rendering/RenderTarget.cs
@@ -6,7 +6,7 @@ namespace RGB.NET.Core
///
/// Represents a single target of a brush render.
///
- public class BrushRenderTarget
+ public readonly struct RenderTarget
{
#region Properties & Fields
@@ -23,23 +23,21 @@ namespace RGB.NET.Core
///
/// Gets the representing the position to render the target-.
///
- public Point Point { get; }
+ public Point Point => Rectangle.Center;
#endregion
#region Constructors
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The target-.
/// The representing the area to render the target-.
- public BrushRenderTarget(Led led, Rectangle rectangle)
+ public RenderTarget(Led led, Rectangle rectangle)
{
this.Led = led;
this.Rectangle = rectangle;
-
- this.Point = rectangle.Center;
}
#endregion
diff --git a/RGB.NET.Core/Rendering/Textures/EmptyTexture.cs b/RGB.NET.Core/Rendering/Textures/EmptyTexture.cs
new file mode 100644
index 0000000..2998eeb
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Textures/EmptyTexture.cs
@@ -0,0 +1,13 @@
+namespace RGB.NET.Core
+{
+ internal class EmptyTexture : ITexture
+ {
+ #region Properties & Fields
+
+ public Size Size { get; } = new(0, 0);
+ public Color this[in Point point] => Color.Transparent;
+ public Color this[in Rectangle rectangle] => Color.Transparent;
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Rendering/Textures/ITexture.cs b/RGB.NET.Core/Rendering/Textures/ITexture.cs
new file mode 100644
index 0000000..7d297e1
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Textures/ITexture.cs
@@ -0,0 +1,12 @@
+namespace RGB.NET.Core
+{
+ public interface ITexture
+ {
+ static ITexture Empty => new EmptyTexture();
+
+ Size Size { get; }
+
+ Color this[in Point point] { get; }
+ Color this[in Rectangle rectangle] { get; }
+ }
+}
diff --git a/RGB.NET.Core/Rendering/Textures/PixelTexture.cs b/RGB.NET.Core/Rendering/Textures/PixelTexture.cs
new file mode 100644
index 0000000..9b14405
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Textures/PixelTexture.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Buffers;
+using System.Runtime.CompilerServices;
+
+namespace RGB.NET.Core
+{
+ public abstract class PixelTexture : ITexture
+ where T : unmanaged
+ {
+ #region Constants
+
+ private const int STACK_ALLOC_LIMIT = 1024;
+
+ #endregion
+
+ #region Properties & Fields
+
+ private readonly int _dataPerPixel;
+ private readonly int _stride;
+
+ public ISampler Sampler { get; set; }
+ public Size Size { get; }
+
+ protected abstract ReadOnlySpan Data { get; }
+
+ public virtual Color this[in Point point]
+ {
+ get
+ {
+ if (Data.Length == 0) return Color.Transparent;
+
+ int x = (int)MathF.Round(Size.Width * point.X.Clamp(0, 1));
+ int y = (int)MathF.Round(Size.Height * point.Y.Clamp(0, 1));
+ return GetColor(GetPixelData(x, y));
+ }
+ }
+
+ public virtual Color this[in Rectangle rectangle]
+ {
+ get
+ {
+ if (Data.Length == 0) return Color.Transparent;
+
+ int x = (int)MathF.Round(Size.Width * rectangle.Location.X.Clamp(0, 1));
+ int y = (int)MathF.Round(Size.Height * rectangle.Location.Y.Clamp(0, 1));
+ int width = (int)MathF.Round(Size.Width * rectangle.Size.Width.Clamp(0, 1));
+ int height = (int)MathF.Round(Size.Height * rectangle.Size.Height.Clamp(0, 1));
+
+ if ((width == 0) || (height == 0)) return Color.Transparent;
+ if ((width == 1) && (height == 1)) return GetColor(GetPixelData(x, y));
+
+ int bufferSize = width * height * _dataPerPixel;
+ if (bufferSize <= STACK_ALLOC_LIMIT)
+ {
+ Span buffer = stackalloc T[bufferSize];
+ GetRegionData(x, y, width, height, buffer);
+
+ Span pixelData = stackalloc T[_dataPerPixel];
+ Sampler.SampleColor(new SamplerInfo(width, height, buffer), pixelData);
+
+ return GetColor(pixelData);
+ }
+ else
+ {
+ T[] rent = ArrayPool.Shared.Rent(bufferSize);
+
+ Span buffer = new Span(rent).Slice(0, bufferSize);
+ GetRegionData(x, y, width, height, buffer);
+
+ Span pixelData = stackalloc T[_dataPerPixel];
+ Sampler.SampleColor(new SamplerInfo(width, height, buffer), pixelData);
+
+ ArrayPool.Shared.Return(rent);
+
+ return GetColor(pixelData);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ public PixelTexture(int with, int height, int dataPerPixel, ISampler sampler, int stride = -1)
+ {
+ this._stride = stride == -1 ? with : stride;
+ this._dataPerPixel = dataPerPixel;
+ this.Sampler = sampler;
+
+ Size = new Size(with, height);
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected abstract Color GetColor(in ReadOnlySpan pixel);
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected virtual ReadOnlySpan GetPixelData(int x, int y) => Data.Slice((y * _stride) + x, _dataPerPixel);
+
+ protected virtual void GetRegionData(int x, int y, int width, int height, in Span buffer)
+ {
+ int dataWidth = width * _dataPerPixel;
+ ReadOnlySpan data = Data;
+ for (int i = 0; i < height; i++)
+ {
+ ReadOnlySpan dataSlice = data.Slice((((y + i) * _stride) + x) * _dataPerPixel, dataWidth);
+ Span destination = buffer.Slice(i * dataWidth, dataWidth);
+ dataSlice.CopyTo(destination);
+ }
+ }
+
+ #endregion
+ }
+
+ public sealed class PixelTexture : PixelTexture
+ {
+ #region Properties & Fields
+
+ private readonly Color[] _data;
+
+ protected override ReadOnlySpan Data => _data;
+
+ #endregion
+
+ #region Constructors
+
+ public PixelTexture(int with, int height, Color[] data)
+ : this(with, height, data, new AverageColorSampler())
+ { }
+
+ public PixelTexture(int with, int height, Color[] data, ISampler sampler)
+ : base(with, height, 1, sampler)
+ {
+ this._data = data;
+
+ if (Data.Length != (with * height)) throw new ArgumentException($"Data-Length {Data.Length} differs from the given size {with}x{height} ({with * height}).");
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override Color GetColor(in ReadOnlySpan pixel) => pixel[0];
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Rendering/Textures/Sampler/AverageColorSampler.cs b/RGB.NET.Core/Rendering/Textures/Sampler/AverageColorSampler.cs
new file mode 100644
index 0000000..4910dbc
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Textures/Sampler/AverageColorSampler.cs
@@ -0,0 +1,28 @@
+using System;
+
+namespace RGB.NET.Core
+{
+ public class AverageColorSampler : ISampler
+ {
+ #region Methods
+
+ public void SampleColor(in SamplerInfo info, in Span pixelData)
+ {
+ int count = info.Width * info.Height;
+ if (count == 0) return;
+
+ float a = 0, r = 0, g = 0, b = 0;
+ foreach (Color color in info.Data)
+ {
+ a += color.A;
+ r += color.R;
+ g += color.G;
+ b += color.B;
+ }
+
+ pixelData[0] = new Color(a / count, r / count, g / count, b / count);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Rendering/Textures/Sampler/ISampler.cs b/RGB.NET.Core/Rendering/Textures/Sampler/ISampler.cs
new file mode 100644
index 0000000..ce507bd
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Textures/Sampler/ISampler.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace RGB.NET.Core
+{
+ public interface ISampler
+ {
+ void SampleColor(in SamplerInfo info, in Span pixelData);
+ }
+}
diff --git a/RGB.NET.Core/Rendering/Textures/Sampler/SamplerInfo.cs b/RGB.NET.Core/Rendering/Textures/Sampler/SamplerInfo.cs
new file mode 100644
index 0000000..a544381
--- /dev/null
+++ b/RGB.NET.Core/Rendering/Textures/Sampler/SamplerInfo.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace RGB.NET.Core
+{
+ public readonly ref struct SamplerInfo
+ {
+ #region Properties & Fields
+
+ public int Width { get; }
+ public int Height { get; }
+ public ReadOnlySpan Data { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public SamplerInfo(int width, int height, ReadOnlySpan data)
+ {
+ this.Width = width;
+ this.Height = height;
+ this.Data = data;
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs
index 722c30e..3d754fd 100644
--- a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs
+++ b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs
@@ -30,6 +30,9 @@ namespace RGB.NET.Core
/// Optional custom-data passed to the subscribers of the .event.
protected virtual void OnUpdate(CustomUpdateData? updateData = null) => Update?.Invoke(this, updateData ?? new CustomUpdateData());
+ ///
+ public abstract void Start();
+
///
public abstract void Dispose();
diff --git a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs
index 43caf4c..61e85a3 100644
--- a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs
+++ b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs
@@ -86,7 +86,7 @@ namespace RGB.NET.Core
///
/// Starts the trigger.
///
- public void Start()
+ public override void Start()
{
if (IsRunning) return;
diff --git a/RGB.NET.Core/Update/Devices/IUpdateQueue.cs b/RGB.NET.Core/Update/Devices/IUpdateQueue.cs
new file mode 100644
index 0000000..0fbcd7a
--- /dev/null
+++ b/RGB.NET.Core/Update/Devices/IUpdateQueue.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+
+namespace RGB.NET.Core
+{
+ public interface IUpdateQueue : IDisposable
+ where TIdentifier : notnull
+ {
+ ///
+ /// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available.
+ ///
+ /// The set of data.
+ // ReSharper disable once MemberCanBeProtected.Global
+ void SetData(IEnumerable<(TIdentifier, TData)> dataSet);
+
+ ///
+ /// Resets the current data set.
+ ///
+ void Reset();
+ }
+
+ public interface IUpdateQueue : IUpdateQueue
/// The type of the key used to identify some data.
/// The type of the data.
- public abstract class UpdateQueue : IDisposable
+ public abstract class UpdateQueue : IUpdateQueue
where TIdentifier : notnull
{
#region Properties & Fields
private readonly object _dataLock = new();
private readonly IDeviceUpdateTrigger _updateTrigger;
- private Dictionary? _currentDataSet;
+ private readonly Dictionary _currentDataSet = new();
#endregion
@@ -45,17 +46,25 @@ namespace RGB.NET.Core
/// provided by the trigger.
protected virtual void OnUpdate(object? sender, CustomUpdateData customData)
{
- Dictionary dataSet;
+ (TIdentifier, TData)[] dataSet;
+ Span<(TIdentifier, TData)> data;
lock (_dataLock)
{
- if (_currentDataSet == null) return;
+ if (_currentDataSet.Count == 0) return;
- dataSet = _currentDataSet;
- _currentDataSet = null;
+ dataSet = ArrayPool<(TIdentifier, TData)>.Shared.Rent(_currentDataSet.Count);
+ data = new Span<(TIdentifier, TData)>(dataSet).Slice(0, _currentDataSet.Count);
+
+ int i = 0;
+ foreach ((TIdentifier key, TData value) in _currentDataSet)
+ data[i++] = (key, value);
+
+ _currentDataSet.Clear();
}
- if (dataSet.Count != 0)
- Update(dataSet);
+ Update(data);
+
+ ArrayPool<(TIdentifier, TData)>.Shared.Return(dataSet);
}
///
@@ -69,26 +78,22 @@ namespace RGB.NET.Core
/// Performs the update this queue is responsible for.
///
/// The set of data that needs to be updated.
- protected abstract void Update(Dictionary dataSet);
+ protected abstract void Update(in ReadOnlySpan<(TIdentifier key, TData color)> dataSet);
///
/// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available.
///
/// The set of data.
// ReSharper disable once MemberCanBeProtected.Global
- public virtual void SetData(Dictionary dataSet)
+ public virtual void SetData(IEnumerable<(TIdentifier, TData)> dataSet)
{
- if (dataSet.Count == 0) return;
+ IList<(TIdentifier, TData)> data = dataSet.ToList();
+ if (data.Count == 0) return;
lock (_dataLock)
{
- if (_currentDataSet == null)
- _currentDataSet = dataSet;
- else
- {
- foreach ((TIdentifier key, TData value) in dataSet)
- _currentDataSet[key] = value;
- }
+ foreach ((TIdentifier key, TData value) in data)
+ _currentDataSet[key] = value;
}
_updateTrigger.TriggerHasData();
@@ -100,7 +105,7 @@ namespace RGB.NET.Core
public virtual void Reset()
{
lock (_dataLock)
- _currentDataSet = null;
+ _currentDataSet.Clear();
}
///
@@ -118,7 +123,7 @@ namespace RGB.NET.Core
///
/// Represents a generic using an object as the key and a color as the value.
///
- public abstract class UpdateQueue : UpdateQueue
event EventHandler? Update;
+
+ void Start();
}
}
diff --git a/RGB.NET.Core/Update/ManualUpdateTrigger.cs b/RGB.NET.Core/Update/ManualUpdateTrigger.cs
new file mode 100644
index 0000000..728f43e
--- /dev/null
+++ b/RGB.NET.Core/Update/ManualUpdateTrigger.cs
@@ -0,0 +1,94 @@
+// ReSharper disable MemberCanBePrivate.Global
+
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace RGB.NET.Core
+{
+ ///
+ ///
+ /// Represents an
+ ///
+ public sealed class ManualUpdateTrigger : AbstractUpdateTrigger
+ {
+ #region Properties & Fields
+
+ private AutoResetEvent _mutex = new(false);
+ private Task? UpdateTask { get; set; }
+ private CancellationTokenSource? UpdateTokenSource { get; set; }
+ private CancellationToken UpdateToken { get; set; }
+
+ ///
+ /// Gets the time it took the last update-loop cycle to run.
+ ///
+ public double LastUpdateTime { get; private set; }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// A value indicating if the trigger should automatically right after construction.
+ public ManualUpdateTrigger()
+ {
+ Start();
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Starts the trigger if needed, causing it to performing updates.
+ ///
+ public override void Start()
+ {
+ if (UpdateTask == null)
+ {
+ UpdateTokenSource?.Dispose();
+ UpdateTokenSource = new CancellationTokenSource();
+ UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default);
+ }
+ }
+
+ ///
+ /// Stops the trigger if running, causing it to stop performing updates.
+ ///
+ private void Stop()
+ {
+ if (UpdateTask != null)
+ {
+ UpdateTokenSource?.Cancel();
+ // ReSharper disable once MethodSupportsCancellation
+ UpdateTask.Wait();
+ UpdateTask.Dispose();
+ UpdateTask = null;
+ }
+ }
+
+ public void TriggerUpdate() => _mutex.Set();
+
+ private void UpdateLoop()
+ {
+ OnStartup();
+
+ while (!UpdateToken.IsCancellationRequested)
+ {
+ if (_mutex.WaitOne(100))
+ {
+ long preUpdateTicks = Stopwatch.GetTimestamp();
+ OnUpdate();
+ LastUpdateTime = ((Stopwatch.GetTimestamp() - preUpdateTicks) / 10000.0);
+ }
+ }
+ }
+
+ ///
+ public override void Dispose() => Stop();
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs
index 24321be..a63c29b 100644
--- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs
+++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs
@@ -56,7 +56,7 @@ namespace RGB.NET.Core
///
/// Starts the trigger if needed, causing it to performing updates.
///
- public void Start()
+ public override void Start()
{
lock (_lock)
{
diff --git a/RGB.NET.Decorators/RGB.NET.Decorators.csproj b/RGB.NET.Decorators/RGB.NET.Decorators.csproj
deleted file mode 100644
index f87a519..0000000
--- a/RGB.NET.Decorators/RGB.NET.Decorators.csproj
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
- net5.0
- latest
- enable
-
- Darth Affe
- Wyrez
- en-US
- en-US
- RGB.NET.Decorators
- RGB.NET.Decorators
- RGB.NET.Decorators
- RGB.NET.Decorators
- RGB.NET.Decorators
- Decorators-Presets of RGB.NET
- Decorators-Presets of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals
- Copyright © Darth Affe 2020
- Copyright © Darth Affe 2020
- http://lib.arge.be/icon.png
- https://github.com/DarthAffe/RGB.NET
- https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE
- Github
- https://github.com/DarthAffe/RGB.NET
- True
-
-
-
- 0.0.1
- 0.0.1
- 0.0.1
-
- ..\bin\
- true
- True
- True
-
-
-
- $(DefineConstants);TRACE;DEBUG
- true
- full
- false
-
-
-
- pdbonly
- true
- $(NoWarn);CS1591;CS1572;CS1573
- $(DefineConstants);RELEASE
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs
index 00f22f4..59a1351 100644
--- a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs
+++ b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using AuraServiceLib;
using RGB.NET.Core;
@@ -14,7 +12,7 @@ namespace RGB.NET.Devices.Asus
///
/// Represents a device provider responsible for Cooler Master devices.
///
- public class AsusDeviceProvider : IRGBDeviceProvider
+ public class AsusDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -24,20 +22,6 @@ namespace RGB.NET.Devices.Asus
///
public static AsusDeviceProvider Instance => _instance ?? new AsusDeviceProvider();
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for asus devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
private IAuraSdk2? _sdk;
#endregion
@@ -52,107 +36,44 @@ namespace RGB.NET.Devices.Asus
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(AsusDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
-
+
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- IsInitialized = false;
+ _sdk = (IAuraSdk2)new AuraSdk();
+ _sdk.SwitchMode();
+ }
- try
+ protected override IEnumerable LoadDevices()
+ {
+ if (_sdk == null) yield break;
+
+ foreach (IAuraSyncDevice device in _sdk.Enumerate(0))
{
- UpdateTrigger.Stop();
-
- // ReSharper disable once SuspiciousTypeConversion.Global
- _sdk = (IAuraSdk2)new AuraSdk();
- _sdk.SwitchMode();
-
- IList devices = new List();
- foreach (IAuraSyncDevice device in _sdk.Enumerate(0))
+ yield return (AsusDeviceType)device.Type switch
{
- try
- {
- IAsusRGBDevice rgbDevice;
- switch ((AsusDeviceType)device.Type)
- {
- case AsusDeviceType.MB_RGB:
- rgbDevice = new AsusMainboardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mainboard, device, WMIHelper.GetMainboardInfo()?.model ?? device.Name));
- break;
-
- case AsusDeviceType.MB_ADDRESABLE:
- rgbDevice = new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.LedStripe, device), LedId.LedStripe1);
- break;
-
- case AsusDeviceType.VGA_RGB:
- rgbDevice = new AsusGraphicsCardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.GraphicsCard, device));
- break;
-
- case AsusDeviceType.HEADSET_RGB:
- rgbDevice = new AsusHeadsetRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Headset, device));
- break;
-
- case AsusDeviceType.DRAM_RGB:
- rgbDevice = new AsusDramRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.DRAM, device));
- break;
-
- case AsusDeviceType.KEYBOARD_RGB:
- case AsusDeviceType.NB_KB_RGB:
- case AsusDeviceType.NB_KB_4ZONE_RGB:
- rgbDevice = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device));
- break;
-
- case AsusDeviceType.MOUSE_RGB:
- rgbDevice = new AsusMouseRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mouse, device));
- break;
-
- default:
- rgbDevice = new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Unknown, device), LedId.Custom1);
- break;
- }
-
- if (loadFilter.HasFlag(rgbDevice.DeviceInfo.DeviceType))
- {
- rgbDevice.Initialize(UpdateTrigger);
- devices.Add(rgbDevice);
- }
- }
- catch
- {
- if (throwExceptions)
- throw;
- }
- }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
+ AsusDeviceType.MB_RGB => new AsusMainboardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mainboard, device, WMIHelper.GetMainboardInfo()?.model ?? device.Name), GetUpdateTrigger()),
+ AsusDeviceType.MB_ADDRESABLE => new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.LedStripe, device), LedId.LedStripe1, GetUpdateTrigger()),
+ AsusDeviceType.VGA_RGB => new AsusGraphicsCardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.GraphicsCard, device), GetUpdateTrigger()),
+ AsusDeviceType.HEADSET_RGB => new AsusHeadsetRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Headset, device), GetUpdateTrigger()),
+ AsusDeviceType.DRAM_RGB => new AsusDramRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.DRAM, device), GetUpdateTrigger()),
+ AsusDeviceType.KEYBOARD_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), GetUpdateTrigger()),
+ AsusDeviceType.NB_KB_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), GetUpdateTrigger()),
+ AsusDeviceType.NB_KB_4ZONE_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), GetUpdateTrigger()),
+ AsusDeviceType.MOUSE_RGB => new AsusMouseRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mouse, device), GetUpdateTrigger()),
+ _ => new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Unknown, device), LedId.Custom1, GetUpdateTrigger())
+ };
}
- catch
- {
- if (throwExceptions)
- throw;
- return false;
- }
- return true;
}
///
- public void Dispose()
+ public override void Dispose()
{
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ base.Dispose();
try { _sdk?.ReleaseControl(0); }
catch { /* at least we tried */ }
diff --git a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs
index 6920a01..ef1b046 100644
--- a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs
@@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the DRAM.
- internal AsusDramRGBDevice(AsusRGBDeviceInfo info)
- : base(info)
- { }
+ internal AsusDramRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)
diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs
index f0fc1bc..f80056a 100644
--- a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs
@@ -1,75 +1,23 @@
-using System.Collections.Generic;
-using System.Linq;
-using RGB.NET.Core;
+using RGB.NET.Core;
namespace RGB.NET.Devices.Asus
{
///
- ///
///
/// Represents a generic Asus-device. (keyboard, mouse, headset, mousepad).
///
public abstract class AsusRGBDevice : AbstractRGBDevice, IAsusRGBDevice
where TDeviceInfo : AsusRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected AsusUpdateQueue? UpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by Asus for the device.
- protected AsusRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
-
- #endregion
-
- #region Methods
-
- ///
- /// Initializes the device.
- ///
- public void Initialize(IDeviceUpdateTrigger updateTrigger)
- {
- InitializeLayout();
-
- UpdateQueue = new AsusUpdateQueue(updateTrigger);
- UpdateQueue.Initialize(DeviceInfo.Device);
- }
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout();
-
- ///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
- ///
- public override void Dispose()
- {
- try { UpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected AsusRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new AsusUpdateQueue(updateTrigger, info.Device))
+ { }
#endregion
}
diff --git a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs
index c114b52..e0abfa5 100644
--- a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs
@@ -21,18 +21,19 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the headset.
- internal AsusUnspecifiedRGBDevice(AsusRGBDeviceInfo info, LedId baseLedId)
- : base(info)
+ internal AsusUnspecifiedRGBDevice(AsusRGBDeviceInfo info, LedId baseLedId, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
{
this._baseLedId = baseLedId;
+
+ InitializeLayout();
}
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)
@@ -41,6 +42,7 @@ namespace RGB.NET.Devices.Asus
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)_baseLedId;
+
#endregion
}
}
diff --git a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
index 1623fa7..70b1a38 100644
--- a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
+++ b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System;
using AuraServiceLib;
using RGB.NET.Core;
@@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Asus
///
/// The device to be updated.
///
- protected IAuraSyncDevice? Device { get; private set; }
+ protected IAuraSyncDevice Device { get; }
#endregion
@@ -25,28 +25,19 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The update trigger used by this queue.
- public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger)
+ public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger, IAuraSyncDevice device)
: base(updateTrigger)
- { }
+ {
+ this.Device = device;
+ }
#endregion
#region Methods
- ///
- /// Initializes the queue.
- ///
- /// The device to be updated.
- public void Initialize(IAuraSyncDevice device)
- {
- Device = device;
- }
-
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- if (Device == null) return;
-
try
{
if ((Device.Type == (uint)AsusDeviceType.KEYBOARD_RGB) || (Device.Type == (uint)AsusDeviceType.NB_KB_RGB))
diff --git a/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs
index 720fd3c..74b0d08 100644
--- a/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Asus
///
/// Represents a asus RGB-device.
///
- internal interface IAsusRGBDevice : IRGBDevice
- {
- void Initialize(IDeviceUpdateTrigger updateTrigger);
- }
+ public interface IAsusRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs
index 8c0f98a..698b2c3 100644
--- a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs
@@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the graphics card.
- internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info)
- : base(info)
- { }
+ internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)
diff --git a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs
index 96c4c87..22d14d9 100644
--- a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs
@@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the headset.
- internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info)
- : base(info)
- { }
+ internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)
diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs
index b10eb60..28cfbec 100644
--- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs
@@ -24,16 +24,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the keyboard.
- internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info)
- : base(info)
- { }
+ internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
Dictionary reversedMapping = AsusKeyboardLedMapping.MAPPING.ToDictionary(x => x.Value, x => x.Key);
diff --git a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs
index e4b25a5..bde9f1b 100644
--- a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs
@@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the mainboard.
- internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info)
- : base(info)
- { }
+ internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)
@@ -33,7 +34,7 @@ namespace RGB.NET.Devices.Asus
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1;
-
+
#endregion
}
}
diff --git a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs
index cd97e88..fdbd204 100644
--- a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs
+++ b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs
@@ -15,16 +15,17 @@ namespace RGB.NET.Devices.Asus
/// Initializes a new instance of the class.
///
/// The specific information provided by Asus for the mouse.
- internal AsusMouseRGBDevice(AsusRGBDeviceInfo info)
- : base(info)
- { }
+ internal AsusMouseRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
int ledCount = DeviceInfo.Device.Lights.Count;
for (int i = 0; i < ledCount; i++)
diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs
index f7e57dc..eb96ce0 100644
--- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs
+++ b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.CoolerMaster.Helper;
using RGB.NET.Devices.CoolerMaster.Native;
@@ -15,7 +13,7 @@ namespace RGB.NET.Devices.CoolerMaster
///
/// Represents a device provider responsible for Cooler Master devices.
///
- public class CoolerMasterDeviceProvider : IRGBDeviceProvider
+ public class CoolerMasterDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -37,20 +35,6 @@ namespace RGB.NET.Devices.CoolerMaster
///
public static List PossibleX64NativePaths { get; } = new() { "x64/CMSDK.dll" };
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for cooler master devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -63,97 +47,48 @@ namespace RGB.NET.Devices.CoolerMaster
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CoolerMasterDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- IsInitialized = false;
-
- try
- {
- UpdateTrigger.Stop();
-
- _CoolerMasterSDK.Reload();
- if (_CoolerMasterSDK.GetSDKVersion() <= 0) return false;
-
- IList devices = new List();
-
- foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes)))
- {
- try
- {
- RGBDeviceType deviceType = index.GetDeviceType();
- if (deviceType == RGBDeviceType.None) continue;
-
- if (_CoolerMasterSDK.IsDevicePlugged(index))
- {
- if (!loadFilter.HasFlag(deviceType)) continue;
-
- ICoolerMasterRGBDevice device;
- switch (deviceType)
- {
- case RGBDeviceType.Keyboard:
- CoolerMasterPhysicalKeyboardLayout physicalLayout = _CoolerMasterSDK.GetDeviceLayout(index);
- device = new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, physicalLayout));
- break;
-
- case RGBDeviceType.Mouse:
- device = new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index));
- break;
-
- default:
- if (throwExceptions)
- throw new RGBDeviceException("Unknown Device-Type");
- else
- continue;
- }
-
- if (!_CoolerMasterSDK.EnableLedControl(true, index))
- throw new RGBDeviceException("Failed to enable LED control for device " + index);
-
- device.Initialize(UpdateTrigger);
- devices.Add(device);
- }
- }
- catch { if (throwExceptions) throw; }
- }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
- }
- catch
- {
- if (throwExceptions)
- throw;
- return false;
- }
-
- return true;
+ _CoolerMasterSDK.Reload();
+ if (_CoolerMasterSDK.GetSDKVersion() <= 0) Throw(new RGBDeviceException("Failed to initialize CoolerMaster-SDK"));
}
- ///
- public void Dispose()
+ protected override IEnumerable LoadDevices()
{
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
+ foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes)))
+ {
+ RGBDeviceType deviceType = index.GetDeviceType();
+ if (deviceType == RGBDeviceType.None) continue;
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ if (_CoolerMasterSDK.IsDevicePlugged(index))
+ {
+ if (!_CoolerMasterSDK.EnableLedControl(true, index))
+ Throw(new RGBDeviceException("Failed to enable LED control for device " + index));
+ else
+ {
+ switch (deviceType)
+ {
+ case RGBDeviceType.Keyboard:
+ yield return new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, _CoolerMasterSDK.GetDeviceLayout(index)), GetUpdateTrigger());
+ break;
- // DarthAffe 03.03.2020: Should be done but isn't possible due to an weird winodws-hook inside the sdk which corrupts the stack when unloading the dll
- //try { _CoolerMasterSDK.UnloadCMSDK(); }
- //catch { /* at least we tried */ }
+ case RGBDeviceType.Mouse:
+ yield return new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index), GetUpdateTrigger());
+ break;
+
+ default:
+ Throw(new RGBDeviceException("Unknown Device-Type"));
+ break;
+ }
+ }
+ }
+ }
}
#endregion
diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs
index b176bc7..fdeaf39 100644
--- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs
+++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs
@@ -1,76 +1,34 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.CoolerMaster.Native;
namespace RGB.NET.Devices.CoolerMaster
{
///
- ///
///
/// Represents a generic CoolerMaster-device. (keyboard, mouse, headset, mousepad).
///
public abstract class CoolerMasterRGBDevice : AbstractRGBDevice, ICoolerMasterRGBDevice
where TDeviceInfo : CoolerMasterRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected CoolerMasterUpdateQueue? UpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by CoolerMaster for the device.
- protected CoolerMasterRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
+ protected CoolerMasterRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new CoolerMasterUpdateQueue(updateTrigger, info.DeviceIndex))
+ { }
#endregion
#region Methods
-
- ///
- /// Initializes the device.
- ///
- public void Initialize(IDeviceUpdateTrigger updateTrigger)
- {
- InitializeLayout();
-
- UpdateQueue = new CoolerMasterUpdateQueue(updateTrigger, DeviceInfo.DeviceIndex);
- }
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout();
-
- ///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
///
///
public override void Dispose()
{
- try { UpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
_CoolerMasterSDK.EnableLedControl(false, DeviceInfo.DeviceIndex);
base.Dispose();
diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs
index 21b26ce..42c96fe 100644
--- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs
+++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System;
using RGB.NET.Core;
using RGB.NET.Devices.CoolerMaster.Native;
@@ -28,7 +28,7 @@ namespace RGB.NET.Devices.CoolerMaster
: base(updateTrigger)
{
this._deviceIndex = deviceIndex;
-
+
_deviceMatrix = new _CoolerMasterColorMatrix();
_deviceMatrix.KeyColor = new _CoolerMasterKeyColor[_CoolerMasterColorMatrix.ROWS, _CoolerMasterColorMatrix.COLUMNS];
}
@@ -38,12 +38,12 @@ namespace RGB.NET.Devices.CoolerMaster
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- foreach (KeyValuePair data in dataSet)
+ foreach ((object key, Color color) in dataSet)
{
- (int row, int column) = ((int, int))data.Key;
- _deviceMatrix.KeyColor[row, column] = new _CoolerMasterKeyColor(data.Value.GetR(), data.Value.GetG(), data.Value.GetB());
+ (int row, int column) = ((int, int))key;
+ _deviceMatrix.KeyColor[row, column] = new _CoolerMasterKeyColor(color.GetR(), color.GetG(), color.GetB());
}
_CoolerMasterSDK.SetAllLedColor(_deviceMatrix, _deviceIndex);
diff --git a/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs
index 8483843..4edd1e9 100644
--- a/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs
+++ b/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.CoolerMaster
///
/// Represents a CoolerMaster RGB-device.
///
- internal interface ICoolerMasterRGBDevice : IRGBDevice
- {
- void Initialize(IDeviceUpdateTrigger updateTrigger);
- }
+ public interface ICoolerMasterRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs
index 29df3be..9007148 100644
--- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs
+++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs
@@ -22,16 +22,17 @@ namespace RGB.NET.Devices.CoolerMaster
/// Initializes a new instance of the class.
///
/// The specific information provided by CoolerMaster for the keyboard
- internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info)
- : base(info)
- { }
+ internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary>? deviceMappings))
throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex}");
@@ -44,7 +45,7 @@ namespace RGB.NET.Devices.CoolerMaster
///
protected override object GetLedCustomData(LedId ledId) => CoolerMasterKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId];
-
+
#endregion
}
}
diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs
index e1efb77..aa4c3aa 100644
--- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs
+++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs
@@ -16,16 +16,15 @@ namespace RGB.NET.Devices.CoolerMaster
/// Initializes a new instance of the class.
///
/// The specific information provided by CoolerMaster for the mouse
- internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info)
- : base(info)
+ internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
{ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
Dictionary mapping = CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex];
@@ -35,7 +34,7 @@ namespace RGB.NET.Devices.CoolerMaster
///
protected override object GetLedCustomData(LedId ledId) => CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex][ledId];
-
+
#endregion
}
}
diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs
index 4f7a57a..3e05167 100644
--- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs
+++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs
@@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Corsair
///
/// Represents a device provider responsible for corsair (CUE) devices.
///
- public class CorsairDeviceProvider : IRGBDeviceProvider
+ public class CorsairDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -37,12 +37,6 @@ namespace RGB.NET.Devices.Corsair
///
public static List PossibleX64NativePaths { get; } = new() { "x64/CUESDK.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" };
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
///
/// Gets the protocol details for the current SDK-connection.
///
@@ -53,14 +47,6 @@ namespace RGB.NET.Devices.Corsair
///
public CorsairError LastError => _CUESDK.CorsairGetLastError();
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for corsair devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -73,156 +59,108 @@ namespace RGB.NET.Devices.Corsair
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CorsairDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- /// Thrown if the SDK is already initialized or if the SDK is not compatible to CUE.
- /// Thrown if the CUE-SDK provides an error.
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- IsInitialized = false;
+ _CUESDK.Reload();
- try
- {
- UpdateTrigger.Stop();
+ ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake());
- _CUESDK.Reload();
+ CorsairError error = LastError;
+ if (error != CorsairError.Success)
+ Throw(new CUEException(error));
- ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake());
+ if (ProtocolDetails.BreakingChanges)
+ Throw(new RGBDeviceException("The SDK currently used isn't compatible with the installed version of CUE.\r\n"
+ + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n"
+ + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})"));
- CorsairError error = LastError;
- if (error != CorsairError.Success)
- throw new CUEException(error);
-
- if (ProtocolDetails.BreakingChanges)
- throw new RGBDeviceException("The SDK currently used isn't compatible with the installed version of CUE.\r\n"
- + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n"
- + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})");
-
- // DarthAffe 02.02.2021: 127 is iCUE
- if (!_CUESDK.CorsairSetLayerPriority(128))
- throw new CUEException(LastError);
-
- Dictionary modelCounter = new();
- IList devices = new List();
- int deviceCount = _CUESDK.CorsairGetDeviceCount();
- for (int i = 0; i < deviceCount; i++)
- {
- try
- {
- _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo))!;
- CorsairRGBDeviceInfo info = new(i, RGBDeviceType.Unknown, nativeDeviceInfo, modelCounter);
- if (!info.CapsMask.HasFlag(CorsairDeviceCaps.Lighting))
- continue; // Everything that doesn't support lighting control is useless
-
- CorsairDeviceUpdateQueue? deviceUpdateQueue = null;
- foreach (ICorsairRGBDevice device in GetRGBDevice(info, i, nativeDeviceInfo, modelCounter))
- {
- if ((device == null) || !loadFilter.HasFlag(device.DeviceInfo.DeviceType)) continue;
-
- deviceUpdateQueue ??= new CorsairDeviceUpdateQueue(UpdateTrigger, info.CorsairDeviceIndex);
-
- device.Initialize(deviceUpdateQueue);
-
- error = LastError;
- if (error != CorsairError.Success)
- throw new CUEException(error);
-
- devices.Add(device);
- }
- }
- catch { if (throwExceptions) throw; }
- }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
- }
- catch
- {
- Reset();
- if (throwExceptions) throw;
- return false;
- }
-
- return true;
+ // DarthAffe 02.02.2021: 127 is iCUE
+ if (!_CUESDK.CorsairSetLayerPriority(128))
+ Throw(new CUEException(LastError));
}
- private static IEnumerable GetRGBDevice(CorsairRGBDeviceInfo info, int i, _CorsairDeviceInfo nativeDeviceInfo, Dictionary modelCounter)
+ protected override IEnumerable LoadDevices()
{
- switch (info.CorsairDeviceType)
+ Dictionary modelCounter = new();
+ int deviceCount = _CUESDK.CorsairGetDeviceCount();
+ for (int i = 0; i < deviceCount; i++)
{
- case CorsairDeviceType.Keyboard:
- yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
- break;
+ _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo))!;
+ CorsairRGBDeviceInfo info = new(i, RGBDeviceType.Unknown, nativeDeviceInfo, modelCounter);
+ if (!info.CapsMask.HasFlag(CorsairDeviceCaps.Lighting))
+ continue; // Everything that doesn't support lighting control is useless
- case CorsairDeviceType.Mouse:
- yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
- break;
+ CorsairDeviceUpdateQueue updateQueue = new(GetUpdateTrigger(), info.CorsairDeviceIndex);
+ switch (info.CorsairDeviceType)
+ {
+ case CorsairDeviceType.Keyboard:
+ yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
+ break;
- case CorsairDeviceType.Headset:
- yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
- break;
+ case CorsairDeviceType.Mouse:
+ yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
+ break;
- case CorsairDeviceType.Mousepad:
- yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
- break;
+ case CorsairDeviceType.Headset:
+ yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
+ break;
- case CorsairDeviceType.HeadsetStand:
- yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
- break;
+ case CorsairDeviceType.Mousepad:
+ yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
+ break;
- case CorsairDeviceType.MemoryModule:
- yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter));
- break;
+ case CorsairDeviceType.HeadsetStand:
+ yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
+ break;
- case CorsairDeviceType.Cooler:
- case CorsairDeviceType.CommanderPro:
- case CorsairDeviceType.LightningNodePro:
- _CorsairChannelsInfo? channelsInfo = nativeDeviceInfo.channels;
- if (channelsInfo != null)
- {
- IntPtr channelInfoPtr = channelsInfo.channels;
+ case CorsairDeviceType.MemoryModule:
+ yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter), updateQueue);
+ break;
- for (int channel = 0; channel < channelsInfo.channelsCount; channel++)
+ case CorsairDeviceType.Cooler:
+ case CorsairDeviceType.CommanderPro:
+ case CorsairDeviceType.LightningNodePro:
+ _CorsairChannelsInfo? channelsInfo = nativeDeviceInfo.channels;
+ if (channelsInfo != null)
{
- CorsairLedId referenceLed = GetChannelReferenceId(info.CorsairDeviceType, channel);
- if (referenceLed == CorsairLedId.Invalid) continue;
+ IntPtr channelInfoPtr = channelsInfo.channels;
- _CorsairChannelInfo channelInfo = (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo))!;
-
- int channelDeviceInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelDeviceInfo));
- IntPtr channelDeviceInfoPtr = channelInfo.devices;
-
- for (int device = 0; device < channelInfo.devicesCount; device++)
+ for (int channel = 0; channel < channelsInfo.channelsCount; channel++)
{
- _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!;
+ CorsairLedId referenceLed = GetChannelReferenceId(info.CorsairDeviceType, channel);
+ if (referenceLed == CorsairLedId.Invalid) continue;
- yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter));
- referenceLed += channelDeviceInfo.deviceLedCount;
+ _CorsairChannelInfo channelInfo = (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo))!;
- channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize);
+ int channelDeviceInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelDeviceInfo));
+ IntPtr channelDeviceInfoPtr = channelInfo.devices;
+
+ for (int device = 0; device < channelInfo.devicesCount; device++)
+ {
+ _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!;
+
+ yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter), updateQueue);
+ referenceLed += channelDeviceInfo.deviceLedCount;
+
+ channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize);
+ }
+
+ int channelInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelInfo));
+ channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize);
}
-
- int channelInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelInfo));
- channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize);
}
- }
+ break;
- break;
-
-
- // ReSharper disable once RedundantCaseLabel
- case CorsairDeviceType.Unknown:
- default:
- throw new RGBDeviceException("Unknown Device-Type");
+ default:
+ Throw(new RGBDeviceException("Unknown Device-Type"));
+ break;
+ }
}
}
@@ -240,23 +178,17 @@ namespace RGB.NET.Devices.Corsair
};
}
- private void Reset()
+ protected override void Reset()
{
ProtocolDetails = null;
- Devices = Enumerable.Empty();
- IsInitialized = false;
+
+ base.Reset();
}
///
- public void Dispose()
+ public override void Dispose()
{
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ base.Dispose();
try { _CUESDK.UnloadCUESDK(); }
catch { /* at least we tried */ }
diff --git a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs
index 0ea52b4..fc67e5a 100644
--- a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs
@@ -25,16 +25,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the custom-device.
- internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
LedId referenceId = GetReferenceLed(DeviceInfo.DeviceType);
@@ -45,7 +46,7 @@ namespace RGB.NET.Devices.Corsair
AddLed(ledId, new Point(i * 10, 0), new Size(10, 10));
}
}
-
+
protected override object GetLedCustomData(LedId ledId) => _idMapping.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid;
protected virtual LedId GetReferenceLed(RGBDeviceType deviceType)
diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs
index ae1859a..340fdee 100644
--- a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs
+++ b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Corsair.Native;
@@ -36,26 +35,26 @@ namespace RGB.NET.Devices.Corsair
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
int structSize = Marshal.SizeOf(typeof(_CorsairLedColor));
- IntPtr ptr = Marshal.AllocHGlobal(structSize * dataSet.Count);
+ IntPtr ptr = Marshal.AllocHGlobal(structSize * dataSet.Length);
IntPtr addPtr = new(ptr.ToInt64());
- foreach (KeyValuePair data in dataSet)
+ foreach ((object key, Color color) in dataSet)
{
- _CorsairLedColor color = new()
- {
- ledId = (int)data.Key,
- r = data.Value.GetR(),
- g = data.Value.GetG(),
- b = data.Value.GetB()
+ _CorsairLedColor corsairColor = new()
+ {
+ ledId = (int)key,
+ r = color.GetR(),
+ g = color.GetG(),
+ b = color.GetB()
};
- Marshal.StructureToPtr(color, addPtr, false);
+ Marshal.StructureToPtr(corsairColor, addPtr, false);
addPtr = new IntPtr(addPtr.ToInt64() + structSize);
}
- _CUESDK.CorsairSetLedsColorsBufferByDeviceIndex(_deviceIndex, dataSet.Count, ptr);
+ _CUESDK.CorsairSetLedsColorsBufferByDeviceIndex(_deviceIndex, dataSet.Length, ptr);
_CUESDK.CorsairSetLedsColorsFlushBuffer();
Marshal.FreeHGlobal(ptr);
}
diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs
index d573ba2..c7e1864 100644
--- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs
@@ -1,99 +1,23 @@
-using System.Collections.Generic;
-using System.Linq;
-using RGB.NET.Core;
+using RGB.NET.Core;
namespace RGB.NET.Devices.Corsair
{
///
- ///
///
/// Represents a generic CUE-device. (keyboard, mouse, headset, mousepad).
///
public abstract class CorsairRGBDevice : AbstractRGBDevice, ICorsairRGBDevice
where TDeviceInfo : CorsairRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets a dictionary containing all of the .
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected Dictionary InternalLedMapping { get; } = new();
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected CorsairDeviceUpdateQueue? DeviceUpdateQueue { get; set; }
-
- #endregion
-
- #region Indexer
-
- ///
- /// Gets the with the specified .
- ///
- /// The of the to get.
- /// The with the specified or null if no is found.
- // ReSharper disable once MemberCanBePrivate.Global
- public Led? this[CorsairLedId ledId] => InternalLedMapping.TryGetValue(ledId, out Led? led) ? led : null;
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by CUE for the device.
- protected CorsairRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
-
- #endregion
-
- #region Methods
-
- ///
- /// Initializes the device.
- ///
- public void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue)
- {
- DeviceUpdateQueue = deviceUpdateQueue;
-
- InitializeLayout();
-
- foreach (Led led in LedMapping.Values)
- {
- if (led.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid))
- InternalLedMapping.Add(ledId, led);
- }
- }
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout();
-
- ///
- protected override void UpdateLeds(IEnumerable ledsToUpdate)
- => DeviceUpdateQueue?.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid))));
-
- ///
- public override void Dispose()
- {
- try { DeviceUpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected CorsairRGBDevice(TDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ { }
#endregion
}
diff --git a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs
index 325c46c..9caca09 100644
--- a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Corsair
///
/// Represents a corsair RGB-device.
///
- internal interface ICorsairRGBDevice : IRGBDevice
- {
- void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue);
- }
+ public interface ICorsairRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs
index 7a39b28..92455d9 100644
--- a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs
@@ -18,16 +18,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the headset
- internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
AddLed(LedId.Headset1, new Point(0, 0), new Size(10, 10));
AddLed(LedId.Headset2, new Point(10, 0), new Size(10, 10));
diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs
index 966fc77..ca17c0e 100644
--- a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs
@@ -23,16 +23,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the headset stand
- internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;
diff --git a/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs b/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs
index d823f09..3a50788 100644
--- a/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs
+++ b/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs
@@ -8,10 +8,10 @@ namespace RGB.NET.Devices.Corsair
internal static Rectangle ToRectangle(this _CorsairLedPosition position)
{
//HACK DarthAffe 08.07.2018: It seems like corsair introduced a bug here - it's always 0.
- double width = position.width < 0.5 ? 10 : position.width;
- double height = position.height < 0.5 ? 10 : position.height;
- double posX = position.left;
- double posY = position.top;
+ float width = position.width < 0.5f ? 10 : (float)position.width;
+ float height = position.height < 0.5f ? 10 : (float)position.height;
+ float posX = (float)position.left;
+ float posY = (float)position.top;
return new Rectangle(posX, posY, width, height);
}
diff --git a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs
index 1d950dd..268cd75 100644
--- a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs
@@ -28,16 +28,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the keyboard
- internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;
diff --git a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs
index f174b8c..cdc42e7 100644
--- a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs
@@ -22,16 +22,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the memory.
- internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;
diff --git a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs
index f9bfa42..a3d015f 100644
--- a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs
@@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the mouse
- internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
switch (DeviceInfo.PhysicalLayout)
{
diff --git a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs
index 00b526d..1f74aee 100644
--- a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs
+++ b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs
@@ -23,16 +23,17 @@ namespace RGB.NET.Devices.Corsair
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the mousepad
- internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info)
- : base(info)
- { }
+ internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
_CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions));
if (nativeLedPositions == null) return;
diff --git a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs
index 4720e1e..0d23fd5 100644
--- a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs
+++ b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.DMX.E131;
@@ -14,7 +12,7 @@ namespace RGB.NET.Devices.DMX
///
/// Represents a device provider responsible for DMX devices.
///
- public class DMXDeviceProvider : IRGBDeviceProvider
+ public class DMXDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -24,22 +22,11 @@ namespace RGB.NET.Devices.DMX
///
public static DMXDeviceProvider Instance => _instance ?? new DMXDeviceProvider();
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
///
/// Gets a list of all defined device-definitions.
///
public List DeviceDefinitions { get; } = new();
- ///
- /// The used to trigger the updates for dmx devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -52,8 +39,6 @@ namespace RGB.NET.Devices.DMX
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(DMXDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
@@ -66,58 +51,27 @@ namespace RGB.NET.Devices.DMX
/// The to add.
public void AddDeviceDefinition(IDMXDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition);
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK() { }
+
+ protected override IEnumerable LoadDevices()
{
- IsInitialized = false;
-
- try
+ foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions)
{
- UpdateTrigger.Stop();
-
- IList devices = new List();
-
- foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions)
+ IRGBDevice? device = null;
+ try
{
- try
- {
- if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition)
- {
- if (e131DMXDeviceDefinition.Leds.Count > 0)
- {
- E131Device device = new(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds);
- device.Initialize(UpdateTrigger);
- devices.Add(device);
- }
- }
- }
- catch { if (throwExceptions) throw; }
+ if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition)
+ if (e131DMXDeviceDefinition.Leds.Count > 0)
+ device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds, GetUpdateTrigger(0));
+ }
+ catch (Exception ex)
+ {
+ Throw(ex);
}
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
+ if (device != null)
+ yield return device;
}
- catch
- {
- if (throwExceptions) throw;
- return false;
- }
-
- return true;
- }
-
- ///
- public void Dispose()
- {
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
}
#endregion
diff --git a/RGB.NET.Devices.DMX/E131/E131Device.cs b/RGB.NET.Devices.DMX/E131/E131Device.cs
index 3a8c4fe..0c170c6 100644
--- a/RGB.NET.Devices.DMX/E131/E131Device.cs
+++ b/RGB.NET.Devices.DMX/E131/E131Device.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.DMX.E131
@@ -12,55 +11,39 @@ namespace RGB.NET.Devices.DMX.E131
{
#region Properties & Fields
- ///
- public override E131DeviceInfo DeviceInfo { get; }
-
private readonly Dictionary getValueFunc)>> _ledMappings;
- private E131UpdateQueue? _updateQueue;
-
#endregion
#region Constructors
///
- internal E131Device(E131DeviceInfo deviceInfo, Dictionary getValueFunc)>> ledMappings)
+ internal E131Device(E131DeviceInfo deviceInfo, Dictionary getValueFunc)>> ledMappings, IDeviceUpdateTrigger updateTrigger)
+ : base(deviceInfo, new E131UpdateQueue(updateTrigger, deviceInfo.Hostname, deviceInfo.Port))
{
- this.DeviceInfo = deviceInfo;
this._ledMappings = ledMappings;
+
+ InitializeLayout();
+
+ E131UpdateQueue updateQueue = (E131UpdateQueue)UpdateQueue;
+ updateQueue.DataPacket.SetCID(DeviceInfo.CID);
+ updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe);
}
#endregion
#region Methods
- internal void Initialize(IDeviceUpdateTrigger updateTrigger)
+ private void InitializeLayout()
{
int count = 0;
foreach (LedId id in _ledMappings.Keys)
AddLed(id, new Point((count++) * 10, 0), new Size(10, 10));
-
- _updateQueue = new E131UpdateQueue(updateTrigger, DeviceInfo.Hostname, DeviceInfo.Port);
- _updateQueue.DataPacket.SetCID(DeviceInfo.CID);
- _updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe);
}
///
protected override object GetLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]);
-
- ///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
- ///
- public override void Dispose()
- {
- try { _updateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
-
#endregion
}
}
diff --git a/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs b/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs
index dcf301e..e7a3f96 100644
--- a/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs
+++ b/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Net.Sockets;
using RGB.NET.Core;
@@ -52,15 +51,15 @@ namespace RGB.NET.Devices.DMX.E131
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
DataPacket.SetSequenceNumber(GetNextSequenceNumber());
- foreach (KeyValuePair data in dataSet)
+ foreach ((object key, Color color) in dataSet)
{
- LedChannelMapping mapping = (LedChannelMapping)data.Key;
+ LedChannelMapping mapping = (LedChannelMapping)key;
foreach ((int channel, Func getValue) in mapping)
- DataPacket.SetChannel(channel, getValue(data.Value));
+ DataPacket.SetChannel(channel, getValue(color));
}
_socket.Send(DataPacket, DataPacket.Length);
diff --git a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs
index 66ec439..5e9ab8b 100644
--- a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs
+++ b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Layout;
@@ -14,7 +12,7 @@ namespace RGB.NET.Devices.Debug
///
/// Represents a device provider responsible for debug devices.
///
- public class DebugDeviceProvider : IRGBDeviceProvider
+ public class DebugDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -24,13 +22,7 @@ namespace RGB.NET.Devices.Debug
///
public static DebugDeviceProvider Instance => _instance ?? new DebugDeviceProvider();
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- private List<(IDeviceLayout layout, string imageLayout, Action>? updateLedsAction)> _fakeDeviceDefinitions = new();
+ private List<(IDeviceLayout layout, Action>? updateLedsAction)> _fakeDeviceDefinitions = new();
#endregion
@@ -54,48 +46,28 @@ namespace RGB.NET.Devices.Debug
/// Adds a new fake device definition.
///
/// The path of the layout file to be used.
- /// The image-layout to load.
/// A action emulating led-updates.
- public void AddFakeDeviceDefinition(IDeviceLayout layout, string imageLayout, Action>? updateLedsAction = null)
- => _fakeDeviceDefinitions.Add((layout, imageLayout, updateLedsAction));
+ public void AddFakeDeviceDefinition(IDeviceLayout layout, Action>? updateLedsAction = null)
+ => _fakeDeviceDefinitions.Add((layout, updateLedsAction));
///
/// Removes all previously added fake device definitions.
///
public void ClearFakeDeviceDefinitions() => _fakeDeviceDefinitions.Clear();
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false)
+ protected override void InitializeSDK() { }
+
+ protected override IEnumerable LoadDevices()
{
- IsInitialized = false;
- try
- {
- List devices = new();
- foreach ((IDeviceLayout layout, string imageLayout, Action>? updateLedsAction) in _fakeDeviceDefinitions)
- {
- DebugRGBDevice device = new(layout, updateLedsAction);
- devices.Add(device);
- }
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
-
- return true;
- }
- catch
- {
- if (throwExceptions) throw;
- return false;
- }
+ foreach ((IDeviceLayout layout, Action>? updateLedsAction) in _fakeDeviceDefinitions)
+ yield return new DebugRGBDevice(layout, updateLedsAction);
}
///
- public void ResetDevices()
- { }
-
- ///
- public void Dispose()
+ public override void Dispose()
{
+ base.Dispose();
+
_fakeDeviceDefinitions.Clear();
}
diff --git a/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs b/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs
new file mode 100644
index 0000000..7fe823d
--- /dev/null
+++ b/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs
@@ -0,0 +1,22 @@
+using System;
+using RGB.NET.Core;
+
+namespace RGB.NET.Devices.Debug
+{
+ internal class DebugDeviceUpdateQueue : UpdateQueue
+ {
+ #region Constructors
+
+ public DebugDeviceUpdateQueue()
+ : base(new DeviceUpdateTrigger())
+ { }
+
+ #endregion
+
+ #region Methods
+
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) { }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Devices.Debug/DebugRGBDevice.cs b/RGB.NET.Devices.Debug/DebugRGBDevice.cs
index 052e870..fa11042 100644
--- a/RGB.NET.Devices.Debug/DebugRGBDevice.cs
+++ b/RGB.NET.Devices.Debug/DebugRGBDevice.cs
@@ -13,9 +13,6 @@ namespace RGB.NET.Devices.Debug
{
#region Properties & Fields
- ///
- public override DebugRGBDeviceInfo DeviceInfo { get; }
-
public IDeviceLayout Layout { get; }
private Action>? _updateLedsAction;
@@ -27,12 +24,11 @@ namespace RGB.NET.Devices.Debug
/// Internal constructor of .
///
internal DebugRGBDevice(IDeviceLayout layout, Action>? updateLedsAction = null)
+ : base(new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData), new DebugDeviceUpdateQueue())
{
this.Layout = layout;
this._updateLedsAction = updateLedsAction;
- DeviceInfo = new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData);
-
Layout.ApplyTo(this, true);
}
diff --git a/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs
index 4c8e260..7c3b2be 100644
--- a/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs
+++ b/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Logitech
///
/// Represents a logitech RGB-device.
///
- internal interface ILogitechRGBDevice : IRGBDevice
- {
- void Initialize(UpdateQueue updateQueue);
- }
+ public interface ILogitechRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs
index eacb6b6..f217795 100644
--- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs
+++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs
@@ -3,60 +3,21 @@
namespace RGB.NET.Devices.Logitech
{
///
- ///
///
/// Represents a generic Logitech-device. (keyboard, mouse, headset, mousepad).
///
public abstract class LogitechRGBDevice : AbstractRGBDevice, ILogitechRGBDevice
where TDeviceInfo : LogitechRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected UpdateQueue? UpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by Logitech for the device.
- protected LogitechRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
-
- #endregion
-
- #region Methods
-
- ///
- /// Initializes the device.
- ///
- public virtual void Initialize(UpdateQueue updateQueue)
- {
- UpdateQueue = updateQueue;
- }
-
- ///
- public override void Dispose()
- {
- try { UpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected LogitechRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ { }
#endregion
}
diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
index 8e57da6..aa75343 100644
--- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
+++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.Logitech.HID;
using RGB.NET.Devices.Logitech.Native;
@@ -15,7 +13,7 @@ namespace RGB.NET.Devices.Logitech
///
/// Represents a device provider responsible for logitech devices.
///
- public class LogitechDeviceProvider : IRGBDeviceProvider
+ public class LogitechDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -37,21 +35,8 @@ namespace RGB.NET.Devices.Logitech
///
public static List PossibleX64NativePaths { get; } = new() { "x64/LogitechLedEnginesWrapper.dll" };
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for logitech devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
- // ReSharper disable once CollectionNeverQueried.Local - for now this is just to make sure they're never collected
- private readonly Dictionary _zoneUpdateQueues = new();
- private LogitechPerDeviceUpdateQueue _perDeviceUpdateQueue;
- private LogitechPerKeyUpdateQueue _perKeyUpdateQueue;
+ private LogitechPerDeviceUpdateQueue? _perDeviceUpdateQueue;
+ private LogitechPerKeyUpdateQueue? _perKeyUpdateQueue;
#endregion
@@ -65,116 +50,54 @@ namespace RGB.NET.Devices.Logitech
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(LogitechDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
- _perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(UpdateTrigger);
- _perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(UpdateTrigger);
}
#endregion
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- try
+ _perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(GetUpdateTrigger());
+ _perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(GetUpdateTrigger());
+
+ _LogitechGSDK.Reload();
+ if (!_LogitechGSDK.LogiLedInit()) Throw(new RGBDeviceException("Failed to initialize Logitech-SDK."));
+
+ _LogitechGSDK.LogiLedSaveCurrentLighting();
+ }
+
+ //TODO DarthAffe 04.03.2021: Rework device selection and configuration for HID-based providers
+ protected override IEnumerable LoadDevices()
+ {
+ DeviceChecker.LoadDeviceList();
+
+ if (DeviceChecker.IsPerKeyDeviceConnected && (_perKeyUpdateQueue != null))
{
- if (IsInitialized)
- _LogitechGSDK.LogiLedRestoreLighting();
- }
- catch { /* At least we tried ... */ }
-
- IsInitialized = false;
-
- try
- {
- UpdateTrigger.Stop();
-
- _LogitechGSDK.Reload();
- if (!_LogitechGSDK.LogiLedInit()) return false;
-
- _LogitechGSDK.LogiLedSaveCurrentLighting();
-
- IList devices = new List();
- DeviceChecker.LoadDeviceList();
-
- try
- {
- if (DeviceChecker.IsPerKeyDeviceConnected)
- {
- (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerKeyDeviceData;
- if (loadFilter.HasFlag(deviceType)) //TODO DarthAffe 07.12.2017: Check if it's worth to try another device if the one returned doesn't match the filter
- {
- ILogitechRGBDevice device = new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0));
- device.Initialize(_perKeyUpdateQueue);
- devices.Add(device);
- }
- }
- }
- catch { if (throwExceptions) throw; }
-
- try
- {
- if (DeviceChecker.IsPerDeviceDeviceConnected)
- {
- (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerDeviceDeviceData;
- if (loadFilter.HasFlag(deviceType)) //TODO DarthAffe 07.12.2017: Check if it's worth to try another device if the one returned doesn't match the filter
- {
- ILogitechRGBDevice device = new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0));
- device.Initialize(_perDeviceUpdateQueue);
- devices.Add(device);
- }
- }
- }
- catch { if (throwExceptions) throw; }
-
- try
- {
- if (DeviceChecker.IsZoneDeviceConnected)
- {
- foreach ((string model, RGBDeviceType deviceType, int _, int zones) in DeviceChecker.ZoneDeviceData)
- try
- {
- if (loadFilter.HasFlag(deviceType))
- {
- LogitechZoneUpdateQueue updateQueue = new(UpdateTrigger, deviceType);
- ILogitechRGBDevice device = new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones));
- device.Initialize(updateQueue);
- devices.Add(device);
- _zoneUpdateQueues.Add(deviceType, updateQueue);
- }
- }
- catch { if (throwExceptions) throw; }
- }
- }
- catch { if (throwExceptions) throw; }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
- }
- catch
- {
- if (throwExceptions)
- throw;
- return false;
+ (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerKeyDeviceData;
+ yield return new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0), _perKeyUpdateQueue);
}
- return true;
+ if (DeviceChecker.IsPerDeviceDeviceConnected && (_perDeviceUpdateQueue != null))
+ {
+ (string model, RGBDeviceType deviceType, int _, int _) = DeviceChecker.PerDeviceDeviceData;
+ yield return new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0), _perDeviceUpdateQueue);
+ }
+
+ if (DeviceChecker.IsZoneDeviceConnected)
+ {
+ foreach ((string model, RGBDeviceType deviceType, int _, int zones) in DeviceChecker.ZoneDeviceData)
+ {
+ LogitechZoneUpdateQueue updateQueue = new(GetUpdateTrigger(), deviceType);
+ yield return new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones), updateQueue);
+ }
+ }
}
///
- public void Dispose()
+ public override void Dispose()
{
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ base.Dispose();
try { _LogitechGSDK.LogiLedRestoreLighting(); }
catch { /* at least we tried */ }
diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs
index 416e18e..b65ba13 100644
--- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs
+++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs
@@ -17,26 +17,25 @@ namespace RGB.NET.Devices.Logitech
/// Initializes a new instance of the class.
///
/// The specific information provided by logitech for the per-device-lightable device
- internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info)
- : base(info)
- { }
+ internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue)
+ : base(info, updateQueue)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- public override void Initialize(UpdateQueue updateQueue)
+ private void InitializeLayout()
{
- base.Initialize(updateQueue);
-
AddLed(LedId.Custom1, new Point(0, 0), new Size(10, 10));
}
///
protected override object GetLedCustomData(LedId ledId) => (ledId, LogitechLedId.DEVICE);
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0).Take(1));
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate.Take(1)));
#endregion
}
diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs
index 8ea4c6a..a1ef25e 100644
--- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs
+++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.Logitech.Native;
@@ -27,9 +25,9 @@ namespace RGB.NET.Devices.Logitech
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- Color color = dataSet.Values.First();
+ Color color = dataSet[0].color;
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB);
_LogitechGSDK.LogiLedSetLighting((int)Math.Round(color.R * 100),
diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs
index 2b5a85d..29660c3 100644
--- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs
+++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.Logitech
@@ -17,8 +16,8 @@ namespace RGB.NET.Devices.Logitech
/// Initializes a new instance of the class.
///
/// The specific information provided by logitech for the per-key-lightable device
- internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info)
- : base(info)
+ internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue)
+ : base(info, updateQueue)
{ }
#endregion
@@ -29,7 +28,7 @@ namespace RGB.NET.Devices.Logitech
protected override object GetLedCustomData(LedId ledId) => (ledId, PerKeyIdMapping.DEFAULT.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : LogitechLedId.Invalid);
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}
diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs
index a166a3a..6077ed6 100644
--- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs
+++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using RGB.NET.Core;
using RGB.NET.Devices.Logitech.Native;
@@ -33,27 +32,27 @@ namespace RGB.NET.Devices.Logitech
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB);
Array.Clear(_bitmap, 0, _bitmap.Length);
bool usesBitmap = false;
- foreach (KeyValuePair data in dataSet)
+ foreach ((object key, Color color) in dataSet)
{
- (LedId id, LogitechLedId customData) = ((LedId, LogitechLedId))data.Key;
+ (LedId id, LogitechLedId customData) = ((LedId, LogitechLedId))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))
{
- BitmapMapping.SetColor(_bitmap, bitmapOffset, data.Value);
+ BitmapMapping.SetColor(_bitmap, bitmapOffset, color);
usesBitmap = true;
}
else
_LogitechGSDK.LogiLedSetLightingForKeyWithKeyName((int)customData,
- (int)Math.Round(data.Value.R * 100),
- (int)Math.Round(data.Value.G * 100),
- (int)Math.Round(data.Value.B * 100));
+ (int)MathF.Round(color.R * 100),
+ (int)MathF.Round(color.G * 100),
+ (int)MathF.Round(color.B * 100));
}
if (usesBitmap)
diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs
index 4b0da4f..120dbf1 100644
--- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs
+++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.Logitech
@@ -36,21 +35,20 @@ namespace RGB.NET.Devices.Logitech
/// Initializes a new instance of the class.
///
/// The specific information provided by logitech for the zone-lightable device
- internal LogitechZoneRGBDevice(LogitechRGBDeviceInfo info)
- : base(info)
+ internal LogitechZoneRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue)
+ : base(info, updateQueue)
{
_baseLedId = BASE_LED_MAPPING.TryGetValue(info.DeviceType, out LedId id) ? id : LedId.Custom1;
+
+ InitializeLayout();
}
#endregion
#region Methods
- ///
- public override void Initialize(UpdateQueue updateQueue)
+ private void InitializeLayout()
{
- base.Initialize(updateQueue);
-
for (int i = 0; i < DeviceInfo.Zones; i++)
AddLed(_baseLedId + i, new Point(i * 10, 0), new Size(10, 10));
}
@@ -59,7 +57,7 @@ namespace RGB.NET.Devices.Logitech
protected override object? GetLedCustomData(LedId ledId) => (int)(ledId - _baseLedId);
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}
diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs
index c3fb9ef..7c34363 100644
--- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs
+++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs
@@ -13,12 +13,12 @@ namespace RGB.NET.Devices.Logitech
#region Constants
private static readonly Dictionary DEVICE_TYPE_MAPPING = new()
- {
- {RGBDeviceType.Keyboard, LogitechDeviceType.Keyboard},
- {RGBDeviceType.Mouse, LogitechDeviceType.Mouse},
- {RGBDeviceType.Headset, LogitechDeviceType.Headset},
- {RGBDeviceType.Mousepad, LogitechDeviceType.Mousemat},
- {RGBDeviceType.Speaker, LogitechDeviceType.Speaker}
+ {
+ { RGBDeviceType.Keyboard, LogitechDeviceType.Keyboard },
+ { RGBDeviceType.Mouse, LogitechDeviceType.Mouse },
+ { RGBDeviceType.Headset, LogitechDeviceType.Headset },
+ { RGBDeviceType.Mousepad, LogitechDeviceType.Mousemat },
+ { RGBDeviceType.Speaker, LogitechDeviceType.Speaker }
};
#endregion
@@ -48,17 +48,17 @@ namespace RGB.NET.Devices.Logitech
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.All);
- foreach (KeyValuePair data in dataSet)
+ foreach ((object key, Color color) in dataSet)
{
- int zone = (int)data.Key;
+ int zone = (int)key;
_LogitechGSDK.LogiLedSetLightingForTargetZone(_deviceType, zone,
- (int)Math.Round(data.Value.R * 100),
- (int)Math.Round(data.Value.G * 100),
- (int)Math.Round(data.Value.B * 100));
+ (int)MathF.Round(color.R * 100),
+ (int)MathF.Round(color.G * 100),
+ (int)MathF.Round(color.B * 100));
}
}
diff --git a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs
index cd09af0..c30d4a2 100644
--- a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs
+++ b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Msi
///
/// Represents a MSI RGB-device.
///
- internal interface IMsiRGBDevice : IRGBDevice
- {
- void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount);
- }
+ public interface IMsiRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs b/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs
index b2dffc0..6f6bf73 100644
--- a/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs
+++ b/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System;
using RGB.NET.Core;
using RGB.NET.Devices.Msi.Native;
@@ -34,10 +34,10 @@ namespace RGB.NET.Devices.Msi
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- foreach (KeyValuePair data in dataSet)
- _MsiSDK.SetLedColor(_deviceType, (int)data.Key, data.Value.GetR(), data.Value.GetG(), data.Value.GetB());
+ foreach ((object key, Color color) in dataSet)
+ _MsiSDK.SetLedColor(_deviceType, (int)key, color.GetR(), color.GetG(), color.GetB());
}
#endregion
diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs
index 3da1d27..888155b 100644
--- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs
+++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs
@@ -1,75 +1,23 @@
-using System.Collections.Generic;
-using System.Linq;
-using RGB.NET.Core;
+using RGB.NET.Core;
namespace RGB.NET.Devices.Msi
{
///
- ///
///
/// Represents a generic MSI-device. (keyboard, mouse, headset, mousepad).
///
public abstract class MsiRGBDevice : AbstractRGBDevice, IMsiRGBDevice
where TDeviceInfo : MsiRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected MsiDeviceUpdateQueue? DeviceUpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by MSI for the device.
- protected MsiRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
-
- #endregion
-
- #region Methods
-
- ///
- /// Initializes the device.
- ///
- public void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount)
- {
- DeviceUpdateQueue = updateQueue;
-
- InitializeLayout(ledCount);
- }
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout(int ledCount);
-
- ///
- protected override void UpdateLeds(IEnumerable ledsToUpdate)
- => DeviceUpdateQueue?.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int)));
-
- ///
- public override void Dispose()
- {
- try { DeviceUpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected MsiRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new MsiDeviceUpdateQueue(updateTrigger, info.MsiDeviceType))
+ { }
#endregion
}
diff --git a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs
index 8a41f90..629212c 100644
--- a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs
+++ b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs
@@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi
/// Initializes a new instance of the class.
///
/// The specific information provided by MSI for graphics cards.
- internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info)
- : base(info)
- { }
+ internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout(ledCount);
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout(int ledCount)
+ private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
{
diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs
index 5cf8b00..01f25ad 100644
--- a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs
+++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs
@@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi
/// Initializes a new instance of the class.
///
/// The specific information provided by MSI for the mainboard.
- internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info)
- : base(info)
- { }
+ internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout(ledCount);
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout(int ledCount)
+ private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
{
diff --git a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs
index dd4b702..79ad777 100644
--- a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs
+++ b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs
@@ -16,16 +16,17 @@ namespace RGB.NET.Devices.Msi
/// Initializes a new instance of the class.
///
/// The specific information provided by MSI for the mouse.
- internal MsiMouseRGBDevice(MsiRGBDeviceInfo info)
- : base(info)
- { }
+ internal MsiMouseRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout(ledCount);
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout(int ledCount)
+ private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
{
diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs
index a5b718f..00abd7b 100644
--- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs
+++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs
@@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.Msi.Exceptions;
using RGB.NET.Devices.Msi.Native;
@@ -15,7 +13,7 @@ namespace RGB.NET.Devices.Msi
///
/// Represents a device provider responsible for MSI devices.
///
- public class MsiDeviceProvider : IRGBDeviceProvider
+ public class MsiDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -37,20 +35,6 @@ namespace RGB.NET.Devices.Msi
///
public static List PossibleX64NativePaths { get; } = new() { "x64/MysticLight_SDK.dll" };
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for corsair devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -63,102 +47,58 @@ namespace RGB.NET.Devices.Msi
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(MsiDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- IsInitialized = false;
+ _MsiSDK.Reload();
- try
- {
- UpdateTrigger.Stop();
-
- _MsiSDK.Reload();
-
- IList devices = new List();
-
- int errorCode;
- if ((errorCode = _MsiSDK.Initialize()) != 0)
- ThrowMsiError(errorCode);
-
- if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0)
- ThrowMsiError(errorCode);
-
- for (int i = 0; i < deviceTypes.Length; i++)
- {
- try
- {
- string deviceType = deviceTypes[i];
- int ledCount = ledCounts[i];
-
- //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify)
- if (deviceType.Equals("MSI_MB"))
- {
- MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType);
- IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard"));
- motherboard.Initialize(updateQueue, ledCount);
- devices.Add(motherboard);
- }
- else if (deviceType.Equals("MSI_VGA"))
- {
- //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds
- //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info.
-
- MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType);
- IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard"));
- graphicscard.Initialize(updateQueue, ledCount);
- devices.Add(graphicscard);
- }
- else if (deviceType.Equals("MSI_MOUSE"))
- {
- //Hex3l: Every led under MSI_MOUSE should be a different mouse. Handling all the mouses together seems a good way to avoid overlapping of leds
- //Hex3l: The led name is the name of the mouse (e.g. msi CLUTCH GM11) we could provide it in device info.
-
- MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType);
- IMsiRGBDevice mouses = new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse"));
- mouses.Initialize(updateQueue, ledCount);
- devices.Add(mouses);
- }
-
- //TODO DarthAffe 22.02.2020: Add other devices
- }
- catch { if (throwExceptions) throw; }
- }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
- }
- catch
- {
- if (throwExceptions)
- throw;
- return false;
- }
-
- return true;
+ int errorCode;
+ if ((errorCode = _MsiSDK.Initialize()) != 0)
+ ThrowMsiError(errorCode);
}
- private void ThrowMsiError(int errorCode) => throw new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode));
+ protected override IEnumerable LoadDevices()
+ {
+ int errorCode;
+ if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0)
+ ThrowMsiError(errorCode);
+
+ for (int i = 0; i < deviceTypes.Length; i++)
+ {
+ string deviceType = deviceTypes[i];
+ int ledCount = ledCounts[i];
+
+ if (deviceType.Equals("MSI_MB"))
+ {
+ //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify)
+ yield return new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard"), ledCount, GetUpdateTrigger());
+ }
+ else if (deviceType.Equals("MSI_VGA"))
+ {
+ //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds
+ //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info.
+ yield return new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard"), ledCount, GetUpdateTrigger());
+ }
+ else if (deviceType.Equals("MSI_MOUSE"))
+ {
+ //Hex3l: Every led under MSI_MOUSE should be a different mouse. Handling all the mouses together seems a good way to avoid overlapping of leds
+ //Hex3l: The led name is the name of the mouse (e.g. msi CLUTCH GM11) we could provide it in device info.
+ yield return new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse"), ledCount, GetUpdateTrigger());
+ }
+ }
+ }
+
+ private void ThrowMsiError(int errorCode) => Throw(new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)));
///
- public void Dispose()
+ public override void Dispose()
{
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ base.Dispose();
try { _MsiSDK.UnloadMsiSDK(); }
catch { /* at least we tried */ }
diff --git a/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs
index 544df33..d717599 100644
--- a/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs
+++ b/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Novation
///
/// Represents a novation RGB-device.
///
- internal interface INovationRGBDevice : IRGBDevice
- {
- void Initialize(IDeviceUpdateTrigger updateTrigger);
- }
+ public interface INovationRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs
index 588e359..959e360 100644
--- a/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs
+++ b/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using RGB.NET.Core;
using Sanford.Multimedia.Midi;
@@ -26,10 +25,10 @@ namespace RGB.NET.Devices.Novation
#region Methods
///
- protected override ShortMessage CreateMessage(KeyValuePair data)
+ protected override ShortMessage CreateMessage(object key, in Color color)
{
- (byte mode, byte id) = ((byte, byte))data.Key;
- return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(data.Value)));
+ (byte mode, byte id) = ((byte, byte))key;
+ return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(color)));
}
///
@@ -38,9 +37,9 @@ namespace RGB.NET.Devices.Novation
///
/// The to convert.
/// The novation-representation of the .
- protected virtual int ConvertColor(Color color)
+ protected virtual int ConvertColor(in Color color)
{
- (double hue, double saturation, double value) = color.GetHSV();
+ (double hue, double _, double value) = color.GetHSV();
if ((hue >= 330) || (hue < 30))
return (int)Math.Ceiling(value * 3); // red with brightness 1, 2 or 3
diff --git a/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs
index 5ce5547..f29241b 100644
--- a/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs
+++ b/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using RGB.NET.Core;
using Sanford.Multimedia.Midi;
@@ -37,10 +36,10 @@ namespace RGB.NET.Devices.Novation
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- foreach (KeyValuePair data in dataSet)
- SendMessage(CreateMessage(data));
+ foreach ((object key, Color color) in dataSet)
+ SendMessage(CreateMessage(key, color));
}
///
@@ -59,7 +58,7 @@ namespace RGB.NET.Devices.Novation
///
/// The data set to create the message from.
/// The message created out of the data set.
- protected abstract ShortMessage? CreateMessage(KeyValuePair data);
+ protected abstract ShortMessage? CreateMessage(object key, in Color color);
///
public override void Dispose()
diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs
index 2976355..ffa5d9c 100644
--- a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs
+++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs
@@ -1,76 +1,45 @@
using System;
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.Novation
{
///
- ///
///
/// Represents a generic Novation-device. (launchpad).
///
public abstract class NovationRGBDevice : AbstractRGBDevice, INovationRGBDevice
where TDeviceInfo : NovationRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// The used to update this .
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected MidiUpdateQueue? UpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by Novation for the device.
- protected NovationRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
+ protected NovationRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, GetUpdateQueue(updateTrigger, info))
+ { }
#endregion
#region Methods
- ///
- /// Initializes the device.
- ///
- public void Initialize(IDeviceUpdateTrigger updateTrigger)
- {
- InitializeLayout();
-
- UpdateQueue = DeviceInfo.ColorCapabilities switch
+ private static UpdateQueue GetUpdateQueue(IDeviceUpdateTrigger updateTrigger, TDeviceInfo info) =>
+ info.ColorCapabilities switch
{
- NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId),
- NovationColorCapabilities.RGB => new RGBColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId),
+ NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, info.DeviceId),
+ NovationColorCapabilities.RGB => new RGBColorUpdateQueue(updateTrigger, info.DeviceId),
_ => throw new ArgumentOutOfRangeException()
};
- }
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout();
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
///
/// Resets the back to default.
///
- public virtual void Reset() => UpdateQueue?.Reset();
+ public virtual void Reset() => UpdateQueue.Reset();
///
///
@@ -78,9 +47,6 @@ namespace RGB.NET.Devices.Novation
{
Reset();
- try { UpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
base.Dispose();
}
diff --git a/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs
index 2998059..024fe58 100644
--- a/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs
+++ b/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using RGB.NET.Core;
using Sanford.Multimedia.Midi;
@@ -152,12 +151,12 @@ namespace RGB.NET.Devices.Novation
#region Methods
///
- protected override ShortMessage? CreateMessage(KeyValuePair data)
+ protected override ShortMessage? CreateMessage(object key, in Color color)
{
- (byte mode, byte id) = ((byte, byte))data.Key;
+ (byte mode, byte id) = ((byte, byte))key;
if (mode == 0x00) return null;
- return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(data.Value)));
+ return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(color)));
}
///
@@ -166,7 +165,7 @@ namespace RGB.NET.Devices.Novation
///
/// The to convert.
/// The novation-representation of the .
- protected virtual int ConvertColor(Color color)
+ protected virtual int ConvertColor(in Color color)
{
int bestVelocity = 0;
double bestMatchDistance = double.MaxValue;
diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs
index 39271aa..6be8738 100644
--- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs
+++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs
@@ -17,16 +17,17 @@ namespace RGB.NET.Devices.Novation
/// Initializes a new instance of the class.
///
/// The specific information provided by Novation for the launchpad
- internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info)
- : base(info)
- { }
+ internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
Dictionary mapping = GetDeviceMapping();
diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs
index 89ef95d..e0af6f2 100644
--- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs
+++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using RGB.NET.Core;
using Sanford.Multimedia.Midi;
@@ -14,7 +13,7 @@ namespace RGB.NET.Devices.Novation
///
/// Represents a device provider responsible for Novation devices.
///
- public class NovationDeviceProvider : IRGBDeviceProvider
+ public class NovationDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -24,20 +23,6 @@ namespace RGB.NET.Devices.Novation
///
public static NovationDeviceProvider Instance => _instance ?? new NovationDeviceProvider();
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for novation devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -50,73 +35,32 @@ namespace RGB.NET.Devices.Novation
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(NovationDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK() { }
+
+ protected override IEnumerable LoadDevices()
{
- IsInitialized = false;
-
- try
+ for (int index = 0; index < OutputDeviceBase.DeviceCount; index++)
{
- UpdateTrigger.Stop();
+ MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index);
+ if (outCaps.name == null) continue;
- IList devices = new List();
+ NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices))
+ .Cast()
+ .FirstOrDefault(x => x.GetDeviceId()?.ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant()) ?? false);
- if (loadFilter.HasFlag(RGBDeviceType.LedMatrix))
- for (int index = 0; index < OutputDeviceBase.DeviceCount; index++)
- {
- try
- {
- MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index);
- if (outCaps.name == null) continue;
+ if (deviceId == null) continue;
- NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices))
- .Cast()
- .FirstOrDefault(x => x.GetDeviceId()?.ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant()) ?? false);
+ NovationColorCapabilities colorCapability = deviceId.GetColorCapability();
+ if (colorCapability == NovationColorCapabilities.None) continue;
- if (deviceId == null) continue;
-
- NovationColorCapabilities colorCapability = deviceId.GetColorCapability();
- if (colorCapability == NovationColorCapabilities.None) continue;
-
- INovationRGBDevice device = new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping()));
- device.Initialize(UpdateTrigger);
- devices.Add(device);
- }
- catch { if (throwExceptions) throw; }
- }
-
- UpdateTrigger.Start();
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
+ yield return new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping()), GetUpdateTrigger());
}
- catch
- {
- if (throwExceptions)
- throw;
- return false;
- }
-
- return true;
- }
-
- ///
- public void Dispose()
- {
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
}
#endregion
diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs
index d4e614e..8a7a4b4 100644
--- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs
@@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the chroma link.
- internal RazerChromaLinkRGBDevice(RazerRGBDeviceInfo info)
- : base(info)
- { }
+ internal RazerChromaLinkRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new RazerChromaLinkUpdateQueue(updateTrigger))
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
for (int i = 0; i < _Defines.CHROMALINK_MAX_LEDS; i++)
AddLed(LedId.Custom1 + i, new Point(i * 11, 0), new Size(10, 10));
@@ -37,9 +38,6 @@ namespace RGB.NET.Devices.Razer
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1;
- ///
- protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerChromaLinkUpdateQueue(updateTrigger);
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs
index 513109f..e5f282f 100644
--- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -26,15 +25,15 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override IntPtr CreateEffectParams(Dictionary dataSet)
+ protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_Color[] colors = new _Color[_Defines.CHROMALINK_MAX_LEDS];
- foreach (KeyValuePair data in dataSet)
- colors[(int)data.Key] = new _Color(data.Value);
+ foreach ((object key, Color color) in dataSet)
+ colors[(int)key] = new _Color(color);
_ChromaLinkCustomEffect effectParams = new()
- { Color = colors };
+ { Color = colors };
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
Marshal.StructureToPtr(effectParams, ptr, false);
diff --git a/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs
index 9cf89ad..e04f35a 100644
--- a/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs
@@ -5,9 +5,6 @@ namespace RGB.NET.Devices.Razer
///
/// Represents a razer RGB-device.
///
- internal interface IRazerRGBDevice : IRGBDevice
- {
- void Initialize(IDeviceUpdateTrigger updateTrigger);
- void Reset();
- }
+ public interface IRazerRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs
index d254260..7b516dd 100644
--- a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.Razer
@@ -11,32 +10,15 @@ namespace RGB.NET.Devices.Razer
///
public abstract class RazerRGBDevice : AbstractRGBDevice, IRazerRGBDevice
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override RazerRGBDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected RazerUpdateQueue? UpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by razer for the device.
- protected RazerRGBDevice(RazerRGBDeviceInfo info)
+ protected RazerRGBDevice(RazerRGBDeviceInfo info, IUpdateQueue updateQueue)
+ : base(info, updateQueue)
{
- this.DeviceInfo = info;
-
RequiresFlush = true;
}
@@ -44,35 +26,8 @@ namespace RGB.NET.Devices.Razer
#region Methods
- ///
- /// Initializes the device.
- ///
- public void Initialize(IDeviceUpdateTrigger updateTrigger)
- {
- InitializeLayout();
-
- UpdateQueue = CreateUpdateQueue(updateTrigger);
- }
-
- ///
- /// Creates a specific for this device.
- ///
- /// The trigger used to update the queue.
- /// The for this device.
- protected abstract RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger);
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout();
-
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
- ///
- /// Resets the device.
- ///
- public void Reset() => UpdateQueue?.Reset();
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
///
public override void Dispose()
diff --git a/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs b/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs
index 2727bb9..e89aa9c 100644
--- a/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -32,7 +31,7 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
IntPtr effectParams = CreateEffectParams(dataSet);
Guid effectId = Guid.NewGuid();
@@ -68,7 +67,7 @@ namespace RGB.NET.Devices.Razer
///
/// The data to be updated.
/// An pointing to the effect parameter struct.
- protected abstract IntPtr CreateEffectParams(Dictionary dataSet);
+ protected abstract IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet);
#endregion
}
diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs
index 895d4c9..9ba325b 100644
--- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs
@@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the headset.
- internal RazerHeadsetRGBDevice(RazerRGBDeviceInfo info)
- : base(info)
- { }
+ internal RazerHeadsetRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new RazerHeadsetUpdateQueue(updateTrigger))
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
for (int i = 0; i < _Defines.HEADSET_MAX_LEDS; i++)
AddLed(LedId.Headset1 + i, new Point(i * 11, 0), new Size(10, 10));
@@ -37,9 +38,6 @@ namespace RGB.NET.Devices.Razer
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1;
- ///
- protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerHeadsetUpdateQueue(updateTrigger);
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs
index 1241487..a42e812 100644
--- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -26,16 +25,16 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override IntPtr CreateEffectParams(Dictionary dataSet)
+ protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_Color[] colors = new _Color[_Defines.HEADSET_MAX_LEDS];
- foreach (KeyValuePair data in dataSet)
- colors[(int)data.Key] = new _Color(data.Value);
+ foreach ((object key, Color color) in dataSet)
+ colors[(int)key] = new _Color(color);
_HeadsetCustomEffect effectParams = new()
- { Color = colors };
-
+ { Color = colors };
+
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
Marshal.StructureToPtr(effectParams, ptr, false);
diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs
index c21886d..0ba0e3e 100644
--- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs
@@ -25,16 +25,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the keyboard.
- internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info)
- : base(info)
- { }
+ internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new RazerKeyboardUpdateQueue(updateTrigger))
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
for (int i = 0; i < _Defines.KEYBOARD_MAX_ROW; i++)
for (int j = 0; j < _Defines.KEYBOARD_MAX_COLUMN; j++)
@@ -44,9 +45,6 @@ namespace RGB.NET.Devices.Razer
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape;
- ///
- protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeyboardUpdateQueue(updateTrigger);
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs
index 73abef0..1b1712c 100644
--- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -26,15 +25,14 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override IntPtr CreateEffectParams(Dictionary dataSet)
+ protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_Color[] colors = new _Color[_Defines.KEYBOARD_MAX_LEDS];
- foreach (KeyValuePair data in dataSet)
- colors[(int)data.Key] = new _Color(data.Value);
+ foreach ((object key, Color color) in dataSet)
+ colors[(int)key] = new _Color(color);
- _KeyboardCustomEffect effectParams = new()
- { Color = colors };
+ _KeyboardCustomEffect effectParams = new() { Color = colors };
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
Marshal.StructureToPtr(effectParams, ptr, false);
diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs
index 515fca4..ff9a39a 100644
--- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs
@@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the keypad.
- internal RazerKeypadRGBDevice(RazerRGBDeviceInfo info)
- : base(info)
- { }
+ internal RazerKeypadRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new RazerKeypadUpdateQueue(updateTrigger))
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
for (int i = 0; i < _Defines.KEYPAD_MAX_ROW; i++)
for (int j = 0; j < _Defines.KEYPAD_MAX_COLUMN; j++)
@@ -38,9 +39,6 @@ namespace RGB.NET.Devices.Razer
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1;
- ///
- protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeypadUpdateQueue(updateTrigger);
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs
index b13ef7f..69885ca 100644
--- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -26,15 +25,14 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override IntPtr CreateEffectParams(Dictionary dataSet)
+ protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_Color[] colors = new _Color[_Defines.KEYPAD_MAX_LEDS];
- foreach (KeyValuePair data in dataSet)
- colors[(int)data.Key] = new _Color(data.Value);
+ foreach ((object key, Color color) in dataSet)
+ colors[(int)key] = new _Color(color);
- _KeypadCustomEffect effectParams = new()
- { Color = colors };
+ _KeypadCustomEffect effectParams = new() { Color = colors };
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
Marshal.StructureToPtr(effectParams, ptr, false);
diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs
index 0fd0565..8cddb64 100644
--- a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs
@@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the mouse.
- internal RazerMouseRGBDevice(RazerRGBDeviceInfo info)
- : base(info)
- { }
+ internal RazerMouseRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new RazerMouseUpdateQueue(updateTrigger))
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
for (int i = 0; i < _Defines.MOUSE_MAX_ROW; i++)
for (int j = 0; j < _Defines.MOUSE_MAX_COLUMN; j++)
@@ -38,9 +39,6 @@ namespace RGB.NET.Devices.Razer
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1;
- ///
- protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMouseUpdateQueue(updateTrigger);
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs
index 17d00b8..5e479bf 100644
--- a/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -26,15 +25,14 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override IntPtr CreateEffectParams(Dictionary dataSet)
+ protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_Color[] colors = new _Color[_Defines.MOUSE_MAX_LEDS];
- foreach (KeyValuePair data in dataSet)
- colors[(int)data.Key] = new _Color(data.Value);
+ foreach ((object key, Color color) in dataSet)
+ colors[(int)key] = new _Color(color);
- _MouseCustomEffect effectParams = new()
- { Color = colors };
+ _MouseCustomEffect effectParams = new() { Color = colors };
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
Marshal.StructureToPtr(effectParams, ptr, false);
diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs
index e561a33..c9ea090 100644
--- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs
+++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs
@@ -19,16 +19,17 @@ namespace RGB.NET.Devices.Razer
/// Initializes a new instance of the class.
///
/// The specific information provided by CUE for the mousepad.
- internal RazerMousepadRGBDevice(RazerRGBDeviceInfo info)
- : base(info)
- { }
+ internal RazerMousepadRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new RazerMousepadUpdateQueue(updateTrigger))
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
for (int i = 0; i < _Defines.MOUSEPAD_MAX_LEDS; i++)
AddLed(LedId.Mousepad1 + i, new Point(i * 11, 0), new Size(10, 10));
@@ -36,10 +37,6 @@ namespace RGB.NET.Devices.Razer
///
protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1;
-
- ///
- protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMousepadUpdateQueue(updateTrigger);
-
#endregion
}
}
diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs
index b9aea89..d918152 100644
--- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs
+++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.Native;
@@ -26,15 +25,14 @@ namespace RGB.NET.Devices.Razer
#region Methods
///
- protected override IntPtr CreateEffectParams(Dictionary dataSet)
+ protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet)
{
_Color[] colors = new _Color[_Defines.MOUSEPAD_MAX_LEDS];
- foreach (KeyValuePair data in dataSet)
- colors[(int)data.Key] = new _Color(data.Value);
+ foreach ((object key, Color color) in dataSet)
+ colors[(int)key] = new _Color(color);
- _MousepadCustomEffect effectParams = new()
- { Color = colors };
+ _MousepadCustomEffect effectParams = new() { Color = colors };
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams));
Marshal.StructureToPtr(effectParams, ptr, false);
diff --git a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs
index b4c9944..3a7838b 100644
--- a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs
+++ b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.Razer.HID;
@@ -16,7 +15,7 @@ namespace RGB.NET.Devices.Razer
///
/// Represents a device provider responsible for razer devices.
///
- public class RazerDeviceProvider : IRGBDeviceProvider
+ public class RazerDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -30,34 +29,19 @@ namespace RGB.NET.Devices.Razer
/// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications.
/// The first match will be used.
///
- public static List PossibleX86NativePaths { get; } = new() {@"%systemroot%\SysWOW64\RzChromaSDK.dll"};
+ public static List PossibleX86NativePaths { get; } = new() { @"%systemroot%\SysWOW64\RzChromaSDK.dll" };
///
/// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications.
/// The first match will be used.
///
- public static List PossibleX64NativePaths { get; } =
- new() {@"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll"};
-
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
+ public static List PossibleX64NativePaths { get; } = new() { @"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll" };
///
/// Forces to load the devices represented by the emulator even if they aren't reported to exist.
///
public bool LoadEmulatorDevices { get; set; } = false;
- ///
- /// The used to trigger the updates for razer devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -68,89 +52,65 @@ namespace RGB.NET.Devices.Razer
/// Thrown if this constructor is called even if there is already an instance of this class.
public RazerDeviceProvider()
{
- if (_instance != null)
- throw new InvalidOperationException($"There can be only one instance of type {nameof(RazerDeviceProvider)}");
+ if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(RazerDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- if (IsInitialized)
- TryUnInit();
+ TryUnInit();
- IsInitialized = false;
+ _RazerSDK.Reload();
- try
+ RazerError error;
+ if (((error = _RazerSDK.Init()) != RazerError.Success) && Enum.IsDefined(typeof(RazerError), error)) //HACK DarthAffe 08.02.2018: The x86-SDK seems to have a problem here ...
+ ThrowRazerError(error);
+ }
+
+ protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter)
+ {
+ DeviceChecker.LoadDeviceList(loadFilter);
+
+ IList devices = base.GetLoadedDevices(loadFilter).ToList();
+
+ if (LoadEmulatorDevices)
{
- UpdateTrigger.Stop();
-
- _RazerSDK.Reload();
-
- RazerError error;
- if (((error = _RazerSDK.Init()) != RazerError.Success)
- && Enum.IsDefined(typeof(RazerError), error)) //HACK DarthAffe 08.02.2018: The x86-SDK seems to have a problem here ...
- ThrowRazerError(error);
-
- IList devices = new List();
- DeviceChecker.LoadDeviceList(loadFilter);
-
- foreach ((var model, RGBDeviceType deviceType, int _) in DeviceChecker.ConnectedDevices)
- {
- RazerRGBDevice device = deviceType switch
- {
- RGBDeviceType.Keyboard => new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(model)),
- RGBDeviceType.Mouse => new RazerMouseRGBDevice(new RazerRGBDeviceInfo(deviceType, model)),
- RGBDeviceType.Headset => new RazerHeadsetRGBDevice(new RazerRGBDeviceInfo(deviceType, model)),
- RGBDeviceType.Mousepad => new RazerMousepadRGBDevice(new RazerRGBDeviceInfo(deviceType, model)),
- RGBDeviceType.Keypad => new RazerKeypadRGBDevice(new RazerRGBDeviceInfo(deviceType, model)),
- RGBDeviceType.Unknown => new RazerChromaLinkRGBDevice(new RazerRGBDeviceInfo(deviceType, model)),
- _ => throw new RGBDeviceException($"Razer SDK does not support {deviceType} devices")
- };
-
- devices.Add(device);
- }
-
- if (LoadEmulatorDevices)
- {
- if (loadFilter.HasFlag(RGBDeviceType.Keyboard) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Keyboard))
- devices.Add(new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo("Emulator Keyboard")));
- if (loadFilter.HasFlag(RGBDeviceType.Mouse) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Mouse))
- devices.Add(new RazerMouseRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Mouse, "Emulator Mouse")));
- if (loadFilter.HasFlag(RGBDeviceType.Headset) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Headset))
- devices.Add(new RazerHeadsetRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Headset, "Emulator Headset")));
- if (loadFilter.HasFlag(RGBDeviceType.Mousepad) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Mousepad))
- devices.Add(new RazerMousepadRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Mousepad, "Emulator Mousepad")));
- if (loadFilter.HasFlag(RGBDeviceType.Keypad) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Keypad))
- devices.Add(new RazerKeypadRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Keypad, "Emulator Keypad")));
- if (loadFilter.HasFlag(RGBDeviceType.Unknown) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Unknown))
- devices.Add(new RazerChromaLinkRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Unknown, "Emulator Chroma Link")));
- }
-
- foreach (var rgbDevice in devices)
- {
- RazerRGBDevice device = (RazerRGBDevice)rgbDevice;
- device.Initialize(UpdateTrigger);
- }
-
- UpdateTrigger.Start();
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
- }
- catch
- {
- TryUnInit();
- if (throwExceptions) throw;
- return false;
+ if (loadFilter.HasFlag(RGBDeviceType.Keyboard) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Keyboard))
+ devices.Add(new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo("Emulator Keyboard"), GetUpdateTrigger()));
+ if (loadFilter.HasFlag(RGBDeviceType.Mouse) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Mouse))
+ devices.Add(new RazerMouseRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Mouse, "Emulator Mouse"), GetUpdateTrigger()));
+ if (loadFilter.HasFlag(RGBDeviceType.Headset) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Headset))
+ devices.Add(new RazerHeadsetRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Headset, "Emulator Headset"), GetUpdateTrigger()));
+ if (loadFilter.HasFlag(RGBDeviceType.Mousepad) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Mousepad))
+ devices.Add(new RazerMousepadRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Mousepad, "Emulator Mousepad"), GetUpdateTrigger()));
+ if (loadFilter.HasFlag(RGBDeviceType.Keypad) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Keypad))
+ devices.Add(new RazerKeypadRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Keypad, "Emulator Keypad"), GetUpdateTrigger()));
+ if (loadFilter.HasFlag(RGBDeviceType.Unknown) && devices.All(d => d.DeviceInfo.DeviceType != RGBDeviceType.Unknown))
+ devices.Add(new RazerChromaLinkRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Unknown, "Emulator Chroma Link"), GetUpdateTrigger()));
}
- return true;
+ return devices;
+ }
+
+ protected override IEnumerable LoadDevices()
+ {
+ foreach ((var model, RGBDeviceType deviceType, int _) in DeviceChecker.ConnectedDevices)
+ {
+ yield return deviceType switch
+ {
+ RGBDeviceType.Keyboard => new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(model), GetUpdateTrigger()),
+ RGBDeviceType.Mouse => new RazerMouseRGBDevice(new RazerRGBDeviceInfo(deviceType, model), GetUpdateTrigger()),
+ RGBDeviceType.Headset => new RazerHeadsetRGBDevice(new RazerRGBDeviceInfo(deviceType, model), GetUpdateTrigger()),
+ RGBDeviceType.Mousepad => new RazerMousepadRGBDevice(new RazerRGBDeviceInfo(deviceType, model), GetUpdateTrigger()),
+ RGBDeviceType.Keypad => new RazerKeypadRGBDevice(new RazerRGBDeviceInfo(deviceType, model), GetUpdateTrigger()),
+ RGBDeviceType.Unknown => new RazerChromaLinkRGBDevice(new RazerRGBDeviceInfo(deviceType, model), GetUpdateTrigger()),
+ _ => throw new RGBDeviceException($"Razer SDK does not support {deviceType} devices")
+ };
+ }
}
private void ThrowRazerError(RazerError errorCode) => throw new RazerException(errorCode);
@@ -158,26 +118,13 @@ namespace RGB.NET.Devices.Razer
private void TryUnInit()
{
try { _RazerSDK.UnInit(); }
- catch
- { /* We tried our best */
- }
+ catch { /* We tried our best */ }
}
///
- public void Dispose()
+ public override void Dispose()
{
- try { UpdateTrigger.Dispose(); }
- catch
- { /* at least we tried */
- }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch
- { /* at least we tried */
- }
-
- Devices = Enumerable.Empty();
+ base.Dispose();
TryUnInit();
diff --git a/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs
index 57364d9..0270a27 100644
--- a/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs
+++ b/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using RGB.NET.Core;
+using RGB.NET.Core;
namespace RGB.NET.Devices.SteelSeries
{
@@ -7,7 +6,5 @@ namespace RGB.NET.Devices.SteelSeries
/// Represents a steelseries RGB-device.
///
internal interface ISteelSeriesRGBDevice : IRGBDevice
- {
- void Initialize(UpdateQueue updateQueue, Dictionary ledMapping);
- }
+ { }
}
diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs
index 25de272..b3b966d 100644
--- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs
+++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System;
using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.SteelSeries.API;
@@ -44,8 +44,8 @@ namespace RGB.NET.Devices.SteelSeries
}
///
- protected override void Update(Dictionary dataSet)
- => SteelSeriesSDK.UpdateLeds(_deviceType, dataSet.Select(x => (((SteelSeriesLedId)x.Key).GetAPIName(), x.Value.ToIntArray())).Where(x => x.Item1 != null).ToList()!);
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
+ => SteelSeriesSDK.UpdateLeds(_deviceType, dataSet.ToArray().Select(x => (((SteelSeriesLedId)x.key).GetAPIName(), x.color.ToIntArray())).Where(x => x.Item1 != null).ToList()!);
#endregion
}
diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs
index 1f31857..d97bb12 100644
--- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs
+++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.SteelSeries
@@ -13,19 +12,7 @@ namespace RGB.NET.Devices.SteelSeries
{
#region Properties & Fields
- private Dictionary _ledMapping = new();
-
- ///
- ///
- /// Gets information about the .
- ///
- public override SteelSeriesRGBDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected UpdateQueue? UpdateQueue { get; set; }
+ private readonly Dictionary _ledMapping;
#endregion
@@ -35,34 +22,30 @@ namespace RGB.NET.Devices.SteelSeries
/// Initializes a new instance of the class.
///
/// The generic information provided by SteelSeries for the device.
- internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info)
+ internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info, string apiName, Dictionary ledMapping, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new SteelSeriesDeviceUpdateQueue(updateTrigger, apiName))
{
- this.DeviceInfo = info;
+ this._ledMapping = ledMapping;
+
+ InitializeLayout();
}
#endregion
#region Methods
- ///
- /// Initializes the device.
- ///
- void ISteelSeriesRGBDevice.Initialize(UpdateQueue updateQueue, Dictionary ledMapping)
+ private void InitializeLayout()
{
- _ledMapping = ledMapping;
-
int counter = 0;
- foreach (KeyValuePair mapping in ledMapping)
+ foreach (KeyValuePair mapping in _ledMapping)
AddLed(mapping.Key, new Point((counter++) * 10, 0), new Size(10, 10));
-
- UpdateQueue = updateQueue;
}
///
protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId];
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
///
public override void Dispose()
diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
index f42885f..f1793fd 100644
--- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
+++ b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.SteelSeries.API;
using RGB.NET.Devices.SteelSeries.HID;
@@ -12,7 +10,7 @@ namespace RGB.NET.Devices.SteelSeries
///
/// Represents a device provider responsible for SteelSeries- devices.
///
- public class SteelSeriesDeviceProvider : IRGBDeviceProvider
+ public class SteelSeriesDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -22,20 +20,6 @@ namespace RGB.NET.Devices.SteelSeries
///
public static SteelSeriesDeviceProvider Instance => _instance ?? new SteelSeriesDeviceProvider();
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for SteelSeries devices.
- ///
- public SteelSeriesDeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -48,67 +32,41 @@ namespace RGB.NET.Devices.SteelSeries
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SteelSeriesDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new SteelSeriesDeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- try
- {
- IsInitialized = false;
-
- UpdateTrigger.Stop();
-
- if (!SteelSeriesSDK.IsInitialized)
- SteelSeriesSDK.Initialize();
-
- IList devices = new List();
- DeviceChecker.LoadDeviceList(loadFilter);
-
- try
- {
- foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, Dictionary ledMapping) in DeviceChecker.ConnectedDevices)
- {
- ISteelSeriesRGBDevice device = new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(deviceType, model, steelSeriesDeviceType));
- string apiName = steelSeriesDeviceType.GetAPIName() ?? throw new RGBDeviceException($"Missing API-name for device {model}");
- SteelSeriesDeviceUpdateQueue updateQueue = new(UpdateTrigger, apiName);
- device.Initialize(updateQueue, ledMapping);
- devices.Add(device);
- }
- }
- catch { if (throwExceptions) throw; }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
- }
- catch
- {
- IsInitialized = false;
- if (throwExceptions) throw;
- return false;
- }
-
- return true;
+ if (!SteelSeriesSDK.IsInitialized)
+ SteelSeriesSDK.Initialize();
}
-
- ///
- public void Dispose()
- {
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter)
+ {
+ DeviceChecker.LoadDeviceList(loadFilter);
+
+ return base.GetLoadedDevices(loadFilter);
+ }
+
+ protected override IEnumerable LoadDevices()
+ {
+ foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, Dictionary ledMapping) in DeviceChecker.ConnectedDevices)
+ {
+ string? apiName = steelSeriesDeviceType.GetAPIName();
+ if (apiName == null)
+ Throw(new RGBDeviceException($"Missing API-name for device {model}"));
+ else
+ yield return new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(deviceType, model, steelSeriesDeviceType), apiName, ledMapping, GetUpdateTrigger());
+ }
+ }
+
+ ///
+ public override void Dispose()
+ {
+ base.Dispose();
try { SteelSeriesSDK.Dispose(); }
catch { /* shit happens */ }
diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs
index 1a9f186..545dccd 100644
--- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs
+++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs
@@ -8,22 +8,12 @@ using RGB.NET.Core;
namespace RGB.NET.Devices.WS281X.Arduino
{
// ReSharper disable once InconsistentNaming
- ///
///
/// Represents an arduino WS2812 device.
///
public class ArduinoWS2812USBDevice : AbstractRGBDevice, ILedStripe
{
#region Properties & Fields
-
- ///
- /// Gets the update queue performing updates for this device.
- ///
- public ArduinoWS2812USBUpdateQueue UpdateQueue { get; }
-
- ///
- public override ArduinoWS2812USBDeviceInfo DeviceInfo { get; }
-
///
/// Gets the channel (as defined in the arduino-sketch) this device is attached to.
///
@@ -39,18 +29,19 @@ namespace RGB.NET.Devices.WS281X.Arduino
/// The update trigger used by this queue.
/// The update queue performing updates for this device.
/// The channel (as defined in the arduino-sketch) this device is attached to.
- public ArduinoWS2812USBDevice(ArduinoWS2812USBDeviceInfo deviceInfo, ArduinoWS2812USBUpdateQueue updateQueue, int channel)
+ public ArduinoWS2812USBDevice(ArduinoWS2812USBDeviceInfo deviceInfo, ArduinoWS2812USBUpdateQueue updateQueue, int channel, int ledCount)
+ : base(deviceInfo, updateQueue)
{
- this.DeviceInfo = deviceInfo;
- this.UpdateQueue = updateQueue;
this.Channel = channel;
+
+ InitializeLayout(ledCount);
}
#endregion
#region Methods
- internal void Initialize(int ledCount)
+ private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10));
@@ -63,16 +54,7 @@ namespace RGB.NET.Devices.WS281X.Arduino
protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : Enumerable.Empty();
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
- ///
- public override void Dispose()
- {
- try { UpdateQueue.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}
diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs
index ebe5a76..9263e64 100644
--- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs
+++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs
@@ -50,9 +50,9 @@ namespace RGB.NET.Devices.WS281X.Arduino
}
///
- protected override IEnumerable GetCommands(Dictionary dataSet)
+ protected override IEnumerable GetCommands(IList<(object key, Color color)> dataSet)
{
- foreach (IGrouping channelData in dataSet.Select(x => (((int channel, int key))x.Key, x.Value))
+ foreach (IGrouping channelData in dataSet.Select(x => (((int channel, int key))x.key, x.color))
.GroupBy(x => x.Item1.channel))
{
int channel = channelData.Key;
diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs
index c6aa63c..adbf0bf 100644
--- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs
+++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs
@@ -67,15 +67,14 @@ namespace RGB.NET.Devices.WS281X.Arduino
///
public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger)
{
+ //TODO DarthAffe 04.03.2021: one queue per device
ArduinoWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection);
IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels();
int counter = 0;
foreach ((int channel, int ledCount) in channels)
{
string name = string.Format(Name ?? $"Arduino WS2812 USB ({Port}) [{{0}}]", ++counter);
- ArduinoWS2812USBDevice device = new(new ArduinoWS2812USBDeviceInfo(name), queue, channel);
- device.Initialize(ledCount);
- yield return device;
+ yield return new ArduinoWS2812USBDevice(new ArduinoWS2812USBDeviceInfo(name), queue, channel, ledCount);
}
}
diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs
index 6e2d813..9ff359d 100644
--- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs
+++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs
@@ -2,13 +2,12 @@
// ReSharper disable UnusedMember.Global
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.WS281X.Bitwizard
{
// ReSharper disable once InconsistentNaming
- ///
+ ///
///
/// Represents an bitwizard WS2812 USB device.
///
@@ -18,14 +17,6 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
private readonly int _ledOffset;
- ///
- /// Gets the update queue performing updates for this device.
- ///
- public BitwizardWS2812USBUpdateQueue UpdateQueue { get; }
-
- ///
- public override BitwizardWS2812USBDeviceInfo DeviceInfo { get; }
-
#endregion
#region Constructors
@@ -35,19 +26,18 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
///
/// The update trigger used by this queue.
/// The update queue performing updates for this device.
- public BitwizardWS2812USBDevice(BitwizardWS2812USBDeviceInfo deviceInfo, BitwizardWS2812USBUpdateQueue updateQueue, int ledOffset)
+ public BitwizardWS2812USBDevice(BitwizardWS2812USBDeviceInfo deviceInfo, BitwizardWS2812USBUpdateQueue updateQueue, int ledOffset, int ledCount)
+ : base(deviceInfo, updateQueue)
{
- this.DeviceInfo = deviceInfo;
- this.UpdateQueue = updateQueue;
-
this._ledOffset = ledOffset;
+ InitializeLayout(ledCount);
}
#endregion
#region Methods
- internal void Initialize(int ledCount)
+ private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10));
@@ -57,16 +47,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
protected override object GetLedCustomData(LedId ledId) => _ledOffset + ((int)ledId - (int)LedId.LedStripe1);
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
- ///
- public override void Dispose()
- {
- try { UpdateQueue.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}
diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs
index 242b6d1..623f0fe 100644
--- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs
+++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs
@@ -36,7 +36,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
}
///
- protected override IEnumerable GetCommands(Dictionary dataSet)
+ protected override IEnumerable GetCommands(IList<(object key, Color color)> dataSet)
{
foreach ((object key, Color value) in dataSet)
yield return $"pix {(int)key} {value.AsRGBHexString(false)}";
diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs
index 3a46ac1..558548a 100644
--- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs
+++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs
@@ -36,15 +36,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
///
public string? Name { get; set; }
- ///
- /// Gets or sets the pin sed to control the leds.
- ///
- public int Pin { get; set; } = 0;
-
- ///
- /// Gets or sets the amount of leds of this device.
- ///
- public int StripLength { get; set; } = 384;
+ public List<(int pin, int stripLength)> Strips { get; } = new();
///
/// Gets or sets the amount of leds controlled by one pin.
@@ -60,9 +52,11 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
/// Initializes a new instance of the class.
///
/// The serial connection used for the device.
- public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection)
+ public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection, params (int pin, int stripLength)[] strips)
{
this.SerialConnection = serialConnection;
+
+ Strips.AddRange(strips);
}
///
@@ -70,9 +64,11 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
///
/// The name of the serial-port to connect to.
/// The baud-rate of the serial-connection.
- public BitwizardWS281XDeviceDefinition(string port, int baudRate = 115200)
+ public BitwizardWS281XDeviceDefinition(string port, int baudRate = 115200, params (int pin, int stripLength)[] strips)
{
SerialConnection = new SerialPortConnection(port, baudRate);
+
+ Strips.AddRange(strips);
}
#endregion
@@ -82,12 +78,13 @@ namespace RGB.NET.Devices.WS281X.Bitwizard
///
public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger)
{
- BitwizardWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection);
- string name = Name ?? $"Bitwizard WS2812 USB ({Port})";
- int ledOffset = Pin * MaxStripLength;
- BitwizardWS2812USBDevice device = new(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset);
- device.Initialize(StripLength);
- yield return device;
+ foreach ((int pin, int stripLength) in Strips)
+ {
+ BitwizardWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection);
+ string name = Name ?? $"Bitwizard WS2812 USB ({Port}) Pin {pin}";
+ int ledOffset = pin * MaxStripLength;
+ yield return new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset, stripLength);
+ }
}
#endregion
diff --git a/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs b/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs
index b3f2b4e..7bee162 100644
--- a/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs
+++ b/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using RGB.NET.Core;
namespace RGB.NET.Devices.WS281X
@@ -56,9 +57,9 @@ namespace RGB.NET.Devices.WS281X
}
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- foreach (TData command in GetCommands(dataSet))
+ foreach (TData command in GetCommands(dataSet.ToArray()))
{
SerialConnection.ReadTo(Prompt);
SendCommand(command);
@@ -70,7 +71,7 @@ namespace RGB.NET.Devices.WS281X
///
/// The set of data that needs to be updated.
/// The commands to be sent.
- protected abstract IEnumerable GetCommands(Dictionary dataSet);
+ protected abstract IEnumerable GetCommands(IList<(object key, Color color)> dataSet);
///
/// Sends a command as a string followed by a line-break to the device.
diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs
index b471e17..3e59cd1 100644
--- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs
+++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs
@@ -16,14 +16,6 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
{
#region Properties & Fields
- ///
- /// Gets the update queue performing updates for this device.
- ///
- public NodeMCUWS2812USBUpdateQueue UpdateQueue { get; }
-
- ///
- public override NodeMCUWS2812USBDeviceInfo DeviceInfo { get; }
-
///
/// Gets the channel (as defined in the NodeMCU-sketch) this device is attached to.
///
@@ -39,18 +31,19 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
/// The update trigger used by this queue.
/// The update queue performing updates for this device.
/// The channel (as defined in the NodeMCU-sketch) this device is attached to.
- public NodeMCUWS2812USBDevice(NodeMCUWS2812USBDeviceInfo deviceInfo, NodeMCUWS2812USBUpdateQueue updateQueue, int channel)
+ public NodeMCUWS2812USBDevice(NodeMCUWS2812USBDeviceInfo info, NodeMCUWS2812USBUpdateQueue updateQueue, int channel, int ledCount)
+ : base(info, updateQueue)
{
- this.DeviceInfo = deviceInfo;
- this.UpdateQueue = updateQueue;
this.Channel = channel;
+
+ InitializeLayout(ledCount);
}
#endregion
#region Methods
- internal void Initialize(int ledCount)
+ private void InitializeLayout(int ledCount)
{
for (int i = 0; i < ledCount; i++)
AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10));
@@ -63,16 +56,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : Enumerable.Empty();
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
-
- ///
- public override void Dispose()
- {
- try { UpdateQueue.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}
diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs
index 2c020c4..ef25700 100644
--- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs
+++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs
@@ -77,10 +77,9 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
}
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- foreach (IGrouping channelData in dataSet.Select(x => (((int channel, int key))x.Key, x.Value))
- .GroupBy(x => x.Item1.channel))
+ foreach (IGrouping channelData in dataSet.ToArray().Select(x => (((int channel, int key))x.key, x.color)).GroupBy(x => x.Item1.channel))
{
byte[] buffer = GetBuffer(channelData);
_sendDataAction(buffer);
@@ -98,7 +97,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
_udpClient?.Send(buffer, buffer.Length);
}
- private byte[] GetBuffer(IGrouping data)
+ private byte[] GetBuffer(IGrouping data)
{
int channel = data.Key;
byte[] buffer = _dataBuffer[channel];
@@ -106,8 +105,8 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
buffer[0] = GetSequenceNumber(channel);
buffer[1] = (byte)channel;
int i = 2;
- foreach ((byte _, byte r, byte g, byte b) in data.OrderBy(x => x.Item1.key)
- .Select(x => x.Value.GetRGBBytes()))
+ foreach ((byte _, byte r, byte g, byte b) in data.OrderBy(x => x.identifier.key)
+ .Select(x => x.color.GetRGBBytes()))
{
buffer[i++] = r;
buffer[i++] = g;
diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs
index b87f39e..04d34ff 100644
--- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs
+++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs
@@ -72,9 +72,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU
foreach ((int channel, int ledCount) in channels)
{
string name = string.Format(Name ?? $"NodeMCU WS2812 WIFI ({Hostname}) [{{0}}]", ++counter);
- NodeMCUWS2812USBDevice device = new(new NodeMCUWS2812USBDeviceInfo(name), queue, channel);
- device.Initialize(ledCount);
- yield return device;
+ yield return new NodeMCUWS2812USBDevice(new NodeMCUWS2812USBDeviceInfo(name), queue, channel, ledCount);
}
}
diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs
index aeee841..deac3ae 100644
--- a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs
+++ b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs
@@ -2,8 +2,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using RGB.NET.Core;
namespace RGB.NET.Devices.WS281X
@@ -13,7 +11,7 @@ namespace RGB.NET.Devices.WS281X
/// Represents a device provider responsible for WS2812B- and WS2811-Led-devices.
///
// ReSharper disable once InconsistentNaming
- public class WS281XDeviceProvider : IRGBDeviceProvider
+ public class WS281XDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -23,12 +21,6 @@ namespace RGB.NET.Devices.WS281X
///
public static WS281XDeviceProvider Instance => _instance ?? new WS281XDeviceProvider();
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
///
/// Gets a list of all defined device-definitions.
///
@@ -36,11 +28,6 @@ namespace RGB.NET.Devices.WS281X
// ReSharper disable once ReturnTypeCanBeEnumerable.Global
public List DeviceDefinitions { get; } = new();
- ///
- /// The used to trigger the updates for corsair devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -53,8 +40,6 @@ namespace RGB.NET.Devices.WS281X
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WS281XDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
@@ -68,49 +53,23 @@ namespace RGB.NET.Devices.WS281X
// ReSharper disable once UnusedMember.Global
public void AddDeviceDefinition(IWS281XDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition);
- ///
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false)
+ protected override void InitializeSDK() { }
+
+ protected override IEnumerable LoadDevices()
{
- IsInitialized = false;
-
- try
+ int i = 0;
+ foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions)
{
- UpdateTrigger.Stop();
-
- List devices = new();
- foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions)
- {
- try
- {
- devices.AddRange(deviceDefinition.CreateDevices(UpdateTrigger));
- }
- catch { if (throwExceptions) throw; }
- }
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
+ IDeviceUpdateTrigger updateTrigger = GetUpdateTrigger(i++);
+ foreach (IRGBDevice device in deviceDefinition.CreateDevices(updateTrigger))
+ yield return device;
}
- catch
- {
- if (throwExceptions)
- throw;
- return false;
- }
-
- return true;
}
-
- ///
- public void Dispose()
- {
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */}
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ ///
+ public override void Dispose()
+ {
+ base.Dispose();
DeviceDefinitions.Clear();
}
diff --git a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs
index b7356eb..932aff9 100644
--- a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs
+++ b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs
@@ -5,8 +5,6 @@ namespace RGB.NET.Devices.Wooting.Generic
///
/// Represents a Wooting RGB-device.
///
- internal interface IWootingRGBDevice : IRGBDevice
- {
- void Initialize(IDeviceUpdateTrigger updateTrigger);
- }
+ public interface IWootingRGBDevice : IRGBDevice
+ { }
}
diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs
index 4f843a8..b7a4d22 100644
--- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs
+++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs
@@ -10,60 +10,15 @@ namespace RGB.NET.Devices.Wooting.Generic
public abstract class WootingRGBDevice : AbstractRGBDevice, IWootingRGBDevice
where TDeviceInfo : WootingRGBDeviceInfo
{
- #region Properties & Fields
-
- ///
- ///
- /// Gets information about the .
- ///
- public override TDeviceInfo DeviceInfo { get; }
-
- ///
- /// Gets or sets the update queue performing updates for this device.
- ///
- // ReSharper disable once MemberCanBePrivate.Global
- protected UpdateQueue? UpdateQueue { get; set; }
-
- #endregion
-
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The generic information provided by Wooting for the device.
- protected WootingRGBDevice(TDeviceInfo info)
- {
- this.DeviceInfo = info;
- }
-
- #endregion
-
- #region Methods
-
- ///
- /// Initializes the device.
- ///
- public void Initialize(IDeviceUpdateTrigger updateTrigger)
- {
- InitializeLayout();
-
- UpdateQueue = new WootingUpdateQueue(updateTrigger);
- }
-
- ///
- /// Initializes the and of the device.
- ///
- protected abstract void InitializeLayout();
-
- ///
- public override void Dispose()
- {
- try { UpdateQueue?.Dispose(); }
- catch { /* at least we tried */ }
-
- base.Dispose();
- }
+ protected WootingRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, new WootingUpdateQueue(updateTrigger))
+ { }
#endregion
}
diff --git a/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs b/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs
index 8f89610..da4b3bf 100644
--- a/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs
+++ b/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System;
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Native;
@@ -26,17 +26,17 @@ namespace RGB.NET.Devices.Wooting.Generic
#region Methods
///
- protected override void Update(Dictionary dataSet)
+ protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet)
{
- foreach (KeyValuePair data in dataSet)
+ foreach ((object key, Color color) in dataSet)
{
- (int row, int column) = ((int, int))data.Key;
- _WootingSDK.ArraySetSingle((byte)row, (byte)column, data.Value.GetR(), data.Value.GetG(), data.Value.GetB());
+ (int row, int column) = ((int, int))key;
+ _WootingSDK.ArraySetSingle((byte)row, (byte)column, color.GetR(), color.GetG(), color.GetB());
}
_WootingSDK.ArrayUpdateKeyboard();
}
-
+
#endregion
}
}
diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs
index 7994145..2f7ac90 100644
--- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs
+++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Linq;
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Enum;
using RGB.NET.Devices.Wooting.Generic;
@@ -25,16 +24,17 @@ namespace RGB.NET.Devices.Wooting.Keyboard
/// Initializes a new instance of the class.
///
/// The specific information provided by Wooting for the keyboard
- internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info)
- : base(info)
- { }
+ internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger)
+ : base(info, updateTrigger)
+ {
+ InitializeLayout();
+ }
#endregion
#region Methods
- ///
- protected override void InitializeLayout()
+ private void InitializeLayout()
{
//TODO DarthAffe 13.02.2021: Check how the mapping can work without knowing the physical layout
Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][WootingPhysicalKeyboardLayout.US];
@@ -47,7 +47,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard
protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][WootingPhysicalKeyboardLayout.US][ledId];
///
- protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0));
+ protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate));
#endregion
}
diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs
index e0dc3e5..6decd4a 100644
--- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs
+++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
using System.Runtime.InteropServices;
using RGB.NET.Core;
using RGB.NET.Devices.Wooting.Enum;
@@ -15,7 +13,7 @@ namespace RGB.NET.Devices.Wooting
///
/// Represents a device provider responsible for Wooting devices.
///
- public class WootingDeviceProvider : IRGBDeviceProvider
+ public class WootingDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
@@ -37,20 +35,6 @@ namespace RGB.NET.Devices.Wooting
///
public static List PossibleX64NativePaths { get; } = new() { "x64/wooting-rgb-sdk64.dll" };
- ///
- ///
- /// Indicates if the SDK is initialized and ready to use.
- ///
- public bool IsInitialized { get; private set; }
-
- ///
- public IEnumerable Devices { get; private set; } = Enumerable.Empty();
-
- ///
- /// The used to trigger the updates for cooler master devices.
- ///
- public DeviceUpdateTrigger UpdateTrigger { get; }
-
#endregion
#region Constructors
@@ -61,68 +45,42 @@ namespace RGB.NET.Devices.Wooting
/// Thrown if this constructor is called even if there is already an instance of this class.
public WootingDeviceProvider()
{
- if (_instance != null)
- throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}");
+ if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}");
_instance = this;
-
- UpdateTrigger = new DeviceUpdateTrigger();
}
#endregion
#region Methods
- ///
- /// Thrown if the SDK failed to initialize
- public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false)
+ protected override void InitializeSDK()
{
- IsInitialized = false;
+ _WootingSDK.Reload();
+ }
- try
+ protected override IEnumerable LoadDevices()
+ {
+ if (_WootingSDK.KeyboardConnected())
{
- UpdateTrigger.Stop();
-
- _WootingSDK.Reload();
-
- IList devices = new List();
- if (_WootingSDK.KeyboardConnected())
+ _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!;
+ IWootingRGBDevice? device = nativeDeviceInfo.Model switch
{
- _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!;
- IWootingRGBDevice device = nativeDeviceInfo.Model switch
- {
- "Wooting two" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo)),
- "Wooting one" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne)),
- _ => throw new RGBDeviceException("No supported Wooting keyboard connected")
- };
+ "Wooting two" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo), GetUpdateTrigger()),
+ "Wooting one" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne), GetUpdateTrigger()),
+ _ => null
+ };
- device.Initialize(UpdateTrigger);
- devices.Add(device);
- }
-
- UpdateTrigger.Start();
-
- Devices = new ReadOnlyCollection(devices);
- IsInitialized = true;
+ if (device == null)
+ Throw(new RGBDeviceException("No supported Wooting keyboard connected"));
+ else
+ yield return device;
}
- catch
- {
- if (throwExceptions) throw;
- return false;
- }
-
- return true;
}
///
- public void Dispose()
+ public override void Dispose()
{
- try { UpdateTrigger.Dispose(); }
- catch { /* at least we tried */ }
-
- foreach (IRGBDevice device in Devices)
- try { device.Dispose(); }
- catch { /* at least we tried */ }
- Devices = Enumerable.Empty();
+ base.Dispose();
try { _WootingSDK.Close(); }
catch { /* Unlucky.. */ }
diff --git a/RGB.NET.Groups/RGB.NET.Groups.csproj.DotSettings b/RGB.NET.Groups/RGB.NET.Groups.csproj.DotSettings
deleted file mode 100644
index b248500..0000000
--- a/RGB.NET.Groups/RGB.NET.Groups.csproj.DotSettings
+++ /dev/null
@@ -1,3 +0,0 @@
-
- True
- True
\ No newline at end of file
diff --git a/RGB.NET.Layout/DeviceLayout.cs b/RGB.NET.Layout/DeviceLayout.cs
index 2f34028..f4363c8 100644
--- a/RGB.NET.Layout/DeviceLayout.cs
+++ b/RGB.NET.Layout/DeviceLayout.cs
@@ -59,27 +59,27 @@ namespace RGB.NET.Layout
/// Gets or sets the width of the .
///
[XmlElement("Width")]
- public double Width { get; set; }
+ public float Width { get; set; }
///
/// Gets or sets the height of the .
///
[XmlElement("Height")]
- public double Height { get; set; }
+ public float Height { get; set; }
///
/// Gets or sets the width of one 'unit' used for the calculation of led positions and sizes.
///
[XmlElement("LedUnitWidth")]
[DefaultValue(19.0)]
- public double LedUnitWidth { get; set; } = 19.0;
+ public float LedUnitWidth { get; set; } = 19.0f;
///
/// Gets or sets the height of one 'unit' used for the calculation of led positions and sizes.
///
[XmlElement("LedUnitHeight")]
[DefaultValue(19.0)]
- public double LedUnitHeight { get; set; } = 19.0;
+ public float LedUnitHeight { get; set; } = 19.0f;
[XmlArray("Leds")]
public List InternalLeds { get; set; } = new();
diff --git a/RGB.NET.Layout/IDeviceLayout.cs b/RGB.NET.Layout/IDeviceLayout.cs
index c06d9d9..677353c 100644
--- a/RGB.NET.Layout/IDeviceLayout.cs
+++ b/RGB.NET.Layout/IDeviceLayout.cs
@@ -38,12 +38,12 @@ namespace RGB.NET.Layout
///
/// Gets or sets the width of the .
///
- double Width { get; }
+ float Width { get; }
///
/// Gets or sets the height of the .
///
- double Height { get; }
+ float Height { get; }
///
/// Gets or sets a list of representing all the of the .
diff --git a/RGB.NET.Layout/ILedLayout.cs b/RGB.NET.Layout/ILedLayout.cs
index 3747a97..5569692 100644
--- a/RGB.NET.Layout/ILedLayout.cs
+++ b/RGB.NET.Layout/ILedLayout.cs
@@ -22,22 +22,22 @@ namespace RGB.NET.Layout
///
/// Gets the x-position of the .
///
- double X { get; }
+ float X { get; }
///
/// Gets the y-position of the .
///
- double Y { get; }
+ float Y { get; }
///
/// Gets the width of the .
///
- double Width { get; }
+ float Width { get; }
///
/// Gets the height of the .
///
- double Height { get; }
+ float Height { get; }
object? CustomData { get; }
}
diff --git a/RGB.NET.Layout/LedLayout.cs b/RGB.NET.Layout/LedLayout.cs
index 3bab36c..39af645 100644
--- a/RGB.NET.Layout/LedLayout.cs
+++ b/RGB.NET.Layout/LedLayout.cs
@@ -83,25 +83,25 @@ namespace RGB.NET.Layout
/// Gets the x-position of the .
///
[XmlIgnore]
- public double X { get; private set; }
+ public float X { get; private set; }
///
/// Gets the y-position of the .
///
[XmlIgnore]
- public double Y { get; private set; }
+ public float Y { get; private set; }
///
/// Gets the width of the .
///
[XmlIgnore]
- public double Width { get; private set; }
+ public float Width { get; private set; }
///
/// Gets the height of the .
///
[XmlIgnore]
- public double Height { get; private set; }
+ public float Height { get; private set; }
#endregion
@@ -128,7 +128,7 @@ namespace RGB.NET.Layout
Y = GetLocationValue(DescriptiveY, lastLed?.Y ?? 0, Height, lastLed?.Height ?? 0);
}
- protected virtual double GetLocationValue(string value, double lastValue, double currentSize, double lastSize)
+ protected virtual float GetLocationValue(string value, float lastValue, float currentSize, float lastSize)
{
try
{
@@ -143,21 +143,21 @@ namespace RGB.NET.Layout
return lastValue + lastSize;
if (value.StartsWith("+", StringComparison.Ordinal))
- return lastValue + lastSize + double.Parse(value[1..], CultureInfo.InvariantCulture);
+ return lastValue + lastSize + float.Parse(value[1..], CultureInfo.InvariantCulture);
if (string.Equals(value, "-", StringComparison.Ordinal))
return lastValue - currentSize;
if (value.StartsWith("-", StringComparison.Ordinal))
- return lastValue - currentSize - double.Parse(value[1..], CultureInfo.InvariantCulture);
+ return lastValue - currentSize - float.Parse(value[1..], CultureInfo.InvariantCulture);
if (string.Equals(value, "~", StringComparison.Ordinal))
return (lastValue + lastSize) - currentSize;
if (value.StartsWith("~", StringComparison.Ordinal))
- return (lastValue + lastSize) - currentSize - double.Parse(value[1..], CultureInfo.InvariantCulture);
+ return (lastValue + lastSize) - currentSize - float.Parse(value[1..], CultureInfo.InvariantCulture);
- return double.Parse(value, CultureInfo.InvariantCulture);
+ return float.Parse(value, CultureInfo.InvariantCulture);
}
catch
{
@@ -165,7 +165,7 @@ namespace RGB.NET.Layout
}
}
- protected virtual double GetSizeValue(string value, double unitSize)
+ protected virtual float GetSizeValue(string value, float unitSize)
{
try
{
@@ -174,9 +174,9 @@ namespace RGB.NET.Layout
value = value.Replace(" ", string.Empty);
if (value.EndsWith("mm", StringComparison.OrdinalIgnoreCase))
- return double.Parse(value[..^2], CultureInfo.InvariantCulture);
+ return float.Parse(value[..^2], CultureInfo.InvariantCulture);
- return unitSize * double.Parse(value, CultureInfo.InvariantCulture);
+ return unitSize * float.Parse(value, CultureInfo.InvariantCulture);
}
catch
{
diff --git a/RGB.NET.Decorators/Brush/FlashDecorator.cs b/RGB.NET.Presets/Decorators/FlashDecorator.cs
similarity index 83%
rename from RGB.NET.Decorators/Brush/FlashDecorator.cs
rename to RGB.NET.Presets/Decorators/FlashDecorator.cs
index 5900851..696782a 100644
--- a/RGB.NET.Decorators/Brush/FlashDecorator.cs
+++ b/RGB.NET.Presets/Decorators/FlashDecorator.cs
@@ -5,7 +5,7 @@
using System;
using RGB.NET.Core;
-namespace RGB.NET.Decorators.Brush
+namespace RGB.NET.Presets.Decorators
{
///
///
@@ -20,46 +20,46 @@ namespace RGB.NET.Decorators.Brush
/// Gets or sets the attack-time (in seconds) of the decorator. (default: 0.2)
/// This is close to a synthesizer envelope. (See as reference)
///
- public double Attack { get; set; } = 0.2;
+ public float Attack { get; set; } = 0.2f;
///
/// Gets or sets the decay-time (in seconds) of the decorator. (default: 0)
/// This is close to a synthesizer envelope. (See as reference)
///
- public double Decay { get; set; } = 0;
+ public float Decay { get; set; } = 0;
///
/// Gets or sets the sustain-time (in seconds) of the decorator. (default: 0.3)
/// This is close to a synthesizer envelope. (See as reference)
/// Note that this value for naming reasons represents the time NOT the level.
///
- public double Sustain { get; set; } = 0.3;
+ public float Sustain { get; set; } = 0.3f;
///
/// Gets or sets the release-time (in seconds) of the decorator. (default: 0.2)
/// This is close to a synthesizer envelope. (See as reference)
///
- public double Release { get; set; } = 0.2;
+ public float Release { get; set; } = 0.2f;
///
/// Gets or sets the level to which the oppacity (percentage) should raise in the attack-cycle. (default: 1);
///
- public double AttackValue { get; set; } = 1;
+ public float AttackValue { get; set; } = 1;
///
/// Gets or sets the level at which the oppacity (percentage) should stay in the sustain-cycle. (default: 1);
///
- public double SustainValue { get; set; } = 1;
+ public float SustainValue { get; set; } = 1;
///
/// Gets or sets the level at which the oppacity (percentage) should stay in the pause-cycle. (default: 0);
///
- public double PauseValue { get; set; } = 0;
+ public float PauseValue { get; set; } = 0;
///
/// Gets or sets the interval (in seconds) in which the decorator should repeat (if repetition is enabled). (default: 1)
///
- public double Interval { get; set; } = 1;
+ public float Interval { get; set; } = 1;
///
/// Gets or sets the amount of repetitions the decorator should do until it's finished. Zero means infinite. (default: 0)
@@ -67,10 +67,10 @@ namespace RGB.NET.Decorators.Brush
public int Repetitions { get; set; } = 0;
private ADSRPhase _currentPhase;
- private double _currentPhaseValue;
+ private float _currentPhaseValue;
private int _repetitionCount;
- private double _currentValue;
+ private float _currentValue;
#endregion
@@ -85,19 +85,19 @@ namespace RGB.NET.Decorators.Brush
#region Methods
///
- public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetA(_currentValue);
+ public void ManipulateColor(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color) => color = color.SetA(_currentValue);
///
protected override void Update(double deltaTime)
{
- _currentPhaseValue -= deltaTime;
+ _currentPhaseValue -= (float)deltaTime;
// Using ifs instead of a switch allows to skip phases with time 0.
// ReSharper disable InvertIf
if (_currentPhase == ADSRPhase.Attack)
if (_currentPhaseValue > 0)
- _currentValue = PauseValue + (Math.Min(1, (Attack - _currentPhaseValue) / Attack) * (AttackValue - PauseValue));
+ _currentValue = PauseValue + (MathF.Min(1, (Attack - _currentPhaseValue) / Attack) * (AttackValue - PauseValue));
else
{
_currentPhaseValue = Decay;
@@ -106,7 +106,7 @@ namespace RGB.NET.Decorators.Brush
if (_currentPhase == ADSRPhase.Decay)
if (_currentPhaseValue > 0)
- _currentValue = SustainValue + (Math.Min(1, _currentPhaseValue / Decay) * (AttackValue - SustainValue));
+ _currentValue = SustainValue + (MathF.Min(1, _currentPhaseValue / Decay) * (AttackValue - SustainValue));
else
{
_currentPhaseValue = Sustain;
@@ -124,7 +124,7 @@ namespace RGB.NET.Decorators.Brush
if (_currentPhase == ADSRPhase.Release)
if (_currentPhaseValue > 0)
- _currentValue = PauseValue + (Math.Min(1, _currentPhaseValue / Release) * (SustainValue - PauseValue));
+ _currentValue = PauseValue + (MathF.Min(1, _currentPhaseValue / Release) * (SustainValue - PauseValue));
else
{
_currentPhaseValue = Interval;
diff --git a/RGB.NET.Brushes/Decorators/IGradientDecorator.cs b/RGB.NET.Presets/Decorators/IGradientDecorator.cs
similarity index 73%
rename from RGB.NET.Brushes/Decorators/IGradientDecorator.cs
rename to RGB.NET.Presets/Decorators/IGradientDecorator.cs
index 86c07de..6f57696 100644
--- a/RGB.NET.Brushes/Decorators/IGradientDecorator.cs
+++ b/RGB.NET.Presets/Decorators/IGradientDecorator.cs
@@ -1,10 +1,10 @@
using RGB.NET.Core;
-namespace RGB.NET.Brushes
+namespace RGB.NET.Presets.Decorators
{
///
///
- /// Represents a basic decorator decorating a .
+ /// Represents a basic decorator decorating a .
///
public interface IGradientDecorator : IDecorator
{ }
diff --git a/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs b/RGB.NET.Presets/Decorators/MoveGradientDecorator.cs
similarity index 78%
rename from RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs
rename to RGB.NET.Presets/Decorators/MoveGradientDecorator.cs
index 52a679b..5f2280f 100644
--- a/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs
+++ b/RGB.NET.Presets/Decorators/MoveGradientDecorator.cs
@@ -1,13 +1,12 @@
-using RGB.NET.Brushes;
-using RGB.NET.Brushes.Gradients;
-using RGB.NET.Core;
+using RGB.NET.Core;
+using RGB.NET.Presets.Textures.Gradients;
-namespace RGB.NET.Decorators.Gradient
+namespace RGB.NET.Presets.Decorators
{
///
///
///
- /// Represents a decorator which allows to move an by modifying his offset.
+ /// Represents a decorator which allows to move an by modifying his offset.
///
public class MoveGradientDecorator : AbstractUpdateAwareDecorator, IGradientDecorator
{
@@ -27,7 +26,7 @@ namespace RGB.NET.Decorators.Gradient
/// : 360 unit = 1 offset.
/// : 1 unit = 1 degree.
///
- public double Speed { get; set; }
+ public float Speed { get; set; }
// ReSharper restore MemberCanBePrivate.Global
// ReSharper restore AutoPropertyCanBeMadeGetOnly.Global
@@ -37,15 +36,15 @@ namespace RGB.NET.Decorators.Gradient
///
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The speed of the movement in units per second.
- /// The meaning of units differs for the different but 360 units will always be one complete cycle:
- /// : 360 unit = 1 offset.
- /// : 1 unit = 1 degree.
- /// The direction the is moved.
+ /// The meaning of units differs for the different but 360 units will always be one complete cycle:
+ /// : 360 unit = 1 offset.
+ /// : 1 unit = 1 degree.
+ /// The direction the is moved.
/// True leads to an offset-increment (normaly moving to the right), false to an offset-decrement (normaly moving to the left).
- public MoveGradientDecorator(RGBSurface surface, double speed = 180.0, bool direction = true)
+ public MoveGradientDecorator(RGBSurface surface, float speed = 180.0f, bool direction = true)
: base(surface)
{
this.Speed = speed;
@@ -59,7 +58,7 @@ namespace RGB.NET.Decorators.Gradient
///
protected override void Update(double deltaTime)
{
- double movement = Speed * deltaTime;
+ float movement = Speed * (float)deltaTime;
if (!Direction)
movement = -movement;
diff --git a/RGB.NET.Groups/Groups/RectangleLedGroup.cs b/RGB.NET.Presets/Groups/RectangleLedGroup.cs
similarity index 84%
rename from RGB.NET.Groups/Groups/RectangleLedGroup.cs
rename to RGB.NET.Presets/Groups/RectangleLedGroup.cs
index e6c2ae7..a17ff98 100644
--- a/RGB.NET.Groups/Groups/RectangleLedGroup.cs
+++ b/RGB.NET.Presets/Groups/RectangleLedGroup.cs
@@ -6,11 +6,11 @@ using System.Collections.Generic;
using System.Linq;
using RGB.NET.Core;
-namespace RGB.NET.Groups
+namespace RGB.NET.Presets.Groups
{
///
///
- /// Represents a containing which physically lay inside a .
+ /// Represents a containing which physically lay inside a .
///
public class RectangleLedGroup : AbstractLedGroup
{
@@ -93,31 +93,28 @@ namespace RGB.NET.Groups
#region Methods
///
- public override void OnAttach(RGBSurface surface)
+ public override void OnAttach()
{
- base.OnAttach(surface);
-
- if (Surface != null)
- Surface.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged;
+ base.OnAttach();
+ Surface!.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged;
}
///
- public override void OnDetach(RGBSurface surface)
+ public override void OnDetach()
{
- if (Surface != null)
- Surface.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged;
+ Surface!.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged;
- base.OnDetach(surface);
+ base.OnDetach();
}
private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache();
///
///
- /// Gets a list containing all of this .
+ /// Gets a list containing all of this .
///
- /// The list containing all of this .
- public override IList GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List());
+ /// The list containing all of this .
+ protected override IEnumerable GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List());
private void InvalidateCache() => _ledCache = null;
diff --git a/RGB.NET.Brushes/Helper/GradientHelper.cs b/RGB.NET.Presets/Helper/GradientHelper.cs
similarity index 58%
rename from RGB.NET.Brushes/Helper/GradientHelper.cs
rename to RGB.NET.Presets/Helper/GradientHelper.cs
index b350af4..6254fe5 100644
--- a/RGB.NET.Brushes/Helper/GradientHelper.cs
+++ b/RGB.NET.Presets/Helper/GradientHelper.cs
@@ -3,7 +3,7 @@
using System;
using RGB.NET.Core;
-namespace RGB.NET.Brushes.Helper
+namespace RGB.NET.Presets.Helper
{
///
/// Offers some extensions and helper-methods for gradient related things.
@@ -20,31 +20,31 @@ namespace RGB.NET.Brushes.Helper
/// The end of the gradient.
/// The on the gradient to which the offset is calculated.
/// The offset of the on the gradient.
- public static double CalculateLinearGradientOffset(Point startPoint, Point endPoint, Point point)
+ public static float CalculateLinearGradientOffset(in Point startPoint, in Point endPoint, in Point point)
{
Point intersectingPoint;
- if (startPoint.Y.Equals(endPoint.Y)) // Horizontal case
+ if (startPoint.Y.EqualsInTolerance(endPoint.Y)) // Horizontal case
intersectingPoint = new Point(point.X, startPoint.Y);
- else if (startPoint.X.Equals(endPoint.X)) // Vertical case
+ else if (startPoint.X.EqualsInTolerance(endPoint.X)) // Vertical case
intersectingPoint = new Point(startPoint.X, point.Y);
else // Diagonal case
{
- double slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X);
- double orthogonalSlope = -1 / slope;
+ float slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X);
+ float orthogonalSlope = -1 / slope;
- double startYIntercept = startPoint.Y - (slope * startPoint.X);
- double pointYIntercept = point.Y - (orthogonalSlope * point.X);
+ float startYIntercept = startPoint.Y - (slope * startPoint.X);
+ float pointYIntercept = point.Y - (orthogonalSlope * point.X);
- double intersectingPointX = (pointYIntercept - startYIntercept) / (slope - orthogonalSlope);
- double intersectingPointY = (slope * intersectingPointX) + startYIntercept;
+ float intersectingPointX = (pointYIntercept - startYIntercept) / (slope - orthogonalSlope);
+ float intersectingPointY = (slope * intersectingPointX) + startYIntercept;
intersectingPoint = new Point(intersectingPointX, intersectingPointY);
}
// Calculate distances relative to the vector start
- double intersectDistance = CalculateDistance(intersectingPoint, startPoint, endPoint);
- double gradientLength = CalculateDistance(endPoint, startPoint, endPoint);
+ float intersectDistance = CalculateDistance(intersectingPoint, startPoint, endPoint);
+ float gradientLength = CalculateDistance(endPoint, startPoint, endPoint);
return intersectDistance / gradientLength;
}
@@ -57,15 +57,15 @@ namespace RGB.NET.Brushes.Helper
/// The origin of the vector.
/// The direction of the vector.
/// The signed magnitude of a on a vector.
- public static double CalculateDistance(Point point, Point origin, Point direction)
+ public static float CalculateDistance(in Point point, in Point origin, in Point direction)
{
- double distance = CalculateDistance(point, origin);
+ float distance = CalculateDistance(point, origin);
- return (((point.Y < origin.Y) && (direction.Y > origin.Y)) ||
- ((point.Y > origin.Y) && (direction.Y < origin.Y)) ||
- ((point.Y.Equals(origin.Y)) && (point.X < origin.X) && (direction.X > origin.X)) ||
- ((point.Y.Equals(origin.Y)) && (point.X > origin.X) && (direction.X < origin.X)))
- ? -distance : distance;
+ return (((point.Y < origin.Y) && (direction.Y > origin.Y))
+ || ((point.Y > origin.Y) && (direction.Y < origin.Y))
+ || ((point.Y.EqualsInTolerance(origin.Y)) && (point.X < origin.X) && (direction.X > origin.X))
+ || ((point.Y.EqualsInTolerance(origin.Y)) && (point.X > origin.X) && (direction.X < origin.X)))
+ ? -distance : distance;
}
///
@@ -74,7 +74,12 @@ namespace RGB.NET.Brushes.Helper
/// The first .
/// The second .
/// The distance between the two .
- public static double CalculateDistance(Point point1, Point point2) => Math.Sqrt(((point1.Y - point2.Y) * (point1.Y - point2.Y)) + ((point1.X - point2.X) * (point1.X - point2.X)));
+ public static float CalculateDistance(in Point point1, in Point point2)
+ {
+ float x = point1.X - point2.X;
+ float y = point1.Y - point2.Y;
+ return MathF.Sqrt((y * y) + (x * x));
+ }
#endregion
}
diff --git a/RGB.NET.Groups/RGB.NET.Groups.csproj b/RGB.NET.Presets/RGB.NET.Presets.csproj
similarity index 82%
rename from RGB.NET.Groups/RGB.NET.Groups.csproj
rename to RGB.NET.Presets/RGB.NET.Presets.csproj
index a0251a2..4740b83 100644
--- a/RGB.NET.Groups/RGB.NET.Groups.csproj
+++ b/RGB.NET.Presets/RGB.NET.Presets.csproj
@@ -8,13 +8,13 @@
Wyrez
en-US
en-US
- RGB.NET.Groups
- RGB.NET.Groups
- RGB.NET.Groups
- RGB.NET.Groups
- RGB.NET.Groups
- Group-Presets of RGB.NET
- Group-Presets of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals
+ RGB.NET.Presets
+ RGB.NET.Presets
+ RGB.NET.Presets
+ RGB.NET.Presets
+ RGB.NET.Presets
+ Presets-Presets of RGB.NET
+ Presets for RGB.NET, a C# (.NET) library for accessing various RGB-peripherals
Copyright © Darth Affe 2020
Copyright © Darth Affe 2020
http://lib.arge.be/icon.png
diff --git a/RGB.NET.Presets/RGB.NET.Presets.csproj.DotSettings b/RGB.NET.Presets/RGB.NET.Presets.csproj.DotSettings
new file mode 100644
index 0000000..3af07cd
--- /dev/null
+++ b/RGB.NET.Presets/RGB.NET.Presets.csproj.DotSettings
@@ -0,0 +1,5 @@
+
+ False
+ False
+ True
+ True
\ No newline at end of file
diff --git a/RGB.NET.Presets/Textures/AbstractGradientTexture.cs b/RGB.NET.Presets/Textures/AbstractGradientTexture.cs
new file mode 100644
index 0000000..a724871
--- /dev/null
+++ b/RGB.NET.Presets/Textures/AbstractGradientTexture.cs
@@ -0,0 +1,42 @@
+using RGB.NET.Core;
+using RGB.NET.Presets.Textures.Gradients;
+
+namespace RGB.NET.Presets.Textures
+{
+ public abstract class AbstractGradientTexture : AbstractBindable, ITexture
+ {
+ #region Properties & Fields
+
+ ///
+ /// Gets the gradient drawn by the brush.
+ ///
+ public IGradient Gradient { get; }
+
+ ///
+ public Size Size { get; }
+
+ ///
+ public Color this[in Point point] => GetColor(point);
+
+ ///
+ public Color this[in Rectangle rectangle] => GetColor(rectangle.Center);
+
+ #endregion
+
+ #region Constructors
+
+ protected AbstractGradientTexture(Size size, IGradient gradient)
+ {
+ this.Size = size;
+ this.Gradient = gradient;
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected abstract Color GetColor(in Point point);
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Presets/Textures/BytePixelTexture.cs b/RGB.NET.Presets/Textures/BytePixelTexture.cs
new file mode 100644
index 0000000..ab008b7
--- /dev/null
+++ b/RGB.NET.Presets/Textures/BytePixelTexture.cs
@@ -0,0 +1,47 @@
+using System;
+using RGB.NET.Core;
+using RGB.NET.Presets.Textures.Sampler;
+
+namespace RGB.NET.Presets.Textures
+{
+ public sealed class BytePixelTexture : PixelTexture
+ {
+ #region Properties & Fields
+
+ private readonly byte[] _data;
+ protected override ReadOnlySpan Data => _data;
+
+ public ColorFormat ColorFormat { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public BytePixelTexture(int with, int height, byte[] data, ColorFormat colorFormat = ColorFormat.RGB)
+ : this(with, height, data, new AverageByteSampler(), colorFormat)
+ { }
+
+ public BytePixelTexture(int with, int height, byte[] data, ISampler sampler, ColorFormat colorFormat = ColorFormat.RGB)
+ : base(with, height, 3, sampler)
+ {
+ this._data = data;
+ this.ColorFormat = colorFormat;
+
+ if (Data.Length != ((with * height) * 3)) throw new ArgumentException($"Data-Length {Data.Length} differs from the given size {with}x{height} * 3 bytes ({with * height * 3}).");
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override Color GetColor(in ReadOnlySpan pixel)
+ {
+ if (ColorFormat == ColorFormat.BGR)
+ return new Color(pixel[2], pixel[1], pixel[0]);
+
+ return new Color(pixel[0], pixel[1], pixel[2]);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Presets/Textures/ConicalGradientTexture.cs b/RGB.NET.Presets/Textures/ConicalGradientTexture.cs
new file mode 100644
index 0000000..cf53ae4
--- /dev/null
+++ b/RGB.NET.Presets/Textures/ConicalGradientTexture.cs
@@ -0,0 +1,98 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable MemberCanBeProtected.Global
+// ReSharper disable ReturnTypeCanBeEnumerable.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+// ReSharper disable UnusedMember.Global
+
+using System;
+using RGB.NET.Core;
+using RGB.NET.Presets.Textures.Gradients;
+
+namespace RGB.NET.Presets.Textures
+{
+ ///
+ ///
+ /// Represents a brush drawing a conical gradient.
+ ///
+ public sealed class ConicalGradientTexture : AbstractGradientTexture
+ {
+ #region Constants
+
+ private const float PI2 = MathF.PI * 2.0f;
+
+ #endregion
+
+ #region Properties & Fields
+
+ private float _origin = MathF.Atan2(-1, 0);
+ ///
+ /// Gets or sets the origin (radian-angle) this is drawn to. (default: -π/2)
+ ///
+ public float Origin
+ {
+ get => _origin;
+ set => SetProperty(ref _origin, value);
+ }
+
+ private Point _center = new(0.5f, 0.5f);
+ ///
+ /// Gets or sets the center (as percentage in the range [0..1]) of the drawn by this . (default: 0.5, 0.5)
+ ///
+ public Point Center
+ {
+ get => _center;
+ set => SetProperty(ref _center, value);
+ }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The drawn by this .
+ public ConicalGradientTexture(Size size, IGradient gradient)
+ : base(size, gradient)
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The center (as percentage in the range [0..1]).
+ /// The drawn by this .
+ public ConicalGradientTexture(Size size, IGradient gradient, Point center)
+ : base(size, gradient)
+ {
+ this.Center = center;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The center (as percentage in the range [0..1]).
+ /// The origin (radian-angle) the is drawn to.
+ /// The drawn by this .
+ public ConicalGradientTexture(Size size, IGradient gradient, Point center, float origin)
+ : base(size, gradient)
+ {
+ this.Center = center;
+ this.Origin = origin;
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override Color GetColor(in Point point)
+ {
+ float angle = MathF.Atan2(point.Y - Center.Y, point.X - Center.X) - Origin;
+ if (angle < 0) angle += PI2;
+ float offset = angle / PI2;
+
+ return Gradient.GetColor(offset);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Presets/Textures/Enums/ColorFormat.cs b/RGB.NET.Presets/Textures/Enums/ColorFormat.cs
new file mode 100644
index 0000000..a098ff5
--- /dev/null
+++ b/RGB.NET.Presets/Textures/Enums/ColorFormat.cs
@@ -0,0 +1,8 @@
+namespace RGB.NET.Presets.Textures
+{
+ public enum ColorFormat
+ {
+ RGB,
+ BGR
+ }
+}
diff --git a/RGB.NET.Presets/Textures/FloatPixelTexture.cs b/RGB.NET.Presets/Textures/FloatPixelTexture.cs
new file mode 100644
index 0000000..686f05c
--- /dev/null
+++ b/RGB.NET.Presets/Textures/FloatPixelTexture.cs
@@ -0,0 +1,47 @@
+using System;
+using RGB.NET.Core;
+using RGB.NET.Presets.Textures.Sampler;
+
+namespace RGB.NET.Presets.Textures
+{
+ public sealed class FloatPixelTexture : PixelTexture
+ {
+ #region Properties & Fields
+
+ private readonly float[] _data;
+ protected override ReadOnlySpan Data => _data;
+
+ public ColorFormat ColorFormat { get; }
+
+ #endregion
+
+ #region Constructors
+
+ public FloatPixelTexture(int with, int height, float[] data, ColorFormat colorFormat = ColorFormat.RGB)
+ : this(with, height, data, new AverageFloatSampler(), colorFormat)
+ { }
+
+ public FloatPixelTexture(int with, int height, float[] data, ISampler sampler, ColorFormat colorFormat = ColorFormat.RGB)
+ : base(with, height, 3, sampler)
+ {
+ this._data = data;
+ this.ColorFormat = colorFormat;
+
+ if (Data.Length != ((with * height) * 3)) throw new ArgumentException($"Data-Length {Data.Length} differs from the given size {with}x{height} * 3 bytes ({with * height * 3}).");
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override Color GetColor(in ReadOnlySpan pixel)
+ {
+ if (ColorFormat == ColorFormat.BGR)
+ return new Color(pixel[2], pixel[1], pixel[0]);
+
+ return new Color(pixel[0], pixel[1], pixel[2]);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Brushes/Gradients/AbstractGradient.cs b/RGB.NET.Presets/Textures/Gradients/AbstractGradient.cs
similarity index 90%
rename from RGB.NET.Brushes/Gradients/AbstractGradient.cs
rename to RGB.NET.Presets/Textures/Gradients/AbstractGradient.cs
index 2a6350b..e52788c 100644
--- a/RGB.NET.Brushes/Gradients/AbstractGradient.cs
+++ b/RGB.NET.Presets/Textures/Gradients/AbstractGradient.cs
@@ -8,8 +8,9 @@ using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using RGB.NET.Core;
+using RGB.NET.Presets.Decorators;
-namespace RGB.NET.Brushes.Gradients
+namespace RGB.NET.Presets.Textures.Gradients
{
///
///
@@ -95,32 +96,32 @@ namespace RGB.NET.Brushes.Gradients
///
///
///
- protected double ClipOffset(double offset)
+ protected float ClipOffset(float offset)
{
- double max = GradientStops.Max(n => n.Offset);
+ float max = GradientStops.Max(stop => stop.Offset);
if (offset > max)
return max;
- double min = GradientStops.Min(n => n.Offset);
+ float min = GradientStops.Min(stop => stop.Offset);
return offset < min ? min : offset;
}
///
- public abstract Color GetColor(double offset);
+ public abstract Color GetColor(float offset);
///
- public virtual void Move(double offset)
+ public virtual void Move(float offset)
{
- offset /= 360.0;
+ offset /= 360.0f;
foreach (GradientStop gradientStop in GradientStops)
gradientStop.Offset += offset;
- while (GradientStops.All(x => x.Offset > 1))
+ while (GradientStops.All(stop => stop.Offset > 1))
foreach (GradientStop gradientStop in GradientStops)
gradientStop.Offset -= 1;
- while (GradientStops.All(x => x.Offset < 0))
+ while (GradientStops.All(stop => stop.Offset < 0))
foreach (GradientStop gradientStop in GradientStops)
gradientStop.Offset += 1;
}
diff --git a/RGB.NET.Brushes/Gradients/GradientStop.cs b/RGB.NET.Presets/Textures/Gradients/GradientStop.cs
similarity index 89%
rename from RGB.NET.Brushes/Gradients/GradientStop.cs
rename to RGB.NET.Presets/Textures/Gradients/GradientStop.cs
index 3cb4597..aba665d 100644
--- a/RGB.NET.Brushes/Gradients/GradientStop.cs
+++ b/RGB.NET.Presets/Textures/Gradients/GradientStop.cs
@@ -3,7 +3,7 @@
using RGB.NET.Core;
-namespace RGB.NET.Brushes.Gradients
+namespace RGB.NET.Presets.Textures.Gradients
{
///
/// Represents a stop on a gradient.
@@ -12,11 +12,11 @@ namespace RGB.NET.Brushes.Gradients
{
#region Properties & Fields
- private double _offset;
+ private float _offset;
///
/// Gets or sets the percentage offset to place this . This should be inside the range of [0..1] but it's not necessary.
///
- public double Offset
+ public float Offset
{
get => _offset;
set => SetProperty(ref _offset, value);
@@ -41,7 +41,7 @@ namespace RGB.NET.Brushes.Gradients
///
/// The percentage offset to place this .
/// The of the .
- public GradientStop(double offset, Color color)
+ public GradientStop(float offset, Color color)
{
this.Offset = offset;
this.Color = color;
diff --git a/RGB.NET.Brushes/Gradients/IGradient.cs b/RGB.NET.Presets/Textures/Gradients/IGradient.cs
similarity index 85%
rename from RGB.NET.Brushes/Gradients/IGradient.cs
rename to RGB.NET.Presets/Textures/Gradients/IGradient.cs
index 590ba4c..1917256 100644
--- a/RGB.NET.Brushes/Gradients/IGradient.cs
+++ b/RGB.NET.Presets/Textures/Gradients/IGradient.cs
@@ -1,9 +1,9 @@
using System;
using RGB.NET.Core;
+using RGB.NET.Presets.Decorators;
-namespace RGB.NET.Brushes.Gradients
+namespace RGB.NET.Presets.Textures.Gradients
{
- ///
///
/// Represents a basic gradient.
///
@@ -19,12 +19,12 @@ namespace RGB.NET.Brushes.Gradients
///
/// The percentage offset to take the from.
/// The at the specific offset.
- Color GetColor(double offset);
+ Color GetColor(float offset);
///
/// Moves the by the provided offset.
///
/// The offset the should be moved.
- void Move(double offset);
+ void Move(float offset);
}
}
diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Presets/Textures/Gradients/LinearGradient.cs
similarity index 85%
rename from RGB.NET.Brushes/Gradients/LinearGradient.cs
rename to RGB.NET.Presets/Textures/Gradients/LinearGradient.cs
index f22ec24..2aa898e 100644
--- a/RGB.NET.Brushes/Gradients/LinearGradient.cs
+++ b/RGB.NET.Presets/Textures/Gradients/LinearGradient.cs
@@ -5,7 +5,7 @@ using System.ComponentModel;
using System.Linq;
using RGB.NET.Core;
-namespace RGB.NET.Brushes.Gradients
+namespace RGB.NET.Presets.Textures.Gradients
{
///
///
@@ -24,7 +24,7 @@ namespace RGB.NET.Brushes.Gradients
///
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
public LinearGradient()
{
@@ -33,7 +33,7 @@ namespace RGB.NET.Brushes.Gradients
///
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The stops with which the gradient should be initialized.
public LinearGradient(params GradientStop[] gradientStops)
@@ -44,9 +44,9 @@ namespace RGB.NET.Brushes.Gradients
///
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
- /// Specifies whether the gradient should wrapp or not (see for an example of what this means).
+ /// Specifies whether the gradient should wrapp or not (see for an example of what this means).
/// The stops with which the gradient should be initialized.
public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops)
: base(wrapGradient, gradientStops)
@@ -83,7 +83,7 @@ namespace RGB.NET.Brushes.Gradients
///
/// The percentage offset to take the color from.
/// The at the specific offset.
- public override Color GetColor(double offset)
+ public override Color GetColor(float offset)
{
if (GradientStops.Count == 0) return Color.Transparent;
if (GradientStops.Count == 1) return GradientStops[0].Color;
@@ -93,14 +93,14 @@ namespace RGB.NET.Brushes.Gradients
(GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, _orderedGradientStops, WrapGradient);
- double blendFactor = 0;
+ float blendFactor = 0;
if (!gsBefore.Offset.Equals(gsAfter.Offset))
blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset));
- double colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A;
- double colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R;
- double colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G;
- double colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B;
+ float colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A;
+ float colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R;
+ float colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G;
+ float colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B;
return new Color(colA, colR, colG, colB);
}
@@ -112,7 +112,7 @@ namespace RGB.NET.Brushes.Gradients
/// The ordered list of to choose from.
/// Bool indicating if the gradient should be wrapped or not.
///
- protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(double offset, LinkedList orderedStops, bool wrap)
+ protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(float offset, LinkedList orderedStops, bool wrap)
{
LinkedList gradientStops = new(orderedStops);
diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Presets/Textures/Gradients/RainbowGradient.cs
similarity index 86%
rename from RGB.NET.Brushes/Gradients/RainbowGradient.cs
rename to RGB.NET.Presets/Textures/Gradients/RainbowGradient.cs
index 2c5c2b6..1ec32e2 100644
--- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs
+++ b/RGB.NET.Presets/Textures/Gradients/RainbowGradient.cs
@@ -3,8 +3,9 @@
using System;
using RGB.NET.Core;
+using RGB.NET.Presets.Decorators;
-namespace RGB.NET.Brushes.Gradients
+namespace RGB.NET.Presets.Textures.Gradients
{
///
///
@@ -16,21 +17,21 @@ namespace RGB.NET.Brushes.Gradients
{
#region Properties & Fields
- private double _startHue;
+ private float _startHue;
///
/// Gets or sets the hue (in degrees) to start from.
///
- public double StartHue
+ public float StartHue
{
get => _startHue;
set => SetProperty(ref _startHue, value);
}
- private double _endHue;
+ private float _endHue;
///
/// Gets or sets the hue (in degrees) to end the with.
///
- public double EndHue
+ public float EndHue
{
get => _endHue;
set => SetProperty(ref _endHue, value);
@@ -52,7 +53,7 @@ namespace RGB.NET.Brushes.Gradients
///
/// The hue (in degrees) to start from (default: 0)
/// The hue (in degrees) to end with (default: 360)
- public RainbowGradient(double startHue = 0, double endHue = 360)
+ public RainbowGradient(float startHue = 0, float endHue = 360)
{
this.StartHue = startHue;
this.EndHue = endHue;
@@ -70,15 +71,15 @@ namespace RGB.NET.Brushes.Gradients
///
/// The percentage offset to take the color from.
/// The color at the specific offset.
- public Color GetColor(double offset)
+ public Color GetColor(float offset)
{
- double range = EndHue - StartHue;
- double hue = StartHue + (range * offset);
+ float range = EndHue - StartHue;
+ float hue = StartHue + (range * offset);
return HSVColor.Create(hue, 1, 1);
}
///
- public void Move(double offset)
+ public void Move(float offset)
{
// RainbowGradient is calculated inverse
offset *= -1;
diff --git a/RGB.NET.Presets/Textures/LinearGradientTexture.cs b/RGB.NET.Presets/Textures/LinearGradientTexture.cs
new file mode 100644
index 0000000..d37bf6a
--- /dev/null
+++ b/RGB.NET.Presets/Textures/LinearGradientTexture.cs
@@ -0,0 +1,79 @@
+// ReSharper disable CollectionNeverUpdated.Global
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable MemberCanBeProtected.Global
+// ReSharper disable ReturnTypeCanBeEnumerable.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+// ReSharper disable UnusedMember.Global
+
+using RGB.NET.Core;
+using RGB.NET.Presets.Helper;
+using RGB.NET.Presets.Textures.Gradients;
+
+namespace RGB.NET.Presets.Textures
+{
+ ///
+ ///
+ /// Represents a brush drawing a linear gradient.
+ ///
+ public sealed class LinearGradientTexture : AbstractGradientTexture
+ {
+ #region Properties & Fields
+
+ private Point _startPoint = new(0, 0.5f);
+ ///
+ /// Gets or sets the start (as percentage in the range [0..1]) of the drawn by this . (default: 0.0, 0.5)
+ ///
+ public Point StartPoint
+ {
+ get => _startPoint;
+ set => SetProperty(ref _startPoint, value);
+ }
+
+ private Point _endPoint = new(1, 0.5f);
+ ///
+ /// Gets or sets the end (as percentage in the range [0..1]) of the drawn by this . (default: 1.0, 0.5)
+ ///
+ public Point EndPoint
+ {
+ get => _endPoint;
+ set => SetProperty(ref _endPoint, value);
+ }
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The drawn by this .
+ public LinearGradientTexture(Size size, IGradient gradient)
+ : base(size, gradient)
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The start (as percentage in the range [0..1]).
+ /// The end (as percentage in the range [0..1]).
+ /// The drawn by this .
+ public LinearGradientTexture(Size size, IGradient gradient, Point startPoint, Point endPoint)
+ : base(size, gradient)
+ {
+ this.StartPoint = startPoint;
+ this.EndPoint = endPoint;
+ }
+
+ #endregion
+
+ #region Methods
+
+ protected override Color GetColor(in Point point)
+ {
+ float offset = GradientHelper.CalculateLinearGradientOffset(StartPoint, EndPoint, point);
+ return Gradient.GetColor(offset);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Presets/Textures/RadialGradientTexture.cs b/RGB.NET.Presets/Textures/RadialGradientTexture.cs
new file mode 100644
index 0000000..b5ff848
--- /dev/null
+++ b/RGB.NET.Presets/Textures/RadialGradientTexture.cs
@@ -0,0 +1,78 @@
+// ReSharper disable MemberCanBePrivate.Global
+// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
+// ReSharper disable UnusedMember.Global
+
+using RGB.NET.Core;
+using RGB.NET.Presets.Helper;
+using RGB.NET.Presets.Textures.Gradients;
+
+namespace RGB.NET.Presets.Textures
+{
+ ///
+ ///
+ /// Represents a brush drawing a radial gradient around a center point.
+ ///
+ public sealed class RadialGradientTexture : AbstractGradientTexture
+ {
+ #region Properties & Fields
+
+ private float _referenceDistance = GradientHelper.CalculateDistance(new Point(0.5f, 0.5f), new Point(0, 0));
+
+ private Point _center = new(0.5f, 0.5f);
+ ///
+ /// Gets or sets the center (as percentage in the range [0..1]) around which the should be drawn. (default: 0.5, 0.5)
+ ///
+ public Point Center
+ {
+ get => _center;
+ set
+ {
+ if (SetProperty(ref _center, value))
+ CalculateReferenceDistance();
+ }
+ }
+
+ #endregion
+
+ #region Constructors
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The gradient drawn by the brush.
+ public RadialGradientTexture(Size size, IGradient gradient)
+ : base(size, gradient)
+ { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The center point (as percentage in the range [0..1]).
+ /// The gradient drawn by the brush.
+ public RadialGradientTexture(Size size, IGradient gradient, Point center)
+ : base(size, gradient)
+ {
+ this.Center = center;
+ }
+
+ #endregion
+
+ #region Methods
+
+ private void CalculateReferenceDistance()
+ {
+ float referenceX = Center.X < 0.5f ? 1 : 0;
+ float referenceY = Center.Y < 0.5f ? 1 : 0;
+ _referenceDistance = GradientHelper.CalculateDistance(new Point(referenceX, referenceY), Center);
+ }
+
+ protected override Color GetColor(in Point point)
+ {
+ float distance = GradientHelper.CalculateDistance(point, Center);
+ float offset = distance / _referenceDistance;
+ return Gradient.GetColor(offset);
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Presets/Textures/Sampler/AverageByteSampler.cs b/RGB.NET.Presets/Textures/Sampler/AverageByteSampler.cs
new file mode 100644
index 0000000..b2f3770
--- /dev/null
+++ b/RGB.NET.Presets/Textures/Sampler/AverageByteSampler.cs
@@ -0,0 +1,30 @@
+using System;
+using RGB.NET.Core;
+
+namespace RGB.NET.Presets.Textures.Sampler
+{
+ public class AverageByteSampler : ISampler
+ {
+ #region Methods
+
+ public void SampleColor(in SamplerInfo info, in Span pixelData)
+ {
+ int count = info.Width * info.Height;
+ if (count == 0) return;
+
+ ReadOnlySpan data = info.Data;
+
+ int dataLength = pixelData.Length;
+ Span sums = stackalloc uint[dataLength];
+ for (int i = 0; i < data.Length; i += dataLength)
+ for (int j = 0; j < sums.Length; j++)
+ sums[j] += data[i + j];
+
+ float divisor = count * byte.MaxValue;
+ for (int i = 0; i < pixelData.Length; i++)
+ pixelData[i] = (sums[i] / divisor).GetByteValueFromPercentage();
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.Presets/Textures/Sampler/AverageFloatSampler.cs b/RGB.NET.Presets/Textures/Sampler/AverageFloatSampler.cs
new file mode 100644
index 0000000..12b0368
--- /dev/null
+++ b/RGB.NET.Presets/Textures/Sampler/AverageFloatSampler.cs
@@ -0,0 +1,29 @@
+using System;
+using RGB.NET.Core;
+
+namespace RGB.NET.Presets.Textures.Sampler
+{
+ public class AverageFloatSampler : ISampler
+ {
+ #region Methods
+
+ public void SampleColor(in SamplerInfo info, in Span pixelData)
+ {
+ int count = info.Width * info.Height;
+ if (count == 0) return;
+
+ ReadOnlySpan data = info.Data;
+
+ int dataLength = pixelData.Length;
+ Span sums = stackalloc float[dataLength];
+ for (int i = 0; i < data.Length; i += dataLength)
+ for (int j = 0; j < sums.Length; j++)
+ sums[j] += data[i + j];
+
+ for (int i = 0; i < pixelData.Length; i++)
+ pixelData[i] = sums[i] / count;
+ }
+
+ #endregion
+ }
+}
diff --git a/RGB.NET.sln b/RGB.NET.sln
index 7a1fb70..c9ec688 100644
--- a/RGB.NET.sln
+++ b/RGB.NET.sln
@@ -5,8 +5,6 @@ VisualStudioVersion = 16.0.29424.173
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{D13032C6-432E-4F43-8A32-071133C22B16}"
EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Presets", "Presets", "{EBC33090-8494-4DF4-B4B6-64D0E531E93F}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Core", "RGB.NET.Core\RGB.NET.Core.csproj", "{F3ED5768-7251-4347-8D8F-2866313DA658}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.CoolerMaster", "RGB.NET.Devices.CoolerMaster\RGB.NET.Devices.CoolerMaster.csproj", "{E8F927F5-E7CF-464A-B9AE-824C2B29A7D1}"
@@ -25,11 +23,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Novation",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Razer", "RGB.NET.Devices.Razer\RGB.NET.Devices.Razer.csproj", "{2E162CB7-2C6C-4069-8356-06162F7BE0AA}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Brushes", "RGB.NET.Brushes\RGB.NET.Brushes.csproj", "{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Decorators", "RGB.NET.Decorators\RGB.NET.Decorators.csproj", "{8725C448-818C-41F7-B23F-F97E062BF233}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Groups", "RGB.NET.Groups\RGB.NET.Groups.csproj", "{6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Presets", "RGB.NET.Presets\RGB.NET.Presets.csproj", "{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.WS281X", "RGB.NET.Devices.WS281X\RGB.NET.Devices.WS281X.csproj", "{0AD382DA-E999-4F74-9658-8D402EE9BF3F}"
EndProject
@@ -91,14 +85,6 @@ Global
{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Release|Any CPU.Build.0 = Release|Any CPU
- {8725C448-818C-41F7-B23F-F97E062BF233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8725C448-818C-41F7-B23F-F97E062BF233}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8725C448-818C-41F7-B23F-F97E062BF233}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8725C448-818C-41F7-B23F-F97E062BF233}.Release|Any CPU.Build.0 = Release|Any CPU
- {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Release|Any CPU.Build.0 = Release|Any CPU
{0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -136,9 +122,6 @@ Global
{00BA7E8E-822A-42DA-9EB4-DDBBC7CB0E46} = {D13032C6-432E-4F43-8A32-071133C22B16}
{19F701FD-5577-4873-9BE6-6775676FA185} = {D13032C6-432E-4F43-8A32-071133C22B16}
{2E162CB7-2C6C-4069-8356-06162F7BE0AA} = {D13032C6-432E-4F43-8A32-071133C22B16}
- {B159FB51-5939-490E-A1BA-FB55D4D7ADDF} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F}
- {8725C448-818C-41F7-B23F-F97E062BF233} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F}
- {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F}
{0AD382DA-E999-4F74-9658-8D402EE9BF3F} = {D13032C6-432E-4F43-8A32-071133C22B16}
{FFDE4387-60F2-47B6-9704-3A57D02B8C64} = {D13032C6-432E-4F43-8A32-071133C22B16}
{A3FD5AD7-040A-47CA-A278-53493A25FF8A} = {92D7C263-D4C9-4D26-93E2-93C1F9C2CD16}
diff --git a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs
index bd0fda1..4b22146 100644
--- a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs
+++ b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs
@@ -221,36 +221,36 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void RGBPercentConstructorTest()
{
- Core.Color color = new(0.25341, 0.55367, 1);
+ Core.Color color = new(0.25341f, 0.55367f, 1);
- Assert.AreEqual(1, color.A, DoubleExtensions.TOLERANCE, "A is not 1");
- Assert.AreEqual(0.25341, color.R, DoubleExtensions.TOLERANCE, "R is not 0.25341");
- Assert.AreEqual(0.55367, color.G, DoubleExtensions.TOLERANCE, "G is not 0.55367");
- Assert.AreEqual(1, color.B, DoubleExtensions.TOLERANCE, "B is not 1");
+ Assert.AreEqual(1, color.A, FloatExtensions.TOLERANCE, "A is not 1");
+ Assert.AreEqual(0.25341, color.R, FloatExtensions.TOLERANCE, "R is not 0.25341");
+ Assert.AreEqual(0.55367, color.G, FloatExtensions.TOLERANCE, "G is not 0.55367");
+ Assert.AreEqual(1, color.B, FloatExtensions.TOLERANCE, "B is not 1");
}
[TestMethod]
public void ARGBPercentConstructorTest()
{
- Core.Color color = new(0.3315, 0.25341, 0.55367, 1);
+ Core.Color color = new(0.3315f, 0.25341f, 0.55367f, 1);
- Assert.AreEqual(0.3315, color.A, DoubleExtensions.TOLERANCE, "A is not 0.3315");
- Assert.AreEqual(0.25341, color.R, DoubleExtensions.TOLERANCE, "R is not 0.25341");
- Assert.AreEqual(0.55367, color.G, DoubleExtensions.TOLERANCE, "G is not 0.55367");
- Assert.AreEqual(1, color.B, DoubleExtensions.TOLERANCE, "B is not 1");
+ Assert.AreEqual(0.3315f, color.A, FloatExtensions.TOLERANCE, "A is not 0.3315");
+ Assert.AreEqual(0.25341f, color.R, FloatExtensions.TOLERANCE, "R is not 0.25341");
+ Assert.AreEqual(0.55367f, color.G, FloatExtensions.TOLERANCE, "G is not 0.55367");
+ Assert.AreEqual(1, color.B, FloatExtensions.TOLERANCE, "B is not 1");
}
[TestMethod]
public void RGBPercentConstructorClampTest()
{
- Core.Color color1 = new(1.1, 1.1, 1.1);
+ Core.Color color1 = new(1.1f, 1.1f, 1.1f);
Assert.AreEqual(1, color1.A, "A is not 1");
Assert.AreEqual(1, color1.R, "R is not 1");
Assert.AreEqual(1, color1.G, "G is not 1");
Assert.AreEqual(1, color1.B, "B is not 1");
- Core.Color color2 = new(-1.0, -1.0, -1.0);
+ Core.Color color2 = new(-1.0f, -1.0f, -1.0f);
Assert.AreEqual(1, color2.A, "A is not 1");
Assert.AreEqual(0, color2.R, "R is not 0");
@@ -261,14 +261,14 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void ARGBPercentConstructorClampTest()
{
- Core.Color color1 = new(1.1, 1.1, 1.1, 1.1);
+ Core.Color color1 = new(1.1f, 1.1f, 1.1f, 1.1f);
Assert.AreEqual(1, color1.A, "A is not 1");
Assert.AreEqual(1, color1.R, "R is not 1");
Assert.AreEqual(1, color1.G, "G is not 1");
Assert.AreEqual(1, color1.B, "B is not 1");
- Core.Color color2 = new(-1.0, -1.0, -1.0, -1.0);
+ Core.Color color2 = new(-1.0f, -1.0f, -1.0f, -1.0f);
Assert.AreEqual(0, color2.A, "A is not 0");
Assert.AreEqual(0, color2.R, "R is not 0");
@@ -324,13 +324,13 @@ namespace RGB.NET.Core.Tests.Color
Assert.AreEqual(1, color2.A);
Core.Color color3 = new(128, 0, 0, 0);
- Assert.AreEqual(128 / 255.0, color3.A);
+ Assert.AreEqual(128 / 255.0f, color3.A);
Core.Color color4 = new(30, 0, 0, 0);
- Assert.AreEqual(30 / 255.0, color4.A);
+ Assert.AreEqual(30 / 255.0f, color4.A);
Core.Color color5 = new(201, 0, 0, 0);
- Assert.AreEqual(201 / 255.0, color5.A);
+ Assert.AreEqual(201 / 255.0f, color5.A);
}
[TestMethod]
@@ -343,13 +343,13 @@ namespace RGB.NET.Core.Tests.Color
Assert.AreEqual(1, color2.R);
Core.Color color3 = new(0, 128, 0, 0);
- Assert.AreEqual(128 / 255.0, color3.R);
+ Assert.AreEqual(128 / 255.0f, color3.R);
Core.Color color4 = new(0, 30, 0, 0);
- Assert.AreEqual(30 / 255.0, color4.R);
+ Assert.AreEqual(30 / 255.0f, color4.R);
Core.Color color5 = new(0, 201, 0, 0);
- Assert.AreEqual(201 / 255.0, color5.R);
+ Assert.AreEqual(201 / 255.0f, color5.R);
}
[TestMethod]
@@ -362,13 +362,13 @@ namespace RGB.NET.Core.Tests.Color
Assert.AreEqual(1, color2.G);
Core.Color color3 = new(0, 0, 128, 0);
- Assert.AreEqual(128 / 255.0, color3.G);
+ Assert.AreEqual(128 / 255.0f, color3.G);
Core.Color color4 = new(0, 0, 30, 0);
- Assert.AreEqual(30 / 255.0, color4.G);
+ Assert.AreEqual(30 / 255.0f, color4.G);
Core.Color color5 = new(0, 0, 201, 0);
- Assert.AreEqual(201 / 255.0, color5.G);
+ Assert.AreEqual(201 / 255.0f, color5.G);
}
[TestMethod]
@@ -381,13 +381,13 @@ namespace RGB.NET.Core.Tests.Color
Assert.AreEqual(1, color2.B);
Core.Color color3 = new(0, 0, 0, 128);
- Assert.AreEqual(128 / 255.0, color3.B);
+ Assert.AreEqual(128 / 255.0f, color3.B);
Core.Color color4 = new(0, 0, 0, 30);
- Assert.AreEqual(30 / 255.0, color4.B);
+ Assert.AreEqual(30 / 255.0f, color4.B);
Core.Color color5 = new(0, 0, 0, 201);
- Assert.AreEqual(201 / 255.0, color5.B);
+ Assert.AreEqual(201 / 255.0f, color5.B);
}
#endregion
diff --git a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs
index 823a203..7d365c5 100644
--- a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs
+++ b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs
@@ -12,55 +12,55 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void AddHueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.AddHSV(hue: 30);
- Assert.AreEqual(HSVColor.Create(210, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(210, 0.5f, 0.5f), result);
}
[TestMethod]
public void AddHueWrapTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.AddHSV(hue: 220);
- Assert.AreEqual(HSVColor.Create(40, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(40, 0.5f, 0.5f), result);
}
[TestMethod]
public void AddSaturationTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.AddHSV(saturation: 0.3);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddHSV(saturation: 0.3f);
- Assert.AreEqual(HSVColor.Create(180, 0.8, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.8f, 0.5f), result);
}
[TestMethod]
public void AddSaturationClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.AddHSV(saturation: 0.8);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddHSV(saturation: 0.8f);
- Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 1.0f, 0.5f), result);
}
[TestMethod]
public void AddValueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.AddHSV(value: 0.3);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddHSV(value: 0.3f);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 0.8), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.8f), result);
}
[TestMethod]
public void AddValueClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.AddHSV(value: 0.8);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddHSV(value: 0.8f);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 1.0f), result);
}
#endregion
@@ -70,55 +70,55 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SubtractHueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SubtractHSV(hue: 30);
- Assert.AreEqual(HSVColor.Create(150, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(150, 0.5f, 0.5f), result);
}
[TestMethod]
public void SubtractHueWrapTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SubtractHSV(hue: 220);
- Assert.AreEqual(HSVColor.Create(320, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(320, 0.5f, 0.5f), result);
}
[TestMethod]
public void SubtractSaturationTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.SubtractHSV(saturation: 0.3);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractHSV(saturation: 0.3f);
- Assert.AreEqual(HSVColor.Create(180, 0.2, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.2f, 0.5f), result);
}
[TestMethod]
public void SubtractSaturationClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.SubtractHSV(saturation: 0.8);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractHSV(saturation: 0.8f);
- Assert.AreEqual(HSVColor.Create(180, 0, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 0, 0.5f), result);
}
[TestMethod]
public void SubtractValueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.SubtractHSV(value: 0.3);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractHSV(value: 0.3f);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 0.2), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.2f), result);
}
[TestMethod]
public void SubtractValueClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.SubtractHSV(value: .8);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractHSV(value: 0.8f);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 0), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 0), result);
}
#endregion
@@ -128,55 +128,55 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void MultiplyHueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.MultiplyHSV(hue: 1.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.MultiplyHSV(hue: 1.5f);
- Assert.AreEqual(HSVColor.Create(270, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(270, 0.5f, 0.5f), result);
}
[TestMethod]
public void MultiplyHueWrapTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.MultiplyHSV(hue: 3);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.5f), result);
}
[TestMethod]
public void MultiplySaturationTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.2, 0.2);
+ Core.Color baseColor = HSVColor.Create(180, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyHSV(saturation: 3);
- Assert.AreEqual(HSVColor.Create(180, 0.6, 0.2), result);
+ Assert.AreEqual(HSVColor.Create(180,0.6f, 0.2f), result);
}
[TestMethod]
public void MultiplySaturationClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.MultiplyHSV(saturation: 3);
- Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 1.0f, 0.5f), result);
}
[TestMethod]
public void MultiplyValueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.2, 0.2);
+ Core.Color baseColor = HSVColor.Create(180, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyHSV(value: 3);
- Assert.AreEqual(HSVColor.Create(180, 0.2, 0.6), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.2f,0.6f), result);
}
[TestMethod]
public void MultiplyValueClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.MultiplyHSV(value: 3);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 1.0f), result);
}
#endregion
@@ -186,28 +186,28 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void DivideHueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.DivideHSV(hue: 30);
- Assert.AreEqual(HSVColor.Create(6, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(6, 0.5f, 0.5f), result);
}
[TestMethod]
public void DivideSaturationTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.6, 0.6);
+ Core.Color baseColor = HSVColor.Create(180,0.6f,0.6f);
Core.Color result = baseColor.DivideHSV(saturation: 2);
- Assert.AreEqual(HSVColor.Create(180, 0.3, 0.6), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.3f,0.6f), result);
}
[TestMethod]
public void DivideValueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.6, 0.6);
+ Core.Color baseColor = HSVColor.Create(180,0.6f,0.6f);
Core.Color result = baseColor.DivideHSV(value: 2);
- Assert.AreEqual(HSVColor.Create(180, 0.6, 0.3), result);
+ Assert.AreEqual(HSVColor.Create(180,0.6f, 0.3f), result);
}
#endregion
@@ -217,64 +217,64 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SetHueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SetHSV(hue: 30);
- Assert.AreEqual(HSVColor.Create(30, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(30, 0.5f, 0.5f), result);
}
[TestMethod]
public void SetHueWrapTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SetHSV(hue: 440);
- Assert.AreEqual(HSVColor.Create(80, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(80, 0.5f, 0.5f), result);
}
[TestMethod]
public void SetHueWrapNegativeTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SetHSV(hue: -30);
- Assert.AreEqual(HSVColor.Create(330, 0.5, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(330, 0.5f, 0.5f), result);
}
[TestMethod]
public void SetSaturationTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.SetHSV(saturation: 0.3);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetHSV(saturation: 0.3f);
- Assert.AreEqual(HSVColor.Create(180, 0.3, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.3f, 0.5f), result);
}
[TestMethod]
public void SetSaturationClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SetHSV(saturation: 2);
- Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result);
+ Assert.AreEqual(HSVColor.Create(180, 1.0f, 0.5f), result);
}
[TestMethod]
public void SetValueTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
- Core.Color result = baseColor.SetHSV(value: 0.3);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetHSV(value: 0.3f);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 0.3), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.3f), result);
}
[TestMethod]
public void SetValueClampTest()
{
- Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5);
+ Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f);
Core.Color result = baseColor.SetHSV(value: 2);
- Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result);
+ Assert.AreEqual(HSVColor.Create(180, 0.5f, 1.0f), result);
}
#endregion
diff --git a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs
index 7a9abc9..ea5a1cc 100644
--- a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs
+++ b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs
@@ -30,19 +30,19 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void BlendUpTest()
{
- Core.Color baseColor = new(0.0, 0.0, 0.0);
- Core.Color blendColor = new(0.5, 1.0, 1.0, 1.0);
+ Core.Color baseColor = new(0.0f, 0.0f, 0.0f);
+ Core.Color blendColor = new(0.5f, 1.0f, 1.0f, 1.0f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor));
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f), baseColor.Blend(blendColor));
}
[TestMethod]
public void BlendDownTest()
{
- Core.Color baseColor = new(1.0, 1.0, 1.0);
- Core.Color blendColor = new(0.5, 0.0, 0.0, 0.0);
+ Core.Color baseColor = new(1.0f, 1.0f, 1.0f);
+ Core.Color blendColor = new(0.5f, 0.0f, 0.0f, 0.0f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor));
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f), baseColor.Blend(blendColor));
}
#endregion
@@ -61,10 +61,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void AddRGBPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.AddRGB(0.2, 0.3, 0.4);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddRGB(0.2f, 0.3f, 0.4f);
- Assert.AreEqual(new Core.Color(0.5, 0.7, 0.8, 0.9), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.7f, 0.8f, 0.9f), result);
}
[TestMethod]
@@ -79,10 +79,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void AddAPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.AddA(0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddA(0.1f);
- Assert.AreEqual(new Core.Color(0.6, 0.5, 0.5, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.6f, 0.5f, 0.5f, 0.5f), result);
}
[TestMethod]
@@ -97,10 +97,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void AddRPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.AddRGB(r: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddRGB(r: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.6, 0.5, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.6f, 0.5f, 0.5f), result);
}
[TestMethod]
@@ -115,10 +115,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void AddGPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.AddRGB(g: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddRGB(g: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.6, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.6f, 0.5f), result);
}
[TestMethod]
@@ -133,10 +133,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void AddBPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.AddRGB(b: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.AddRGB(b: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.6), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f, 0.6f), result);
}
#endregion
@@ -155,10 +155,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SubtractRGBPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SubtractRGB(0.2, 0.3, 0.4);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractRGB(0.2f, 0.3f, 0.4f);
- Assert.AreEqual(new Core.Color(0.5, 0.3, 0.2, 0.1), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.3f, 0.2f, 0.1f), result);
}
[TestMethod]
@@ -173,10 +173,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SubtractAPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SubtractA(0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractA(0.1f);
- Assert.AreEqual(new Core.Color(0.4, 0.5, 0.5, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.4f, 0.5f, 0.5f, 0.5f), result);
}
[TestMethod]
@@ -191,10 +191,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SubtractRPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SubtractRGB(r: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractRGB(r: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.4, 0.5, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.4f, 0.5f, 0.5f), result);
}
[TestMethod]
@@ -209,10 +209,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SubtractGPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SubtractRGB(g: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractRGB(g: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.4, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.4f, 0.5f), result);
}
[TestMethod]
@@ -227,10 +227,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SubtractBPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SubtractRGB(b: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SubtractRGB(b: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.4), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f, 0.4f), result);
}
#endregion
@@ -240,46 +240,46 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void MultiplyRGBPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyRGB(3, 4, 5);
- Assert.AreEqual(new Core.Color(0.2, 0.6, 0.8, 1.0), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.6f, 0.8f, 1.0f), result);
}
[TestMethod]
public void MultiplyAPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyA(3);
- Assert.AreEqual(new Core.Color(0.6, 0.2, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.6f, 0.2f, 0.2f, 0.2f), result);
}
[TestMethod]
public void MultiplyRPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyRGB(r: 3);
- Assert.AreEqual(new Core.Color(0.2, 0.6, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.6f, 0.2f, 0.2f), result);
}
[TestMethod]
public void MultiplyGPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyRGB(g: 3);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.6, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.6f, 0.2f), result);
}
[TestMethod]
public void MultiplyBPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f);
Core.Color result = baseColor.MultiplyRGB(b: 3);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.6), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.6f), result);
}
#endregion
@@ -289,46 +289,46 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void DivideRGBPercentTest()
{
- Core.Color baseColor = new(0.2, 0.6, 0.8, 1.0);
+ Core.Color baseColor = new(0.2f, 0.6f, 0.8f, 1.0f);
Core.Color result = baseColor.DivideRGB(3, 4, 5);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result);
}
[TestMethod]
public void DivideAPercentTest()
{
- Core.Color baseColor = new(0.6, 0.2, 0.2, 0.2);
+ Core.Color baseColor = new(0.6f, 0.2f, 0.2f, 0.2f);
Core.Color result = baseColor.DivideA(3);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result);
}
[TestMethod]
public void DivideRPercentTest()
{
- Core.Color baseColor = new(0.2, 0.6, 0.2, 0.2);
+ Core.Color baseColor = new(0.2f, 0.6f, 0.2f, 0.2f);
Core.Color result = baseColor.DivideRGB(r: 3);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result);
}
[TestMethod]
public void DivideGPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.6, 0.2);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.6f, 0.2f);
Core.Color result = baseColor.DivideRGB(g: 3);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result);
}
[TestMethod]
public void DivideBPercentTest()
{
- Core.Color baseColor = new(0.2, 0.2, 0.2, 0.6);
+ Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.6f);
Core.Color result = baseColor.DivideRGB(b: 3);
- Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result);
+ Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result);
}
#endregion
@@ -347,10 +347,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SetRGBPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SetRGB(0.2, 0.3, 0.4);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetRGB(0.2f, 0.3f, 0.4f);
- Assert.AreEqual(new Core.Color(0.5, 0.2, 0.3, 0.4), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.2f, 0.3f, 0.4f), result);
}
[TestMethod]
@@ -365,10 +365,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SetAPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SetA(0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetA(0.1f);
- Assert.AreEqual(new Core.Color(0.1, 0.5, 0.5, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.1f, 0.5f, 0.5f, 0.5f), result);
}
[TestMethod]
@@ -383,10 +383,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SetRPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SetRGB(r: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetRGB(r: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.1, 0.5, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.1f, 0.5f, 0.5f), result);
}
[TestMethod]
@@ -401,10 +401,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SetGPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SetRGB(g: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetRGB(g: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.1, 0.5), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.1f, 0.5f), result);
}
[TestMethod]
@@ -419,10 +419,10 @@ namespace RGB.NET.Core.Tests.Color
[TestMethod]
public void SetBPercentTest()
{
- Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5);
- Core.Color result = baseColor.SetRGB(b: 0.1);
+ Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f);
+ Core.Color result = baseColor.SetRGB(b: 0.1f);
- Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.1), result);
+ Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f, 0.1f), result);
}
#endregion