diff --git a/Documentation/DeviceLayout.xsd b/Documentation/DeviceLayout.xsd index 91ced39..d534089 100644 --- a/Documentation/DeviceLayout.xsd +++ b/Documentation/DeviceLayout.xsd @@ -13,11 +13,17 @@ - - - + + + + + + + + + @@ -28,6 +34,13 @@ + + + + + + + @@ -35,32 +48,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs b/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs index 9c25109..127ce9c 100644 --- a/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs +++ b/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs @@ -29,7 +29,7 @@ namespace RGB.NET.Brushes set => SetProperty(ref _origin, value); } - private Point _center = new Point(0.5, 0.5); + 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) /// @@ -39,12 +39,12 @@ namespace RGB.NET.Brushes set => SetProperty(ref _center, value); } - private IGradient _gradient; + private IGradient? _gradient; /// /// /// Gets or sets the gradient drawn by the brush. If null it will default to full transparent. /// - public IGradient Gradient + public IGradient? Gradient { get => _gradient; set => SetProperty(ref _gradient, value); @@ -104,6 +104,8 @@ namespace RGB.NET.Brushes /// 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; diff --git a/RGB.NET.Brushes/Brushes/IGradientBrush.cs b/RGB.NET.Brushes/Brushes/IGradientBrush.cs index 5677154..80522a3 100644 --- a/RGB.NET.Brushes/Brushes/IGradientBrush.cs +++ b/RGB.NET.Brushes/Brushes/IGradientBrush.cs @@ -12,6 +12,6 @@ namespace RGB.NET.Brushes /// /// Gets the used by this . /// - IGradient Gradient { get; } + IGradient? Gradient { get; } } } diff --git a/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs b/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs index 0880e4c..c175068 100644 --- a/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs +++ b/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs @@ -20,7 +20,7 @@ namespace RGB.NET.Brushes { #region Properties & Fields - private Point _startPoint = new Point(0, 0.5); + 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) /// @@ -30,7 +30,7 @@ namespace RGB.NET.Brushes set => SetProperty(ref _startPoint, value); } - private Point _endPoint = new Point(1, 0.5); + 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) /// @@ -40,9 +40,9 @@ namespace RGB.NET.Brushes set => SetProperty(ref _endPoint, value); } - private IGradient _gradient; + private IGradient? _gradient; /// - public IGradient Gradient + public IGradient? Gradient { get => _gradient; set => SetProperty(ref _gradient, value); @@ -97,8 +97,8 @@ namespace RGB.NET.Brushes { if (Gradient == null) return Color.Transparent; - Point startPoint = new Point(StartPoint.X * rectangle.Size.Width, StartPoint.Y * rectangle.Size.Height); - Point endPoint = new Point(EndPoint.X * rectangle.Size.Width, EndPoint.Y * rectangle.Size.Height); + 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); diff --git a/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs b/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs index 58df28e..9d2ee34 100644 --- a/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs +++ b/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs @@ -18,7 +18,7 @@ namespace RGB.NET.Brushes { #region Properties & Fields - private Point _center = new Point(0.5, 0.5); + 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) /// @@ -28,9 +28,9 @@ namespace RGB.NET.Brushes set => SetProperty(ref _center, value); } - private IGradient _gradient; + private IGradient? _gradient; /// - public IGradient Gradient + public IGradient? Gradient { get => _gradient; set => SetProperty(ref _gradient, value); @@ -78,7 +78,7 @@ namespace RGB.NET.Brushes { if (Gradient == null) return Color.Transparent; - Point centerPoint = new Point(rectangle.Location.X + (rectangle.Size.Width * Center.X), rectangle.Location.Y + (rectangle.Size.Height * Center.Y)); + 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 ... diff --git a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs b/RGB.NET.Brushes/Brushes/SolidColorBrush.cs index 3620ea5..8bbd68b 100644 --- a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs +++ b/RGB.NET.Brushes/Brushes/SolidColorBrush.cs @@ -52,7 +52,7 @@ namespace RGB.NET.Brushes /// Converts a to a . /// /// The to convert. - public static explicit operator SolidColorBrush(Color color) => new SolidColorBrush(color); + public static explicit operator SolidColorBrush(Color color) => new(color); /// /// Converts a to a . diff --git a/RGB.NET.Brushes/Gradients/AbstractGradient.cs b/RGB.NET.Brushes/Gradients/AbstractGradient.cs index c32a0da..2a6350b 100644 --- a/RGB.NET.Brushes/Gradients/AbstractGradient.cs +++ b/RGB.NET.Brushes/Gradients/AbstractGradient.cs @@ -23,7 +23,7 @@ namespace RGB.NET.Brushes.Gradients /// /// Gets a list of the stops used by this . /// - public ObservableCollection GradientStops { get; } = new ObservableCollection(); + public ObservableCollection GradientStops { get; } = new(); private bool _wrapGradient; /// @@ -42,7 +42,7 @@ namespace RGB.NET.Brushes.Gradients #region Events /// - public event EventHandler GradientChanged; + public event EventHandler? GradientChanged; #endregion @@ -54,7 +54,7 @@ namespace RGB.NET.Brushes.Gradients protected AbstractGradient() { GradientStops.CollectionChanged += GradientCollectionChanged; - PropertyChanged += (sender, args) => OnGradientChanged(); + PropertyChanged += (_, _) => OnGradientChanged(); } /// @@ -64,7 +64,7 @@ namespace RGB.NET.Brushes.Gradients protected AbstractGradient(params GradientStop[] gradientStops) { GradientStops.CollectionChanged += GradientCollectionChanged; - PropertyChanged += (sender, args) => OnGradientChanged(); + PropertyChanged += (_, _) => OnGradientChanged(); foreach (GradientStop gradientStop in gradientStops) GradientStops.Add(gradientStop); @@ -80,7 +80,7 @@ namespace RGB.NET.Brushes.Gradients this.WrapGradient = wrapGradient; GradientStops.CollectionChanged += GradientCollectionChanged; - PropertyChanged += (sender, args) => OnGradientChanged(); + PropertyChanged += (_, _) => OnGradientChanged(); foreach (GradientStop gradientStop in gradientStops) GradientStops.Add(gradientStop); @@ -128,9 +128,9 @@ namespace RGB.NET.Brushes.Gradients /// /// Should be called to indicate that the gradient was changed. /// - protected void OnGradientChanged() => GradientChanged?.Invoke(this, null); + protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty); - private void GradientCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + private void GradientCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (e.OldItems != null) foreach (GradientStop gradientStop in e.OldItems) @@ -143,7 +143,7 @@ namespace RGB.NET.Brushes.Gradients OnGradientChanged(); } - private void GradientStopChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnGradientChanged(); + private void GradientStopChanged(object? sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnGradientChanged(); #endregion } diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Brushes/Gradients/LinearGradient.cs index 535fe5d..f22ec24 100644 --- a/RGB.NET.Brushes/Gradients/LinearGradient.cs +++ b/RGB.NET.Brushes/Gradients/LinearGradient.cs @@ -16,7 +16,7 @@ namespace RGB.NET.Brushes.Gradients #region Properties & Fields private bool _isOrderedGradientListDirty = true; - private LinkedList _orderedGradientStops; + private LinkedList _orderedGradientStops = new(); #endregion @@ -60,12 +60,12 @@ namespace RGB.NET.Brushes.Gradients private void Initialize() { - void OnGradientStopOnPropertyChanged(object sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true; + void OnGradientStopOnPropertyChanged(object? sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true; foreach (GradientStop gradientStop in GradientStops) gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged; - GradientStops.CollectionChanged += (sender, args) => + GradientStops.CollectionChanged += (_, args) => { if (args.OldItems != null) foreach (GradientStop gradientStop in args.OldItems) @@ -114,18 +114,18 @@ namespace RGB.NET.Brushes.Gradients /// protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(double offset, LinkedList orderedStops, bool wrap) { - LinkedList gradientStops = new LinkedList(orderedStops); + LinkedList gradientStops = new(orderedStops); if (wrap) { - GradientStop gsBefore, gsAfter; + GradientStop? gsBefore, gsAfter; do { gsBefore = gradientStops.LastOrDefault(n => n.Offset <= offset); if (gsBefore == null) { - GradientStop lastStop = gradientStops.Last.Value; + GradientStop lastStop = gradientStops.Last!.Value; gradientStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color)); gradientStops.RemoveLast(); } @@ -133,7 +133,7 @@ namespace RGB.NET.Brushes.Gradients gsAfter = gradientStops.FirstOrDefault(n => n.Offset >= offset); if (gsAfter == null) { - GradientStop firstStop = gradientStops.First.Value; + GradientStop firstStop = gradientStops.First!.Value; gradientStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color)); gradientStops.RemoveFirst(); } diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Brushes/Gradients/RainbowGradient.cs index 01946d0..2c5c2b6 100644 --- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs +++ b/RGB.NET.Brushes/Gradients/RainbowGradient.cs @@ -41,7 +41,7 @@ namespace RGB.NET.Brushes.Gradients #region Events /// - public event EventHandler GradientChanged; + public event EventHandler? GradientChanged; #endregion @@ -57,7 +57,7 @@ namespace RGB.NET.Brushes.Gradients this.StartHue = startHue; this.EndHue = endHue; - PropertyChanged += (sender, args) => OnGradientChanged(); + PropertyChanged += (_, _) => OnGradientChanged(); } #endregion @@ -85,7 +85,7 @@ namespace RGB.NET.Brushes.Gradients StartHue += offset; EndHue += offset; - + while ((StartHue > 360) && (EndHue > 360)) { StartHue -= 360; @@ -101,7 +101,7 @@ namespace RGB.NET.Brushes.Gradients /// /// Should be called to indicate that the gradient was changed. /// - protected void OnGradientChanged() => GradientChanged?.Invoke(this, null); + protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty); #endregion } diff --git a/RGB.NET.Core/Brushes/AbstractBrush.cs b/RGB.NET.Core/Brushes/AbstractBrush.cs index 7521bf2..541b6ac 100644 --- a/RGB.NET.Core/Brushes/AbstractBrush.cs +++ b/RGB.NET.Core/Brushes/AbstractBrush.cs @@ -35,7 +35,7 @@ namespace RGB.NET.Core public Rectangle RenderedRectangle { get; protected set; } /// - public Dictionary RenderedTargets { get; } = new Dictionary(); + public Dictionary RenderedTargets { get; } = new(); #endregion diff --git a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs index e666f6f..40b0eec 100644 --- a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs +++ b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs @@ -2,23 +2,6 @@ { public class DefaultColorBehavior : IColorBehavior { - #region Properties & Fields - - private static DefaultColorBehavior _instance = new DefaultColorBehavior(); - /// - /// Gets the singleton instance of . - /// - public static DefaultColorBehavior Instance { get; } = _instance; - - #endregion - - #region Constructors - - private DefaultColorBehavior() - { } - - #endregion - #region Methods /// @@ -32,7 +15,7 @@ /// /// 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(Color color, object? obj) { if (!(obj is Color)) return false; diff --git a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs index 630aca5..3ee7b78 100644 --- a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs +++ b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs @@ -4,7 +4,7 @@ { string ToString(Color color); - bool Equals(Color color, object obj); + bool Equals(Color color, object? obj); int GetHashCode(Color color); diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs index 81a3a33..e389f19 100644 --- a/RGB.NET.Core/Color/Color.cs +++ b/RGB.NET.Core/Color/Color.cs @@ -7,33 +7,27 @@ using System.Diagnostics; namespace RGB.NET.Core { - /// /// /// Represents an ARGB (alpha, red, green, blue) color. /// [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] - public struct Color + public readonly struct Color { #region Constants /// /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0] /// - public static Color Transparent => new Color(0, 0, 0, 0); + public static Color Transparent => new(0, 0, 0, 0); #endregion #region Properties & Fields - private static IColorBehavior _behavior = DefaultColorBehavior.Instance; /// /// Gets or sets the used to perform operations on colors. /// - public static IColorBehavior Behavior - { - get => _behavior; - set => _behavior = value ?? DefaultColorBehavior.Instance; - } + public static IColorBehavior Behavior { get; set; } = new DefaultColorBehavior(); /// /// Gets the alpha component value of this as percentage in the range [0..1]. @@ -199,12 +193,13 @@ namespace RGB.NET.Core /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) => Behavior.Equals(this, obj); + public override bool Equals(object? obj) => Behavior.Equals(this, obj); /// /// Returns a hash code for this , as defined by the current . /// /// An integer value that specifies the hash code for this . + // ReSharper disable once NonReadonlyMemberInGetHashCode public override int GetHashCode() => Behavior.GetHashCode(this); /// @@ -246,42 +241,42 @@ namespace RGB.NET.Core /// /// The containing the components. /// The color. - public static implicit operator Color((byte r, byte g, byte b) components) => new Color(components.r, components.g, components.b); + public static implicit operator Color((byte r, byte g, byte 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((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b); + public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new(components.a, components.r, components.g, components.b); /// /// Converts a of ARGB-components to a . /// /// The containing the components. /// The color. - public static implicit operator Color((int r, int g, int b) components) => new Color(components.r, components.g, components.b); + public static implicit operator Color((int r, int g, int 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((int a, int r, int g, int b) components) => new Color(components.a, components.r, components.g, components.b); + public static implicit operator Color((int a, int r, int g, int b) components) => new(components.a, 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 r, double g, double b) components) => new Color(components.r, components.g, components.b); + public static implicit operator Color((double r, double g, double 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 Color(components.a, components.r, components.g, components.b); + public static implicit operator Color((double a, double r, double g, double 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 f99581c..741a654 100644 --- a/RGB.NET.Core/Color/HSVColor.cs +++ b/RGB.NET.Core/Color/HSVColor.cs @@ -82,7 +82,7 @@ namespace RGB.NET.Core (double cHue, double cSaturation, double cValue) = color.GetHSV(); return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value); } - + /// /// Divides the given HSV values to this color. /// @@ -180,7 +180,7 @@ namespace RGB.NET.Core else // b is max hue = 4.0 + ((r - g) / (max - min)); - hue = hue * 60.0; + hue *= 60.0; hue = hue.Wrap(0, 360); double saturation = max.EqualsInTolerance(0) ? 0 : 1.0 - (min / max); @@ -205,21 +205,15 @@ namespace RGB.NET.Core double q = v * (1.0 - (s * ff)); double t = v * (1.0 - (s * (1.0 - ff))); - switch (i) + return i switch { - case 0: - return (v, t, p); - case 1: - return (q, v, p); - case 2: - return (p, v, t); - case 3: - return (p, q, v); - case 4: - return (t, p, v); - default: - return (v, p, q); - } + 0 => (v, t, p), + 1 => (q, v, p), + 2 => (p, v, t), + 3 => (p, q, v), + 4 => (t, p, v), + _ => (v, p, q) + }; } #endregion diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs index b196076..edb3e1f 100644 --- a/RGB.NET.Core/Color/RGBColor.cs +++ b/RGB.NET.Core/Color/RGBColor.cs @@ -66,7 +66,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b); + => new(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b); /// /// Adds the given RGB-percent values to this color. @@ -76,7 +76,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, color.R + r, color.G + g, color.B + b); + => new(color.A, color.R + r, color.G + g, color.B + b); /// /// Adds the given alpha value to this color. @@ -84,7 +84,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) - => new Color(color.GetA() + a, color.R, color.G, color.B); + => new(color.GetA() + a, color.R, color.G, color.B); /// /// Adds the given alpha-percent value to this color. @@ -92,7 +92,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) - => new Color(color.A + a, color.R, color.G, color.B); + => new(color.A + a, color.R, color.G, color.B); #endregion @@ -106,7 +106,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b); + => new(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b); /// /// Subtracts the given RGB values to this color. @@ -116,7 +116,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, color.R - r, color.G - g, color.B - b); + => new(color.A, color.R - r, color.G - g, color.B - b); /// /// Subtracts the given alpha value to this color. @@ -124,7 +124,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) - => new Color(color.GetA() - a, color.R, color.G, color.B); + => new(color.GetA() - a, color.R, color.G, color.B); /// /// Subtracts the given alpha-percent value to this color. @@ -132,7 +132,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) - => new Color(color.A - aPercent, color.R, color.G, color.B); + => new(color.A - aPercent, color.R, color.G, color.B); #endregion @@ -146,7 +146,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, color.R * r, color.G * g, color.B * b); + => new(color.A, color.R * r, color.G * g, color.B * b); /// /// Multiplies the given alpha value to this color. @@ -154,7 +154,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) - => new Color(color.A * a, color.R, color.G, color.B); + => new(color.A * a, color.R, color.G, color.B); #endregion @@ -168,7 +168,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, color.R / r, color.G / g, color.B / b); + => new(color.A, color.R / r, color.G / g, color.B / b); /// /// Divides the given alpha value to this color. @@ -176,7 +176,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) - => new Color(color.A / a, color.R, color.G, color.B); + => new(color.A / a, color.R, color.G, color.B); #endregion @@ -190,7 +190,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); + => new(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); /// /// Sets the given RGB value of this color. @@ -200,7 +200,7 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); + => new(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); /// /// Sets the given RGB value of this color. @@ -210,21 +210,21 @@ namespace RGB.NET.Core /// 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) - => new Color(color.A, r ?? color.R, g ?? color.G, b ?? color.B); + => new(color.A, r ?? color.R, g ?? color.G, b ?? 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, int a) => new Color(a, color.R, color.G, color.B); + public static Color SetA(this 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 Color(a, color.R, color.G, color.B); + public static Color SetA(this Color color, double a) => new(a, color.R, color.G, color.B); #endregion @@ -258,16 +258,17 @@ namespace RGB.NET.Core if ((hexString == null) || (hexString.Length < 6)) throw new ArgumentException("Invalid hex string", nameof(hexString)); - if (hexString[0] == '#') - hexString = hexString.Substring(1); + ReadOnlySpan span = hexString.AsSpan(); + if (span[0] == '#') + span = span[1..]; - byte[] data = ConversionHelper.HexToBytes(hexString); - if (data.Length == 3) - return new Color(data[0], data[1], data[2]); - if (data.Length == 4) - return new Color(data[0], data[1], data[2], data[3]); - - throw new ArgumentException("Invalid hex string", nameof(hexString)); + byte[] data = ConversionHelper.HexToBytes(span); + return data.Length switch + { + 3 => new Color(data[0], data[1], data[2]), + 4 => new Color(data[0], data[1], data[2], data[3]), + _ => throw new ArgumentException($"Invalid hex string '{hexString}'", nameof(hexString)) + }; } #endregion diff --git a/RGB.NET.Core/Decorators/AbstractDecorateable.cs b/RGB.NET.Core/Decorators/AbstractDecorateable.cs index d12afcd..8acfc54 100644 --- a/RGB.NET.Core/Decorators/AbstractDecorateable.cs +++ b/RGB.NET.Core/Decorators/AbstractDecorateable.cs @@ -11,7 +11,7 @@ namespace RGB.NET.Core { #region Properties & Fields - private readonly List _decorators = new List(); + private readonly List _decorators = new(); /// public IReadOnlyCollection Decorators diff --git a/RGB.NET.Core/Decorators/AbstractDecorator.cs b/RGB.NET.Core/Decorators/AbstractDecorator.cs index 50e007c..e4a765f 100644 --- a/RGB.NET.Core/Decorators/AbstractDecorator.cs +++ b/RGB.NET.Core/Decorators/AbstractDecorator.cs @@ -29,7 +29,7 @@ namespace RGB.NET.Core /// /// Gets a readonly-list of all this decorator is attached to. /// - protected List DecoratedObjects { get; } = new List(); + protected List DecoratedObjects { get; } = new(); #endregion @@ -46,7 +46,7 @@ namespace RGB.NET.Core /// protected virtual void Detach() { - List decoratables = new List(DecoratedObjects); + List decoratables = new(DecoratedObjects); foreach (IDecoratable decoratable in decoratables) { IEnumerable types = decoratable.GetType().GetInterfaces().Where(t => t.IsGenericType diff --git a/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs b/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs index 98e64b2..7217d25 100644 --- a/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs +++ b/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs @@ -8,6 +8,8 @@ { #region Properties & Fields + protected RGBSurface Surface { get; } + /// /// Gets or sets if the should call even if the Decorator is disabled. /// @@ -21,8 +23,9 @@ /// Initializes a new instance of the class. /// /// Bool indicating if the should call even if the Decorator is disabled. - protected AbstractUpdateAwareDecorator(bool updateIfDisabled = false) + protected AbstractUpdateAwareDecorator(RGBSurface surface, bool updateIfDisabled = false) { + this.Surface = surface; this.UpdateIfDisabled = updateIfDisabled; } @@ -34,7 +37,7 @@ public override void OnAttached(IDecoratable decoratable) { if (DecoratedObjects.Count == 0) - RGBSurface.Instance.Updating += OnSurfaceUpdating; + Surface.Updating += OnSurfaceUpdating; base.OnAttached(decoratable); } @@ -45,7 +48,7 @@ base.OnDetached(decoratable); if (DecoratedObjects.Count == 0) - RGBSurface.Instance.Updating -= OnSurfaceUpdating; + Surface.Updating -= OnSurfaceUpdating; } private void OnSurfaceUpdating(UpdatingEventArgs args) diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs index 8ea688a..e7c6d08 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs @@ -2,12 +2,9 @@ // ReSharper disable UnusedMember.Global // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -using System; using System.Collections; using System.Collections.Generic; -using System.IO; using System.Linq; -using RGB.NET.Core.Layout; namespace RGB.NET.Core { @@ -21,13 +18,15 @@ namespace RGB.NET.Core { #region Properties & Fields + RGBSurface? IRGBDevice.Surface { get; set; } + /// public abstract TDeviceInfo DeviceInfo { get; } /// IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo; - private Point _location = new Point(0, 0); + private Point _location = new(0, 0); /// public Point Location { @@ -44,7 +43,7 @@ namespace RGB.NET.Core public Size Size { get => _size; - protected set + set { if (SetProperty(ref _size, value)) UpdateActualData(); @@ -67,7 +66,7 @@ namespace RGB.NET.Core private set => SetProperty(ref _deviceRectangle, value); } - private Scale _scale = new Scale(1); + private Scale _scale = new(1); /// public Scale Scale { @@ -79,7 +78,7 @@ namespace RGB.NET.Core } } - private Rotation _rotation = new Rotation(0); + private Rotation _rotation = new(0); /// public Rotation Rotation { @@ -96,26 +95,18 @@ namespace RGB.NET.Core /// protected bool RequiresFlush { get; set; } = false; - /// - public DeviceUpdateMode UpdateMode { get; set; } = DeviceUpdateMode.Sync; - /// /// Gets a dictionary containing all of the . /// - protected Dictionary LedMapping { get; } = new Dictionary(); - - /// - /// Gets a dictionary containing all associated with this . - /// - protected Dictionary SpecialDeviceParts { get; } = new Dictionary(); + protected Dictionary LedMapping { get; } = new(); #region Indexer /// - Led IRGBDevice.this[LedId ledId] => LedMapping.TryGetValue(ledId, out Led led) ? led : null; + Led? IRGBDevice.this[LedId ledId] => LedMapping.TryGetValue(ledId, out Led? led) ? led : null; /// - Led IRGBDevice.this[Point location] => LedMapping.Values.FirstOrDefault(x => x.LedRectangle.Contains(location)); + Led? IRGBDevice.this[Point location] => LedMapping.Values.FirstOrDefault(x => x.LedRectangle.Contains(location)); /// IEnumerable IRGBDevice.this[Rectangle referenceRect, double minOverlayPercentage] @@ -140,22 +131,20 @@ namespace RGB.NET.Core DeviceUpdate(); // Send LEDs to SDK - List ledsToUpdate = GetLedsToUpdate(flushLeds)?.ToList() ?? new List(); + List ledsToUpdate = GetLedsToUpdate(flushLeds).ToList(); foreach (Led ledToUpdate in ledsToUpdate) ledToUpdate.Update(); - if (UpdateMode.HasFlag(DeviceUpdateMode.Sync)) - UpdateLeds(ledsToUpdate); + UpdateLeds(ledsToUpdate); } protected virtual IEnumerable GetLedsToUpdate(bool flushLeds) => ((RequiresFlush || flushLeds) ? LedMapping.Values : LedMapping.Values.Where(x => x.IsDirty)); - + /// public virtual void Dispose() { try { - SpecialDeviceParts.Clear(); LedMapping.Clear(); } catch { /* this really shouldn't happen */ } @@ -172,15 +161,6 @@ namespace RGB.NET.Core /// protected abstract void UpdateLeds(IEnumerable ledsToUpdate); - /// - /// Initializes the with the specified id. - /// - /// The to initialize. - /// The representing the position of the to initialize. - /// - [Obsolete("Use InitializeLed(LedId ledId, Point location, Size size) instead.")] - protected virtual Led InitializeLed(LedId ledId, Rectangle rectangle) => InitializeLed(ledId, rectangle.Location, rectangle.Size); - /// /// Initializes the with the specified id. /// @@ -188,75 +168,25 @@ namespace RGB.NET.Core /// The location of the to initialize. /// The size of the to initialize. /// The initialized led. - protected virtual Led InitializeLed(LedId ledId, Point location, Size size) + public virtual Led? AddLed(LedId ledId, Point location, Size size, object? customData = null) { if ((ledId == LedId.Invalid) || LedMapping.ContainsKey(ledId)) return null; - Led led = new Led(this, ledId, location, size, CreateLedCustomData(ledId)); + Led led = new(this, ledId, location, size, customData ?? GetLedCustomData(ledId)); LedMapping.Add(ledId, led); return led; } - - /// - /// Applies the given layout. - /// - /// The file containing the layout. - /// The name of the layout used to get the images of the leds. - /// If set to true a new led is initialized for every id in the layout if it doesn't already exist. - protected virtual DeviceLayout ApplyLayoutFromFile(string layoutPath, string imageLayout, bool createMissingLeds = false) + + public virtual Led? RemoveLed(LedId ledId) { - DeviceLayout layout = DeviceLayout.Load(layoutPath); - if (layout != null) - { - string imageBasePath = string.IsNullOrWhiteSpace(layout.ImageBasePath) ? null : PathHelper.GetAbsolutePath(this, layout.ImageBasePath); - if ((imageBasePath != null) && !string.IsNullOrWhiteSpace(layout.DeviceImage) && (DeviceInfo != null)) - DeviceInfo.Image = new Uri(Path.Combine(imageBasePath, layout.DeviceImage), UriKind.Absolute); + if (ledId == LedId.Invalid) return null; + if (!LedMapping.TryGetValue(ledId, out Led? led)) return null; - LedImageLayout ledImageLayout = layout.LedImageLayouts.FirstOrDefault(x => string.Equals(x.Layout, imageLayout, StringComparison.OrdinalIgnoreCase)); - - Size = new Size(layout.Width, layout.Height); - - if (layout.Leds != null) - foreach (LedLayout layoutLed in layout.Leds) - { - if (Enum.TryParse(layoutLed.Id, true, out LedId ledId)) - { - if (!LedMapping.TryGetValue(ledId, out Led led) && createMissingLeds) - led = InitializeLed(ledId, new Point(), new Size()); - - if (led != null) - { - led.Location = new Point(layoutLed.X, layoutLed.Y); - led.Size = new Size(layoutLed.Width, layoutLed.Height); - led.Shape = layoutLed.Shape; - led.ShapeData = layoutLed.ShapeData; - - LedImage image = ledImageLayout?.LedImages.FirstOrDefault(x => x.Id == layoutLed.Id); - if ((imageBasePath != null) && !string.IsNullOrEmpty(image?.Image)) - led.Image = new Uri(Path.Combine(imageBasePath, image.Image), UriKind.Absolute); - } - } - } - } - - return layout; + LedMapping.Remove(ledId); + return led; } - /// - /// Creates provider-specific data associated with this . - /// - /// The . - protected virtual object CreateLedCustomData(LedId ledId) => null; - - /// - public void AddSpecialDevicePart(T specialDevicePart) - where T : class, IRGBDeviceSpecialPart - => SpecialDeviceParts[typeof(T)] = specialDevicePart; - - /// - public T GetSpecialDevicePart() - where T : class, IRGBDeviceSpecialPart - => SpecialDeviceParts.TryGetValue(typeof(T), out IRGBDeviceSpecialPart devicePart) ? (T)devicePart : default; + protected virtual object? GetLedCustomData(LedId ledId) => null; #region Enumerator diff --git a/RGB.NET.Core/Devices/DeviceUpdateMode.cs b/RGB.NET.Core/Devices/DeviceUpdateMode.cs deleted file mode 100644 index 1a60c67..0000000 --- a/RGB.NET.Core/Devices/DeviceUpdateMode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -namespace RGB.NET.Core -{ - /// - /// Contains a list of different device device update modes. - /// - [Flags] - public enum DeviceUpdateMode - { - /// - /// Represents nothing. - /// - None = 0, - - /// - /// Represents a mode which updates the leds of the device. - /// - Sync = 1 << 0, - - /// - /// Represents all update modes. - /// - NoUpdate = 1 << 0xFF - } -} diff --git a/RGB.NET.Core/Devices/IRGBDevice.cs b/RGB.NET.Core/Devices/IRGBDevice.cs index f79b2b7..7103773 100644 --- a/RGB.NET.Core/Devices/IRGBDevice.cs +++ b/RGB.NET.Core/Devices/IRGBDevice.cs @@ -13,6 +13,8 @@ namespace RGB.NET.Core { #region Properties + RGBSurface? Surface { get; internal set; } + /// /// Gets generic information about the . /// @@ -26,7 +28,7 @@ namespace RGB.NET.Core /// /// Gets the of the . /// - Size Size { get; } + Size Size { get; set; } /// /// Gets the actual of the . @@ -49,11 +51,6 @@ namespace RGB.NET.Core /// Rotation Rotation { get; set; } - /// - /// Gets or sets the of the . - /// - DeviceUpdateMode UpdateMode { get; set; } - #endregion #region Indexer @@ -63,14 +60,14 @@ namespace RGB.NET.Core /// /// The of the to get. /// The with the specified or null if no is found. - Led this[LedId ledId] { get; } + Led? this[LedId ledId] { get; } /// /// Gets the at the given physical location. /// /// The to get the location from. /// The at the given or null if no location is found. - Led this[Point location] { get; } + Led? this[Point location] { get; } /// /// Gets a list of inside the given . @@ -89,21 +86,10 @@ namespace RGB.NET.Core /// /// Specifies whether all (including clean ones) should be updated. void Update(bool flushLeds = false); - - /// - /// Adds the given to the device. - /// This will override existing of the same type. - /// - /// The to add. - /// The generic typeof of the to add. - void AddSpecialDevicePart(T specialDevicePart) where T : class, IRGBDeviceSpecialPart; - /// - /// Gets the requested if available on this . - /// - /// The generic type of the requested . - /// The requested or null if not available in this . - T GetSpecialDevicePart() where T : class, IRGBDeviceSpecialPart; + Led? AddLed(LedId ledId, Point location, Size size, object? customData = null); + + Led? RemoveLed(LedId ledId); #endregion } diff --git a/RGB.NET.Core/Devices/IRGBDeviceInfo.cs b/RGB.NET.Core/Devices/IRGBDeviceInfo.cs index f0c9ef3..3bb29c2 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceInfo.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceInfo.cs @@ -1,6 +1,4 @@ -using System; - -namespace RGB.NET.Core +namespace RGB.NET.Core { /// /// Represents a generic information for a @@ -29,15 +27,7 @@ namespace RGB.NET.Core /// string Model { get; } - /// - /// Gets the lighting capability of the - /// - RGBDeviceLighting Lighting { get; } - - /// - /// Gets the URI of an image of the or null if there is no image. - /// - Uri Image { get; set; } + object? LayoutMetadata { get; set; } #endregion } diff --git a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs index dca3645..6060feb 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs @@ -20,28 +20,11 @@ namespace RGB.NET.Core /// IEnumerable Devices { get; } - /// - /// Gets whether the application has exclusive access to devices or not. - /// - bool HasExclusiveAccess { get; } - #endregion #region Methods - /// - /// Initializes the if not already happened or reloads it if it is already initialized. - /// - /// Specifies which types of devices to load. - /// Specifies whether the application should request exclusive access of possible or not. - /// Specifies whether exception during the initialization sequence should be thrown or not. - /// - bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false); - - /// - /// Resets all handled back top default. - /// - void ResetDevices(); + bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false); #endregion } diff --git a/RGB.NET.Core/Devices/IRGBDeviceProviderLoader.cs b/RGB.NET.Core/Devices/IRGBDeviceProviderLoader.cs deleted file mode 100644 index 14a60cb..0000000 --- a/RGB.NET.Core/Devices/IRGBDeviceProviderLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a generic device provider loaded used to dynamically load devices into an application. - /// This class should always provide an empty public constructor! - /// - public interface IRGBDeviceProviderLoader - { - /// - /// Indicates if the returned device-provider needs some specific initialization before use. - /// - bool RequiresInitialization { get; } - - /// - /// Gets the device-provider. - /// - /// The device-provider. - IRGBDeviceProvider GetDeviceProvider(); - } -} diff --git a/RGB.NET.Core/Devices/IRGBDeviceSpecialPart.cs b/RGB.NET.Core/Devices/IRGBDeviceSpecialPart.cs deleted file mode 100644 index 58c4e37..0000000 --- a/RGB.NET.Core/Devices/IRGBDeviceSpecialPart.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace RGB.NET.Core -{ - /// - /// - /// Represents a special part of a . - /// - public interface IRGBDeviceSpecialPart : IEnumerable - { } -} diff --git a/RGB.NET.Core/Devices/Layout/LedImage.cs b/RGB.NET.Core/Devices/Layout/LedImage.cs deleted file mode 100644 index c76d95a..0000000 --- a/RGB.NET.Core/Devices/Layout/LedImage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Xml.Serialization; - -namespace RGB.NET.Core.Layout -{ - /// - /// Represents the serializable image-data of a specific . - /// - [Serializable] - [XmlRoot("LedImage")] - public class LedImage - { - /// - /// Gets or sets the Id of the . - /// - [XmlAttribute("Id")] - public string Id { get; set; } - - /// - /// Gets or sets the image of the . - /// - [XmlAttribute("Image")] - public string Image { get; set; } - } -} diff --git a/RGB.NET.Core/Devices/Layout/LedImageLayout.cs b/RGB.NET.Core/Devices/Layout/LedImageLayout.cs deleted file mode 100644 index 2c3a491..0000000 --- a/RGB.NET.Core/Devices/Layout/LedImageLayout.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Xml.Serialization; - -namespace RGB.NET.Core.Layout -{ - /// - /// Represents the serializable collection of for a specific layout. - /// - [Serializable] - [XmlRoot("LedImageLayout")] - public class LedImageLayout - { - /// - /// Gets or sets the layout of the . - /// - [XmlAttribute("Layout")] - [DefaultValue(null)] - public string Layout { get; set; } - - /// - /// Gets or sets a list of representing the images of all the of the represented layout. - /// - [XmlArray("LedImages")] - public List LedImages { get; set; } = new List(); - } -} diff --git a/RGB.NET.Core/Devices/RGBDeviceLighting.cs b/RGB.NET.Core/Devices/RGBDeviceLighting.cs deleted file mode 100644 index 70a0607..0000000 --- a/RGB.NET.Core/Devices/RGBDeviceLighting.cs +++ /dev/null @@ -1,25 +0,0 @@ -using RGB.NET.Core.Layout; - -namespace RGB.NET.Core -{ - /// - /// Contains a list of different lightning-modes used by . - /// - public enum RGBDeviceLighting - { - /// - /// The doesn't support lighting, - /// - None = 0, - - /// - /// The supports per-key-lightning. - /// - Key = 1, - - /// - /// The supports per-device-lightning. - /// - Device = 2, - } -} diff --git a/RGB.NET.Core/Events/ResolvePathEventArgs.cs b/RGB.NET.Core/Events/ResolvePathEventArgs.cs index 2b73a2e..7257bf2 100644 --- a/RGB.NET.Core/Events/ResolvePathEventArgs.cs +++ b/RGB.NET.Core/Events/ResolvePathEventArgs.cs @@ -8,23 +8,21 @@ namespace RGB.NET.Core /// /// Gets the filename used to resolve the path. - /// This has to be checked for null since it'S possible that only is used. /// Also check before use. /// - public string RelativePart { get; } + public string? RelativePart { get; } /// /// Gets the filename used to resolve the path. - /// This has to be checked for null since it'S possible that only is used. /// Also check before use. /// - public string FileName { get; } + public string? FileName { get; } /// /// Gets the relative path used to resolve the path. /// If this is set and are unused. /// - public string RelativePath { get; } + public string? RelativePath { get; } /// /// Gets or sets the resolved path. diff --git a/RGB.NET.Core/Events/UpdatingEventArgs.cs b/RGB.NET.Core/Events/UpdatingEventArgs.cs index 46e1f73..193db2a 100644 --- a/RGB.NET.Core/Events/UpdatingEventArgs.cs +++ b/RGB.NET.Core/Events/UpdatingEventArgs.cs @@ -21,8 +21,8 @@ namespace RGB.NET.Core /// /// Gets the trigger causing this update. /// - public IUpdateTrigger Trigger { get; } - + public IUpdateTrigger? Trigger { get; } + /// /// Gets the custom-data provided by the trigger for this update. /// @@ -39,7 +39,7 @@ namespace RGB.NET.Core /// The elapsed time (in seconds) since the last update. /// The trigger causing this update. /// The custom-data provided by the trigger for this update. - public UpdatingEventArgs(double deltaTime, IUpdateTrigger trigger, CustomUpdateData customData) + public UpdatingEventArgs(double deltaTime, IUpdateTrigger? trigger, CustomUpdateData customData) { this.DeltaTime = deltaTime; this.Trigger = trigger; diff --git a/RGB.NET.Core/Exceptions/RGBDeviceException.cs b/RGB.NET.Core/Exceptions/RGBDeviceException.cs index 735b0c4..d64275d 100644 --- a/RGB.NET.Core/Exceptions/RGBDeviceException.cs +++ b/RGB.NET.Core/Exceptions/RGBDeviceException.cs @@ -16,7 +16,7 @@ namespace RGB.NET.Core /// /// The message which describes the reason of throwing this exception. /// Optional inner exception, which lead to this exception. - public RGBDeviceException(string message, Exception innerException = null) + public RGBDeviceException(string message, Exception? innerException = null) : base(message, innerException) { } diff --git a/RGB.NET.Core/Exceptions/RGBSurfaceException.cs b/RGB.NET.Core/Exceptions/RGBSurfaceException.cs new file mode 100644 index 0000000..c00aa65 --- /dev/null +++ b/RGB.NET.Core/Exceptions/RGBSurfaceException.cs @@ -0,0 +1,25 @@ +using System; + +namespace RGB.NET.Core +{ + /// + /// + /// Represents an exception thrown by an . + /// + public class RGBSurfaceException : ApplicationException + { + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The message which describes the reason of throwing this exception. + /// Optional inner exception, which lead to this exception. + public RGBSurfaceException(string message, Exception? innerException = null) + : base(message, innerException) + { } + + #endregion + } +} diff --git a/RGB.NET.Core/Extensions/PointExtensions.cs b/RGB.NET.Core/Extensions/PointExtensions.cs index 7c413e9..9766bf3 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(point.X + x, point.Y + y); + public static Point Translate(this Point point, double x = 0, double y = 0) => new(point.X + x, point.Y + y); /// /// Rotates the specified by the given amuont around the given origin. @@ -22,7 +22,7 @@ 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 Point()) + public static Point Rotate(this Point point, Rotation rotation, Point origin = new()) { double sin = Math.Sin(rotation.Radians); double cos = Math.Cos(rotation.Radians); diff --git a/RGB.NET.Core/Extensions/RectangleExtensions.cs b/RGB.NET.Core/Extensions/RectangleExtensions.cs index aae9b04..de09fc0 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 Rectangle(location, rect.Size); + public static Rectangle SetLocation(this Rectangle rect, 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 Rectangle(new Point(x, rect.Location.Y), rect.Size); + public static Rectangle SetX(this Rectangle rect, double 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 Rectangle(new Point(rect.Location.X, y), rect.Size); + public static Rectangle SetY(this Rectangle rect, double 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 Rectangle(rect.Location, size); + public static Rectangle SetSize(this Rectangle rect, 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 Rectangle(rect.Location, new Size(width, rect.Size.Height)); + public static Rectangle SetWidth(this Rectangle rect, double width) => new(rect.Location, new Size(width, rect.Size.Height)); /// /// Sets the of the of the given rectangle. @@ -52,7 +52,7 @@ 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 Rectangle(rect.Location, new Size(rect.Size.Width, height)); + public static Rectangle SetHeight(this Rectangle rect, double height) => new(rect.Location, new Size(rect.Size.Width, height)); /// /// Calculates the percentage of intersection of a rectangle. @@ -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 Rectangle(rect.Location.Translate(x, y), rect.Size); + public static Rectangle Translate(this Rectangle rect, double x = 0, double y = 0) => new(rect.Location.Translate(x, y), rect.Size); /// /// Rotates the specified by the given amuont around the given origin. @@ -141,13 +141,13 @@ 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 Point()) + public static Point[] Rotate(this Rectangle rect, Rotation rotation, Point origin = new()) { Point[] points = { rect.Location, // top left - new Point(rect.Location.X + rect.Size.Width, rect.Location.Y), // top right - new Point(rect.Location.X + rect.Size.Width, rect.Location.Y + rect.Size.Height), // bottom right - new Point(rect.Location.X, rect.Location.Y + rect.Size.Height), // bottom right + new(rect.Location.X + rect.Size.Width, rect.Location.Y), // top right + new(rect.Location.X + rect.Size.Width, rect.Location.Y + rect.Size.Height), // bottom right + new(rect.Location.X, rect.Location.Y + rect.Size.Height), // bottom right }; double sin = Math.Sin(rotation.Radians); diff --git a/RGB.NET.Core/Groups/AbstractLedGroup.cs b/RGB.NET.Core/Groups/AbstractLedGroup.cs index eab6803..3720302 100644 --- a/RGB.NET.Core/Groups/AbstractLedGroup.cs +++ b/RGB.NET.Core/Groups/AbstractLedGroup.cs @@ -11,8 +11,10 @@ namespace RGB.NET.Core { #region Properties & Fields + public RGBSurface? Surface { get; private set; } + /// - public IBrush Brush { get; set; } + public IBrush? Brush { get; set; } /// public int ZIndex { get; set; } = 0; @@ -24,11 +26,9 @@ namespace RGB.NET.Core /// /// Initializes a new instance of the class. /// - /// Specifies whether this should be automatically attached or not. - protected AbstractLedGroup(bool autoAttach) + protected AbstractLedGroup(RGBSurface? attachTo) { - if (autoAttach) - RGBSurface.Instance.AttachLedGroup(this); + attachTo?.AttachLedGroup(this); } #endregion @@ -39,12 +39,10 @@ namespace RGB.NET.Core public abstract IList GetLeds(); /// - public virtual void OnAttach() - { } + public virtual void OnAttach(RGBSurface surface) => Surface = surface; /// - public virtual void OnDetach() - { } + public virtual void OnDetach(RGBSurface surface) => Surface = null; #endregion } diff --git a/RGB.NET.Core/Groups/ILedGroup.cs b/RGB.NET.Core/Groups/ILedGroup.cs index 5db5e63..3985f8a 100644 --- a/RGB.NET.Core/Groups/ILedGroup.cs +++ b/RGB.NET.Core/Groups/ILedGroup.cs @@ -11,10 +11,12 @@ namespace RGB.NET.Core /// public interface ILedGroup : IDecoratable { + public RGBSurface? Surface { get; } + /// /// Gets or sets the which should be drawn over this . /// - IBrush Brush { get; set; } + IBrush? Brush { get; set; } /// /// Gets or sets the z-index of this to allow ordering them before drawing. (lowest first) (default: 0) @@ -30,11 +32,11 @@ namespace RGB.NET.Core /// /// Called when the is attached to the . /// - void OnAttach(); + void OnAttach(RGBSurface surface); /// /// Called when the is detached from the . /// - void OnDetach(); + void OnDetach(RGBSurface surface); } } diff --git a/RGB.NET.Core/Helper/ConversionHelper.cs b/RGB.NET.Core/Helper/ConversionHelper.cs index cf96a36..f1dfe70 100644 --- a/RGB.NET.Core/Helper/ConversionHelper.cs +++ b/RGB.NET.Core/Helper/ConversionHelper.cs @@ -1,4 +1,6 @@ -namespace RGB.NET.Core +using System; + +namespace RGB.NET.Core { /// /// Contains helper methods for converting things. @@ -20,10 +22,10 @@ for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx) { byte b = ((byte)(bytes[bx] >> 4)); - c[cx] = (char)(b > 9 ? b + 0x37: b + 0x30); + c[cx] = (char)(b > 9 ? b + 0x37 : b + 0x30); b = ((byte)(bytes[bx] & 0x0F)); - c[++cx] = (char)(b > 9 ? b + 0x37: b + 0x30); + c[++cx] = (char)(b > 9 ? b + 0x37 : b + 0x30); } return new string(c); @@ -35,10 +37,10 @@ /// /// The HEX-string to convert. /// The correspondending byte array. - public static byte[] HexToBytes(string hexString) + public static byte[] HexToBytes(ReadOnlySpan hexString) { if ((hexString.Length == 0) || ((hexString.Length % 2) != 0)) - return new byte[0]; + return Array.Empty(); byte[] buffer = new byte[hexString.Length / 2]; for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx) diff --git a/RGB.NET.Core/Helper/CultureHelper.cs b/RGB.NET.Core/Helper/CultureHelper.cs deleted file mode 100644 index 3ea900a..0000000 --- a/RGB.NET.Core/Helper/CultureHelper.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Globalization; -using System.Runtime.InteropServices; - -namespace RGB.NET.Core -{ - /// - /// Offers some helper-methods for culture related things. - /// - public static class CultureHelper - { - #region DLLImports - - [DllImport("user32.dll")] - private static extern IntPtr GetKeyboardLayout(uint thread); - - #endregion - - #region Constructors - - #endregion - - #region Methods - - /// - /// Gets the current keyboard-layout from the OS. - /// - /// The current keyboard-layout - public static CultureInfo GetCurrentCulture() - { - try - { - int keyboardLayout = GetKeyboardLayout(0).ToInt32() & 0xFFFF; - return new CultureInfo(keyboardLayout); - } - catch - { - return new CultureInfo(1033); // en-US on error. - } - } - - #endregion - } -} diff --git a/RGB.NET.Core/Helper/PathHelper.cs b/RGB.NET.Core/Helper/PathHelper.cs deleted file mode 100644 index d67e5b7..0000000 --- a/RGB.NET.Core/Helper/PathHelper.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.IO; -using System.Reflection; - -namespace RGB.NET.Core -{ - /// - /// Offers some helper-methods for file-path related things. - /// - public static class PathHelper - { - #region Events - - /// - /// Occurs when a path is resolving. - /// - public static event EventHandler ResolvingAbsolutePath; - - #endregion - - #region Methods - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The relative part of the path to convert. - /// The absolute path. - public static string GetAbsolutePath(string relativePath) => GetAbsolutePath((object)null, relativePath); - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The relative part of the path to convert. - /// The file name of the path to convert. - /// The absolute path. - public static string GetAbsolutePath(string relativePath, string fileName) => GetAbsolutePath(null, relativePath, fileName); - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The requester of this path. (Used for better control when using the event to override this behavior.) - /// The relative path to convert. - /// The file name of the path to convert. - /// The absolute path. - public static string GetAbsolutePath(object sender, string relativePath, string fileName) - { - string relativePart = Path.Combine(relativePath, fileName); - - string assemblyLocation = Assembly.GetEntryAssembly()?.Location; - if (assemblyLocation == null) return relativePart; - - string directoryName = Path.GetDirectoryName(assemblyLocation); - string path = directoryName == null ? null : Path.Combine(directoryName, relativePart); - - ResolvePathEventArgs args = new ResolvePathEventArgs(relativePath, fileName, path); - ResolvingAbsolutePath?.Invoke(sender, args); - - return args.FinalPath; - } - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The requester of this path. (Used for better control when using the event to override this behavior.) - /// The relative path to convert. - /// The absolute path. - public static string GetAbsolutePath(object sender, string relativePath) - { - string assemblyLocation = Assembly.GetEntryAssembly()?.Location; - if (assemblyLocation == null) return relativePath; - - string directoryName = Path.GetDirectoryName(assemblyLocation); - string path = directoryName == null ? null : Path.Combine(directoryName, relativePath); - - ResolvePathEventArgs args = new ResolvePathEventArgs(relativePath, path); - ResolvingAbsolutePath?.Invoke(sender, args); - - return args.FinalPath; - } - - #endregion - } -} diff --git a/RGB.NET.Core/Leds/Led.cs b/RGB.NET.Core/Leds/Led.cs index 67cea33..9766043 100644 --- a/RGB.NET.Core/Leds/Led.cs +++ b/RGB.NET.Core/Leds/Led.cs @@ -35,11 +35,11 @@ namespace RGB.NET.Core set => SetProperty(ref _shape, value); } - private string _shapeData; + private string? _shapeData; /// /// Gets or sets the data used for by the -. /// - public string ShapeData + public string? ShapeData { get => _shapeData; set => SetProperty(ref _shapeData, value); @@ -124,7 +124,7 @@ namespace RGB.NET.Core /// /// Indicates whether the is about to change it's color. /// - public bool IsDirty => RequestedColor.HasValue && (RequestedColor != InternalColor); + public bool IsDirty => RequestedColor.HasValue && (RequestedColor != Color); private Color? _requestedColor; /// @@ -152,45 +152,24 @@ namespace RGB.NET.Core get => _color; set { - if (!IsLocked) - { - if (RequestedColor.HasValue) - RequestedColor += value; - else - RequestedColor = value; - } - + if (RequestedColor.HasValue) + RequestedColor = RequestedColor.Value + value; + else + RequestedColor = value; } } - /// - /// Gets or set the ignoring all workflows regarding locks and update-requests. /> - /// - internal Color InternalColor - { - get => _color; - set => SetProperty(ref _color, value); - } - - private bool _isLocked; - /// - /// Gets or sets if the color of this LED can be changed. - /// - public bool IsLocked - { - get => _isLocked; - set => SetProperty(ref _isLocked, value); - } - /// /// Gets the URI of an image of the or null if there is no image. /// - public Uri Image { get; set; } + public Uri? Image { get; set; } /// /// Gets the provider-specific data associated with this led. /// - public object CustomData { get; } + public object? CustomData { get; } + + public object? LayoutMetadata { get; set; } #endregion @@ -204,7 +183,7 @@ namespace RGB.NET.Core /// The physical location of the relative to the . /// The size of the . /// The provider-specific data associated with this led. - internal Led(IRGBDevice device, LedId id, Point location, Size size, object customData = null) + internal Led(IRGBDevice device, LedId id, Point location, Size size, object? customData = null) { this.Device = device; this.Id = id; @@ -219,14 +198,18 @@ namespace RGB.NET.Core #region Methods - private void DevicePropertyChanged(object sender, PropertyChangedEventArgs e) + private void DevicePropertyChanged(object? sender, PropertyChangedEventArgs e) { - if ((e.PropertyName == nameof(IRGBDevice.Location))) - UpdateAbsoluteData(); - else if (e.PropertyName == nameof(IRGBDevice.DeviceRectangle)) + switch (e.PropertyName) { - UpdateActualData(); - UpdateAbsoluteData(); + case nameof(IRGBDevice.Location): + UpdateAbsoluteData(); + break; + + case nameof(IRGBDevice.DeviceRectangle): + UpdateActualData(); + UpdateAbsoluteData(); + break; } } @@ -235,13 +218,13 @@ namespace RGB.NET.Core ActualSize = Size * Device.Scale; Point actualLocation = (Location * Device.Scale); - Rectangle ledRectangle = new Rectangle(Location * Device.Scale, Size * Device.Scale); + Rectangle ledRectangle = new(Location * Device.Scale, Size * Device.Scale); if (Device.Rotation.IsRotated) { Point deviceCenter = new Rectangle(Device.ActualSize).Center; Point actualDeviceCenter = new Rectangle(Device.DeviceRectangle.Size).Center; - Point centerOffset = new Point(actualDeviceCenter.X - deviceCenter.X, actualDeviceCenter.Y - deviceCenter.Y); + Point centerOffset = new(actualDeviceCenter.X - deviceCenter.X, actualDeviceCenter.Y - deviceCenter.Y); actualLocation = actualLocation.Rotate(Device.Rotation, new Rectangle(Device.ActualSize).Center) + centerOffset; ledRectangle = new Rectangle(ledRectangle.Rotate(Device.Rotation, new Rectangle(Device.ActualSize).Center)).Translate(centerOffset); @@ -283,7 +266,6 @@ namespace RGB.NET.Core { _color = Color.Transparent; RequestedColor = null; - IsLocked = false; // ReSharper disable once ExplicitCallerInfoArgument OnPropertyChanged(nameof(Color)); @@ -297,13 +279,13 @@ namespace RGB.NET.Core /// Converts a to a . /// /// The to convert. - public static implicit operator Color(Led led) => led?.Color ?? Color.Transparent; + public static implicit operator Color(Led led) => led.Color; /// /// Converts a to a . /// /// The to convert. - public static implicit operator Rectangle(Led led) => led?.LedRectangle ?? new Rectangle(); + public static implicit operator Rectangle(Led led) => led.LedRectangle; #endregion } diff --git a/RGB.NET.Core/MVVM/AbstractBindable.cs b/RGB.NET.Core/MVVM/AbstractBindable.cs index ab36978..5d41f1c 100644 --- a/RGB.NET.Core/MVVM/AbstractBindable.cs +++ b/RGB.NET.Core/MVVM/AbstractBindable.cs @@ -14,7 +14,7 @@ namespace RGB.NET.Core /// /// Occurs when a property value changes. /// - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; #endregion @@ -28,10 +28,7 @@ namespace RGB.NET.Core /// Value to apply. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected virtual bool RequiresUpdate(ref T storage, T value) - { - return !Equals(storage, value); - } + protected virtual bool RequiresUpdate(ref T storage, T value) => !Equals(storage, value); /// /// Checks if the property already matches the desired value and updates it if not. @@ -42,13 +39,13 @@ namespace RGB.NET.Core /// Name of the property used to notify listeners. This value is optional /// and can be provided automatically when invoked from compilers that support . /// true if the value was changed, false if the existing value matched the desired value. - protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) + protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string? propertyName = null) { - if (!this.RequiresUpdate(ref storage, value)) return false; + if (!RequiresUpdate(ref storage, value)) return false; storage = value; // ReSharper disable once ExplicitCallerInfoArgument - this.OnPropertyChanged(propertyName); + OnPropertyChanged(propertyName); return true; } @@ -57,10 +54,8 @@ namespace RGB.NET.Core /// /// Name of the property used to notify listeners. This value is optional /// and can be provided automatically when invoked from compilers that support . - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); #endregion } diff --git a/RGB.NET.Core/Positioning/Point.cs b/RGB.NET.Core/Positioning/Point.cs index 9583863..d546994 100644 --- a/RGB.NET.Core/Positioning/Point.cs +++ b/RGB.NET.Core/Positioning/Point.cs @@ -9,14 +9,14 @@ namespace RGB.NET.Core /// Represents a point consisting of a X- and a Y-position. /// [DebuggerDisplay("[X: {X}, Y: {Y}]")] - public struct Point + public readonly struct Point { #region Constants /// /// Gets a [NaN,NaN]-Point. /// - public static Point Invalid => new Point(double.NaN, double.NaN); + public static Point Invalid => new(double.NaN, double.NaN); #endregion @@ -62,13 +62,13 @@ namespace RGB.NET.Core /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) + public override bool Equals(object? obj) { 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)); + && ((double.IsNaN(Y) && double.IsNaN(comparePoint.Y)) || Y.EqualsInTolerance(comparePoint.Y)); } /// @@ -111,7 +111,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 Point(point1.X + point2.X, point1.Y + point2.Y); + public static Point operator +(Point point1, Point point2) => new(point1.X + point2.X, point1.Y + point2.Y); /// /// Returns a new created from the provided and . @@ -119,7 +119,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 Rectangle(point, size); + public static Rectangle operator +(Point point, Size size) => new(point, size); /// /// Returns a new representing the subtraction of the two provided . @@ -127,7 +127,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 Point(point1.X - point2.X, point1.Y - point2.Y); + public static Point operator -(Point point1, Point point2) => new(point1.X - point2.X, point1.Y - point2.Y); /// /// Returns a new representing the multiplication of the two provided . @@ -135,7 +135,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 Point(point1.X * point2.X, point1.Y * point2.Y); + public static Point operator *(Point point1, Point point2) => new(point1.X * point2.X, point1.Y * point2.Y); /// /// Returns a new representing the division of the two provided . @@ -155,7 +155,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(point.X * scale.Horizontal, point.Y * scale.Vertical); + public static Point operator *(Point point, 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 d3b1618..cbf80ab 100644 --- a/RGB.NET.Core/Positioning/Rectangle.cs +++ b/RGB.NET.Core/Positioning/Rectangle.cs @@ -12,7 +12,7 @@ namespace RGB.NET.Core /// Represents a rectangle defined by it's position and it's size. /// [DebuggerDisplay("[Location: {Location}, Size: {Size}]")] - public struct Rectangle + public readonly struct Rectangle { #region Properties & Fields @@ -69,6 +69,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)); } @@ -95,15 +96,14 @@ namespace RGB.NET.Core double posX2 = double.MinValue; double posY2 = double.MinValue; - if (rectangles != null) - foreach (Rectangle rectangle in rectangles) - { - hasPoint = true; - posX = Math.Min(posX, rectangle.Location.X); - posY = Math.Min(posY, rectangle.Location.Y); - posX2 = Math.Max(posX2, rectangle.Location.X + rectangle.Size.Width); - posY2 = Math.Max(posY2, rectangle.Location.Y + rectangle.Size.Height); - } + foreach (Rectangle rectangle in rectangles) + { + hasPoint = true; + posX = Math.Min(posX, rectangle.Location.X); + posY = Math.Min(posY, rectangle.Location.Y); + posX2 = Math.Max(posX2, rectangle.Location.X + rectangle.Size.Width); + posY2 = Math.Max(posY2, rectangle.Location.Y + rectangle.Size.Height); + } (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; @@ -136,15 +136,14 @@ namespace RGB.NET.Core double posX2 = double.MinValue; double posY2 = double.MinValue; - if (points != null) - foreach (Point point in points) - { - hasPoint = true; - posX = Math.Min(posX, point.X); - posY = Math.Min(posY, point.Y); - posX2 = Math.Max(posX2, point.X); - posY2 = Math.Max(posY2, point.Y); - } + foreach (Point point in points) + { + hasPoint = true; + posX = Math.Min(posX, point.X); + posY = Math.Min(posY, point.Y); + posX2 = Math.Max(posX2, point.X); + posY2 = Math.Max(posY2, point.Y); + } (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0)); @@ -178,7 +177,7 @@ namespace RGB.NET.Core /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (!(obj is Rectangle compareRect)) return false; diff --git a/RGB.NET.Core/Positioning/Rotation.cs b/RGB.NET.Core/Positioning/Rotation.cs index 0f638ec..623f64a 100644 --- a/RGB.NET.Core/Positioning/Rotation.cs +++ b/RGB.NET.Core/Positioning/Rotation.cs @@ -9,8 +9,8 @@ namespace RGB.NET.Core /// /// Represents an angular rotation. /// - [DebuggerDisplay("[{Degrees}°]")] - public struct Rotation + [DebuggerDisplay("[{" + nameof(Degrees) + "}°]")] + public readonly struct Rotation { #region Constants @@ -64,14 +64,14 @@ namespace RGB.NET.Core /// /// The angle in degrees. /// The new rotation. - public static Rotation FromDegrees(double degrees) => new Rotation(degrees); + public static Rotation FromDegrees(double 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 Rotation(radians * RADIANS_DEGREES_CONVERSION, radians); + public static Rotation FromRadians(double radians) => new(radians * RADIANS_DEGREES_CONVERSION, radians); /// /// Tests whether the specified is equivalent to this . @@ -85,7 +85,7 @@ namespace RGB.NET.Core /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) => obj is Rotation other && Equals(other); + public override bool Equals(object? obj) => obj is Rotation other && Equals(other); /// /// Returns a hash code for this . @@ -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(rotation.Degrees + value); + public static Rotation operator +(Rotation rotation, double 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(rotation.Degrees - value); + public static Rotation operator -(Rotation rotation, double 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(rotation.Degrees * value); + public static Rotation operator *(Rotation rotation, double value) => new(rotation.Degrees * value); /// /// Returns a new representing the division of the and the provided value. @@ -149,7 +149,7 @@ namespace RGB.NET.Core /// Converts a double to a . /// /// The rotation in degrees to convert. - public static implicit operator Rotation(double rotation) => new Rotation(rotation); + public static implicit operator Rotation(double rotation) => new(rotation); /// /// Converts to a double representing the rotation in degrees. diff --git a/RGB.NET.Core/Positioning/Scale.cs b/RGB.NET.Core/Positioning/Scale.cs index 04b8f09..b12af17 100644 --- a/RGB.NET.Core/Positioning/Scale.cs +++ b/RGB.NET.Core/Positioning/Scale.cs @@ -9,7 +9,7 @@ namespace RGB.NET.Core /// Represents a scaling. /// [DebuggerDisplay("[Horizontal: {Horizontal}, Vertical: {Vertical}]")] - public struct Scale + public readonly struct Scale { #region Properties & Fields @@ -61,7 +61,7 @@ namespace RGB.NET.Core /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) => obj is Scale other && Equals(other); + public override bool Equals(object? obj) => obj is Scale other && Equals(other); /// /// Returns a hash code for this . @@ -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(scale.Horizontal + value, scale.Vertical + value); + public static Scale operator +(Scale scale, double 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(scale.Horizontal - value, scale.Vertical - value); + public static Scale operator -(Scale scale, double 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(scale.Horizontal * value, scale.Vertical * value); + public static Scale operator *(Scale scale, double value) => new(scale.Horizontal * value, scale.Vertical * value); /// /// Returns a new representing the division of the and the provided value. @@ -137,7 +137,7 @@ namespace RGB.NET.Core /// Converts a double to a . /// /// The scale value to convert. - public static implicit operator Scale(double scale) => new Scale(scale); + public static implicit operator Scale(double scale) => new(scale); #endregion } diff --git a/RGB.NET.Core/Positioning/Shape.cs b/RGB.NET.Core/Positioning/Shape.cs index f4cdfe0..1965533 100644 --- a/RGB.NET.Core/Positioning/Shape.cs +++ b/RGB.NET.Core/Positioning/Shape.cs @@ -1,10 +1,9 @@ using System; -using RGB.NET.Core.Layout; namespace RGB.NET.Core { /// - /// Contains a list of different shapes used by . + /// Contains a list of different shapes used to define the layout of a LED. /// [Serializable] public enum Shape diff --git a/RGB.NET.Core/Positioning/Size.cs b/RGB.NET.Core/Positioning/Size.cs index 74f9153..7ed7887 100644 --- a/RGB.NET.Core/Positioning/Size.cs +++ b/RGB.NET.Core/Positioning/Size.cs @@ -9,14 +9,14 @@ namespace RGB.NET.Core /// Represents a size consisting of a width and a height. /// [DebuggerDisplay("[Width: {Width}, Height: {Height}]")] - public struct Size + public readonly struct Size { #region Constants /// /// Gets a [NaN,NaN]-Size. /// - public static Size Invalid => new Size(double.NaN, double.NaN); + public static Size Invalid => new(double.NaN, double.NaN); #endregion @@ -71,13 +71,13 @@ namespace RGB.NET.Core /// /// The object to test. /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) + public override bool Equals(object? obj) { - if (!(obj is Size)) return false; + if (!(obj is Size size)) return false; - Size compareSize = (Size)obj; - return ((double.IsNaN(Width) && double.IsNaN(compareSize.Width)) || Width.EqualsInTolerance(compareSize.Width)) - && ((double.IsNaN(Height) && double.IsNaN(compareSize.Height)) || Height.EqualsInTolerance(compareSize.Height)); + (double width, double height) = size; + return ((double.IsNaN(Width) && double.IsNaN(width)) || Width.EqualsInTolerance(width)) + && ((double.IsNaN(Height) && double.IsNaN(height)) || Height.EqualsInTolerance(height)); } /// @@ -131,7 +131,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 Size(size1.Width + size2.Width, size1.Height + size2.Height); + public static Size operator +(Size size1, Size size2) => new(size1.Width + size2.Width, size1.Height + size2.Height); /// /// Returns a new created from the provided and . @@ -139,7 +139,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 Rectangle(point, size); + public static Rectangle operator +(Size size, Point point) => new(point, size); /// /// Returns a new representing the subtraction of the two provided . @@ -147,7 +147,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 Size(size1.Width - size2.Width, size1.Height - size2.Height); + public static Size operator -(Size size1, Size size2) => new(size1.Width - size2.Width, size1.Height - size2.Height); /// /// Returns a new representing the multiplication of the two provided . @@ -155,7 +155,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 Size(size1.Width * size2.Width, size1.Height * size2.Height); + public static Size operator *(Size size1, 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 +163,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(size.Width * factor, size.Height * factor); + public static Size operator *(Size size, double factor) => new(size.Width * factor, size.Height * factor); /// /// Returns a new representing the division of the two provided . @@ -189,7 +189,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(size.Width * scale.Horizontal, size.Height * scale.Vertical); + public static Size operator *(Size size, Scale scale) => new(size.Width * scale.Horizontal, size.Height * scale.Vertical); #endregion } diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs index 31edaf8..4c6ec12 100644 --- a/RGB.NET.Core/RGBSurface.cs +++ b/RGB.NET.Core/RGBSurface.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Diagnostics; using System.Linq; @@ -14,24 +15,18 @@ namespace RGB.NET.Core /// /// Represents a RGB-surface containing multiple devices. /// - public partial class RGBSurface : AbstractBindable, IDisposable + public class RGBSurface : AbstractBindable, IDisposable { #region Properties & Fields - /// - /// Gets the singelot-instance of the class. - /// - public static RGBSurface Instance { get; } = new RGBSurface(); - private Stopwatch _deltaTimeCounter; - private IList _deviceProvider = new List(); private IList _devices = new List(); private IList _updateTriggers = new List(); // ReSharper disable InconsistentNaming - private readonly LinkedList _ledGroups = new LinkedList(); + private readonly LinkedList _ledGroups = new(); // ReSharper restore InconsistentNaming @@ -71,12 +66,68 @@ namespace RGB.NET.Core #endregion + #region EventHandler + + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void ExceptionEventHandler(ExceptionEventArgs args); + + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void UpdatingEventHandler(UpdatingEventArgs args); + + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void UpdatedEventHandler(UpdatedEventArgs args); + + /// + /// Represents the event-handler of the -event. + /// + /// + public delegate void SurfaceLayoutChangedEventHandler(SurfaceLayoutChangedEventArgs args); + + #endregion + + #region Events + + // ReSharper disable EventNeverSubscribedTo.Global + + /// + /// Occurs when a catched exception is thrown inside the . + /// + public event ExceptionEventHandler? Exception; + + /// + /// Occurs when the starts updating. + /// + public event UpdatingEventHandler? Updating; + + /// + /// Occurs when the update is done. + /// + public event UpdatedEventHandler? Updated; + + /// + /// Occurs when the layout of this changed. + /// + public event SurfaceLayoutChangedEventHandler? SurfaceLayoutChanged; + + // ReSharper restore EventNeverSubscribedTo.Global + + #endregion + #region Constructors /// /// Initializes a new instance of the class. /// - private RGBSurface() + public RGBSurface() { _deltaTimeCounter = Stopwatch.StartNew(); } @@ -91,13 +142,10 @@ namespace RGB.NET.Core /// Specifies whether all , (including clean ones) should be updated. public void Update(bool flushLeds = false) => Update(null, new CustomUpdateData(("flushLeds", flushLeds))); - private void Update(object updateTrigger, CustomUpdateData customData) => Update(updateTrigger as IUpdateTrigger, customData); + private void Update(object? updateTrigger, CustomUpdateData customData) => Update(updateTrigger as IUpdateTrigger, customData); - private void Update(IUpdateTrigger updateTrigger, CustomUpdateData customData) + private void Update(IUpdateTrigger? updateTrigger, CustomUpdateData customData) { - if (customData == null) - customData = new CustomUpdateData(); - try { bool flushLeds = customData["flushLeds"] as bool? ?? false; @@ -108,7 +156,7 @@ namespace RGB.NET.Core lock (_devices) { OnUpdating(updateTrigger, customData); - + if (render) lock (_ledGroups) { @@ -120,9 +168,8 @@ namespace RGB.NET.Core if (updateDevices) foreach (IRGBDevice device in _devices) - if (!device.UpdateMode.HasFlag(DeviceUpdateMode.NoUpdate)) - try { device.Update(flushLeds); } - catch (Exception ex) { OnException(ex); } + try { device.Update(flushLeds); } + catch (Exception ex) { OnException(ex); } OnUpdated(); } @@ -136,23 +183,19 @@ namespace RGB.NET.Core /// public void Dispose() { + List devices; lock (_devices) - foreach (IRGBDevice device in _devices) - try { device.Dispose(); } - catch { /* We do what we can */} + devices = new List(_devices); - lock (_deviceProvider) - foreach (IRGBDeviceProvider deviceProvider in _deviceProvider) - try { deviceProvider.Dispose(); } - catch { /* We do what we can */} + foreach (IRGBDevice device in devices) + try { Detach(device); } + catch { /* We do what we can */} foreach (IUpdateTrigger updateTrigger in _updateTriggers) try { updateTrigger.Dispose(); } catch { /* We do what we can */} _ledGroups.Clear(); - _devices = null; - _deviceProvider = null; } /// @@ -162,15 +205,15 @@ namespace RGB.NET.Core private void Render(ILedGroup ledGroup) { IList leds = ledGroup.GetLeds().ToList(); - IBrush brush = ledGroup.Brush; + IBrush? brush = ledGroup.Brush; if ((brush == null) || !brush.IsEnabled) return; switch (brush.BrushCalculationMode) { case BrushCalculationMode.Relative: - Rectangle brushRectangle = new Rectangle(leds.Select(led => led.AbsoluteLedRectangle)); - Point offset = new Point(-brushRectangle.Location.X, -brushRectangle.Location.Y); + Rectangle brushRectangle = new(leds.Select(led => led.AbsoluteLedRectangle)); + 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.AbsoluteLedRectangle.Translate(offset)))); break; @@ -195,14 +238,12 @@ namespace RGB.NET.Core /// true if the could be attached; otherwise, false. public bool AttachLedGroup(ILedGroup ledGroup) { - if (ledGroup == null) return false; - lock (_ledGroups) { if (_ledGroups.Contains(ledGroup)) return false; _ledGroups.AddLast(ledGroup); - ledGroup.OnAttach(); + ledGroup.OnAttach(this); return true; } @@ -215,25 +256,86 @@ namespace RGB.NET.Core /// true if the could be detached; otherwise, false. public bool DetachLedGroup(ILedGroup ledGroup) { - if (ledGroup == null) return false; - lock (_ledGroups) { - LinkedListNode node = _ledGroups.Find(ledGroup); + LinkedListNode? node = _ledGroups.Find(ledGroup); if (node == null) return false; _ledGroups.Remove(node); - node.Value.OnDetach(); + node.Value.OnDetach(this); return true; } } + public void Attach(IEnumerable devices) + { + lock (_devices) + { + foreach (IRGBDevice device in devices) + Attach(device); + } + } + + public void Attach(IRGBDevice device) + { + lock (_devices) + { + if (_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' is already attached."); + + device.Surface = this; + + _devices.Add(device); + } + } + + 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 attached."); + + device.Surface = null; + + _devices.Remove(device); + } + } + + /// + /// 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 DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) + { + UpdateSurfaceRectangle(); + SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs((sender is IRGBDevice device) ? new[] { device } : Array.Empty(), false, true)); + } + private void UpdateSurfaceRectangle() { lock (_devices) { - Rectangle devicesRectangle = new Rectangle(_devices.Select(d => d.DeviceRectangle)); + Rectangle devicesRectangle = new(_devices.Select(d => d.DeviceRectangle)); SurfaceRectangle = SurfaceRectangle.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height)); } } @@ -247,7 +349,7 @@ namespace RGB.NET.Core where T : class { lock (_devices) - return new ReadOnlyCollection(_devices.Select(x => x as T).Where(x => x != null).ToList()); + return new ReadOnlyCollection(_devices.Where(x => x is T).Cast().ToList()); } /// @@ -284,6 +386,45 @@ namespace RGB.NET.Core updateTrigger.Update -= Update; } + /// + /// Handles the needed event-calls for an exception. + /// + /// The exception previously thrown. + private void OnException(Exception ex) + { + try + { + Exception?.Invoke(new ExceptionEventArgs(ex)); + } + catch { /* Well ... that's not my fault */ } + } + + /// + /// Handles the needed event-calls before updating. + /// + private void OnUpdating(IUpdateTrigger? trigger, CustomUpdateData customData) + { + try + { + double deltaTime = _deltaTimeCounter.Elapsed.TotalSeconds; + _deltaTimeCounter.Restart(); + Updating?.Invoke(new UpdatingEventArgs(deltaTime, trigger, customData)); + } + catch { /* Well ... that's not my fault */ } + } + + /// + /// Handles the needed event-calls after an update. + /// + private void OnUpdated() + { + try + { + Updated?.Invoke(new UpdatedEventArgs()); + } + catch { /* Well ... that's not my fault */ } + } + #endregion } } diff --git a/RGB.NET.Core/RGBSurfaceDeviceEvents.cs b/RGB.NET.Core/RGBSurfaceDeviceEvents.cs deleted file mode 100644 index 8af4f06..0000000 --- a/RGB.NET.Core/RGBSurfaceDeviceEvents.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; - -namespace RGB.NET.Core -{ - public partial class RGBSurface - { - #region EventHandler - - /// - /// Represents the event-handler of the -event. - /// - /// The arguments provided by the event. - public delegate void ExceptionEventHandler(ExceptionEventArgs args); - - /// - /// Represents the event-handler of the -event. - /// - /// The arguments provided by the event. - public delegate void UpdatingEventHandler(UpdatingEventArgs args); - - /// - /// Represents the event-handler of the -event. - /// - /// The arguments provided by the event. - public delegate void UpdatedEventHandler(UpdatedEventArgs args); - - /// - /// Represents the event-handler of the -event. - /// - /// - public delegate void SurfaceLayoutChangedEventHandler(SurfaceLayoutChangedEventArgs args); - - #endregion - - #region Events - - // ReSharper disable EventNeverSubscribedTo.Global - - /// - /// Occurs when a catched exception is thrown inside the . - /// - public event ExceptionEventHandler Exception; - - /// - /// Occurs when the starts updating. - /// - public event UpdatingEventHandler Updating; - - /// - /// Occurs when the update is done. - /// - public event UpdatedEventHandler Updated; - - /// - /// Occurs when the layout of this changed. - /// - public event SurfaceLayoutChangedEventHandler SurfaceLayoutChanged; - - // ReSharper restore EventNeverSubscribedTo.Global - - #endregion - - #region Methods - - /// - /// Handles the needed event-calls for an exception. - /// - /// The exception previously thrown. - private void OnException(Exception ex) - { - try - { - Exception?.Invoke(new ExceptionEventArgs(ex)); - } - catch { /* Well ... that's not my fault */ } - } - - /// - /// Handles the needed event-calls before updating. - /// - private void OnUpdating(IUpdateTrigger trigger, CustomUpdateData customData) - { - try - { - double deltaTime = _deltaTimeCounter.Elapsed.TotalSeconds; - _deltaTimeCounter.Restart(); - Updating?.Invoke(new UpdatingEventArgs(deltaTime, trigger, customData)); - } - catch { /* Well ... that's not my fault */ } - } - - /// - /// Handles the needed event-calls after an update. - /// - private void OnUpdated() - { - try - { - Updated?.Invoke(new UpdatedEventArgs()); - } - catch { /* Well ... that's not my fault */ } - } - - #endregion - } -} diff --git a/RGB.NET.Core/RGBSurfaceDeviceLoader.cs b/RGB.NET.Core/RGBSurfaceDeviceLoader.cs deleted file mode 100644 index df760c3..0000000 --- a/RGB.NET.Core/RGBSurfaceDeviceLoader.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -namespace RGB.NET.Core -{ - public partial class RGBSurface - { - #region Methods - - // ReSharper disable UnusedMember.Global - /// - /// Loads all devices the given by the provided by the give . - /// - /// The which provides the to load the devices from. - /// Specifies which types of devices to load. - /// Specifies whether the application should request exclusive access of possible or not. - /// Specifies whether exception during the initialization sequence should be thrown or not. - public void LoadDevices(IRGBDeviceProviderLoader deviceProviderLoader, RGBDeviceType loadFilter = RGBDeviceType.All, - bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - => LoadDevices(deviceProviderLoader.GetDeviceProvider(), loadFilter, exclusiveAccessIfPossible, throwExceptions); - - /// - /// Loads all devices the given is able to provide. - /// - /// The to load the devices from. - /// Specifies which types of devices to load. - /// Specifies whether the application should request exclusive access of possible or not. - /// Specifies whether exception during the initialization sequence should be thrown or not. - public void LoadDevices(IRGBDeviceProvider deviceProvider, RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - lock (_deviceProvider) - { - if (_deviceProvider.Contains(deviceProvider) || _deviceProvider.Any(x => x.GetType() == deviceProvider.GetType())) return; - - List addedDevices = new List(); - if (deviceProvider.IsInitialized || deviceProvider.Initialize(loadFilter, exclusiveAccessIfPossible, throwExceptions)) - { - _deviceProvider.Add(deviceProvider); - lock (_devices) - foreach (IRGBDevice device in deviceProvider.Devices) - { - if (_devices.Contains(device)) continue; - - addedDevices.Add(device); - - device.PropertyChanged += DeviceOnPropertyChanged; - _devices.Add(device); - } - } - - if (addedDevices.Any()) - { - UpdateSurfaceRectangle(); - SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs(addedDevices, true, false)); - } - } - } - - /// - /// 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 DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) - { - UpdateSurfaceRectangle(); - SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs(new[] { sender as IRGBDevice }, false, true)); - } - - #endregion - } -} diff --git a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs index e311037..722c30e 100644 --- a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs +++ b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs @@ -10,9 +10,9 @@ namespace RGB.NET.Core #region Events /// - public event EventHandler Starting; + public event EventHandler? Starting; /// - public event EventHandler Update; + public event EventHandler? Update; #endregion @@ -22,13 +22,13 @@ namespace RGB.NET.Core /// Invokes the -event. /// /// Optional custom-data passed to the subscribers of the .event. - protected virtual void OnStartup(CustomUpdateData updateData = null) => Starting?.Invoke(this, updateData); + protected virtual void OnStartup(CustomUpdateData? updateData = null) => Starting?.Invoke(this, updateData ?? new CustomUpdateData()); /// /// Invokes the -event. /// /// Optional custom-data passed to the subscribers of the .event. - protected virtual void OnUpdate(CustomUpdateData updateData = null) => Update?.Invoke(this, updateData); + protected virtual void OnUpdate(CustomUpdateData? updateData = null) => Update?.Invoke(this, updateData ?? new CustomUpdateData()); /// public abstract void Dispose(); diff --git a/RGB.NET.Core/Update/CustomUpdateData.cs b/RGB.NET.Core/Update/CustomUpdateData.cs index 0ecfc7f..0c14e77 100644 --- a/RGB.NET.Core/Update/CustomUpdateData.cs +++ b/RGB.NET.Core/Update/CustomUpdateData.cs @@ -9,7 +9,7 @@ namespace RGB.NET.Core { #region Properties & Fields - private Dictionary _data = new Dictionary(); + private Dictionary _data = new(); #endregion @@ -20,10 +20,10 @@ namespace RGB.NET.Core /// /// The key of the value. /// The value represented by the given key. - public object this[string key] + public object? this[string key] { - get => _data.TryGetValue(key?.ToUpperInvariant() ?? string.Empty, out object data) ? data : default; - set => _data[key?.ToUpperInvariant() ?? string.Empty] = value; + get => _data.TryGetValue(key.ToUpperInvariant(), out object? data) ? data : default; + set => _data[key.ToUpperInvariant()] = value; } #endregion diff --git a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs index 8f4beba..43caf4c 100644 --- a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs +++ b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs @@ -53,12 +53,12 @@ namespace RGB.NET.Core } } - protected AutoResetEvent HasDataEvent = new AutoResetEvent(false); + protected AutoResetEvent HasDataEvent { get; set; } = new(false); - protected bool IsRunning; - protected Task UpdateTask; - protected CancellationTokenSource UpdateTokenSource; - protected CancellationToken UpdateToken; + protected bool IsRunning { get; set; } + protected Task? UpdateTask { get; set; } + protected CancellationTokenSource? UpdateTokenSource { get; set; } + protected CancellationToken UpdateToken { get; set; } #endregion @@ -106,15 +106,18 @@ namespace RGB.NET.Core IsRunning = false; - UpdateTokenSource.Cancel(); - await UpdateTask; - UpdateTask.Dispose(); + UpdateTokenSource?.Cancel(); + if (UpdateTask != null) + await UpdateTask; + + UpdateTask?.Dispose(); UpdateTask = null; } protected virtual void UpdateLoop() { OnStartup(); + while (!UpdateToken.IsCancellationRequested) { if (HasDataEvent.WaitOne(Timeout)) diff --git a/RGB.NET.Core/Update/Devices/UpdateQueue.cs b/RGB.NET.Core/Update/Devices/UpdateQueue.cs index da5c82c..d64584e 100644 --- a/RGB.NET.Core/Update/Devices/UpdateQueue.cs +++ b/RGB.NET.Core/Update/Devices/UpdateQueue.cs @@ -10,12 +10,13 @@ namespace RGB.NET.Core /// The type of the key used to identify some data. /// The type of the data. public abstract class UpdateQueue : IDisposable + where TIdentifier : notnull { #region Properties & Fields - private readonly object _dataLock = new object(); + private readonly object _dataLock = new(); private readonly IDeviceUpdateTrigger _updateTrigger; - private Dictionary _currentDataSet; + private Dictionary? _currentDataSet; #endregion @@ -42,16 +43,18 @@ namespace RGB.NET.Core /// /// The causing this update. /// provided by the trigger. - protected virtual void OnUpdate(object sender, CustomUpdateData customData) + protected virtual void OnUpdate(object? sender, CustomUpdateData customData) { Dictionary dataSet; lock (_dataLock) { + if (_currentDataSet == null) return; + dataSet = _currentDataSet; _currentDataSet = null; } - if ((dataSet != null) && (dataSet.Count != 0)) + if (dataSet.Count != 0) Update(dataSet); } @@ -60,7 +63,7 @@ namespace RGB.NET.Core /// /// The starting . /// provided by the trigger. - protected virtual void OnStartup(object sender, CustomUpdateData customData) { } + protected virtual void OnStartup(object? sender, CustomUpdateData customData) { } /// /// Performs the update this queue is responsible for. @@ -75,7 +78,7 @@ namespace RGB.NET.Core // ReSharper disable once MemberCanBeProtected.Global public virtual void SetData(Dictionary dataSet) { - if ((dataSet == null) || (dataSet.Count == 0)) return; + if (dataSet.Count == 0) return; lock (_dataLock) { @@ -83,8 +86,8 @@ namespace RGB.NET.Core _currentDataSet = dataSet; else { - foreach (KeyValuePair command in dataSet) - _currentDataSet[command.Key] = command.Value; + foreach ((TIdentifier key, TData value) in dataSet) + _currentDataSet[key] = value; } } @@ -132,7 +135,7 @@ namespace RGB.NET.Core /// Calls for a data set created out of the provided list of . /// /// - public void SetData(IEnumerable leds) => SetData(leds?.ToDictionary(x => x.CustomData ?? x.Id, x => x.Color)); + public void SetData(IEnumerable leds) => SetData(leds.ToDictionary(x => x.CustomData ?? x.Id, x => x.Color)); #endregion } diff --git a/RGB.NET.Core/Update/IUpdateTrigger.cs b/RGB.NET.Core/Update/IUpdateTrigger.cs index eed8f3d..e80c3c0 100644 --- a/RGB.NET.Core/Update/IUpdateTrigger.cs +++ b/RGB.NET.Core/Update/IUpdateTrigger.cs @@ -10,11 +10,11 @@ namespace RGB.NET.Core /// /// Occurs when the trigger is starting up. /// - event EventHandler Starting; + event EventHandler? Starting; /// /// Occurs when the trigger wants to cause an update. /// - event EventHandler Update; + event EventHandler? Update; } } diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs index 0171ffb..24321be 100644 --- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs +++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs @@ -14,12 +14,11 @@ namespace RGB.NET.Core { #region Properties & Fields - private object _lock = new object(); + private object _lock = new(); - private CancellationTokenSource _updateTokenSource; - private CancellationToken _updateToken; - private Task _updateTask; - private Stopwatch _sleepCounter; + protected Task? UpdateTask { get; set; } + protected CancellationTokenSource? UpdateTokenSource { get; set; } + protected CancellationToken UpdateToken { get; set; } private double _updateFrequency = 1.0 / 30.0; /// @@ -46,8 +45,6 @@ namespace RGB.NET.Core /// A value indicating if the trigger should automatically right after construction. public TimerUpdateTrigger(bool autostart = true) { - _sleepCounter = new Stopwatch(); - if (autostart) Start(); } @@ -63,11 +60,11 @@ namespace RGB.NET.Core { lock (_lock) { - if (_updateTask == null) + if (UpdateTask == null) { - _updateTokenSource?.Dispose(); - _updateTokenSource = new CancellationTokenSource(); - _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); + UpdateTokenSource?.Dispose(); + UpdateTokenSource = new CancellationTokenSource(); + UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); } } } @@ -79,30 +76,35 @@ namespace RGB.NET.Core { lock (_lock) { - if (_updateTask != null) + if (UpdateTask != null) { - _updateTokenSource.Cancel(); + UpdateTokenSource?.Cancel(); // ReSharper disable once MethodSupportsCancellation - _updateTask.Wait(); - _updateTask.Dispose(); - _updateTask = null; + UpdateTask.Wait(); + UpdateTask.Dispose(); + UpdateTask = null; } } } private void UpdateLoop() { - while (!_updateToken.IsCancellationRequested) + OnStartup(); + + while (!UpdateToken.IsCancellationRequested) { - _sleepCounter.Restart(); + long preUpdateTicks = Stopwatch.GetTimestamp(); OnUpdate(); - _sleepCounter.Stop(); - LastUpdateTime = _sleepCounter.Elapsed.TotalSeconds; - int sleep = (int)((UpdateFrequency * 1000.0) - _sleepCounter.ElapsedMilliseconds); - if (sleep > 0) - Thread.Sleep(sleep); + if (UpdateFrequency > 0) + { + double lastUpdateTime = ((Stopwatch.GetTimestamp() - preUpdateTicks) / 10000.0); + LastUpdateTime = lastUpdateTime; + int sleep = (int)((UpdateFrequency * 1000.0) - lastUpdateTime); + if (sleep > 0) + Thread.Sleep(sleep); + } } } diff --git a/RGB.NET.Decorators/Brush/FlashDecorator.cs b/RGB.NET.Decorators/Brush/FlashDecorator.cs index 580fce4..5900851 100644 --- a/RGB.NET.Decorators/Brush/FlashDecorator.cs +++ b/RGB.NET.Decorators/Brush/FlashDecorator.cs @@ -74,6 +74,14 @@ namespace RGB.NET.Decorators.Brush #endregion + #region Constructors + + public FlashDecorator(RGBSurface surface, bool updateIfDisabled = false) + : base(surface, updateIfDisabled) + { } + + #endregion + #region Methods /// diff --git a/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs b/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs index 9e7f86a..52a679b 100644 --- a/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs +++ b/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs @@ -45,7 +45,8 @@ namespace RGB.NET.Decorators.Gradient /// : 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(double speed = 180.0, bool direction = true) + public MoveGradientDecorator(RGBSurface surface, double speed = 180.0, bool direction = true) + : base(surface) { this.Speed = speed; this.Direction = direction; diff --git a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs index 8547b14..7372b20 100644 --- a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs +++ b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; +using System.Linq; using AuraServiceLib; using RGB.NET.Core; @@ -18,7 +18,7 @@ namespace RGB.NET.Devices.Asus { #region Properties & Fields - private static AsusDeviceProvider _instance; + private static AsusDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -31,26 +31,14 @@ namespace RGB.NET.Devices.Asus public bool IsInitialized { get; private set; } /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for asus devices. /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + public DeviceUpdateTrigger UpdateTrigger { get; } - private IAuraSdk2 _sdk; + private IAuraSdk2? _sdk; #endregion @@ -69,17 +57,17 @@ namespace RGB.NET.Devices.Asus } #endregion - + #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); // ReSharper disable once SuspiciousTypeConversion.Global _sdk = (IAuraSdk2)new AuraSdk(); @@ -116,7 +104,7 @@ namespace RGB.NET.Devices.Asus case AsusDeviceType.KEYBOARD_RGB: case AsusDeviceType.NB_KB_RGB: case AsusDeviceType.NB_KB_4ZONE_RGB: - rgbDevice = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device, CultureInfo.CurrentCulture)); + rgbDevice = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device, AsusPhysicalKeyboardLayout.Default)); break; case AsusDeviceType.MOUSE_RGB: @@ -141,7 +129,7 @@ namespace RGB.NET.Devices.Asus } } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -155,19 +143,17 @@ namespace RGB.NET.Devices.Asus return true; } - /// - public void ResetDevices() - { - _sdk?.ReleaseControl(0); - _sdk?.SwitchMode(); - } - /// public void Dispose() { - try { UpdateTrigger?.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(); + try { _sdk?.ReleaseControl(0); } catch { /* at least we tried */ } diff --git a/RGB.NET.Devices.Asus/AsusDeviceProviderLoader.cs b/RGB.NET.Devices.Asus/AsusDeviceProviderLoader.cs deleted file mode 100644 index 576dfb5..0000000 --- a/RGB.NET.Devices.Asus/AsusDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// Represents a device provider loaded used to dynamically load asus devices into an application. - /// - public class AsusDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => AsusDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs index 7ee2183..6920a01 100644 --- a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs @@ -26,18 +26,13 @@ namespace RGB.NET.Devices.Asus /// protected override void InitializeLayout() { - //TODO DarthAffe 07.10.2017: Look for a good default layout int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.DRAM1 + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 21.10.2017: We don't know the model, how to save layouts and images? - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Drams", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + AddLed(LedId.DRAM1 + i, new Point(i * 10, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.DRAM1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.DRAM1; #endregion } diff --git a/RGB.NET.Devices.Asus/Enum/AsusLogicalKeyboardLayout.cs b/RGB.NET.Devices.Asus/Enum/AsusLogicalKeyboardLayout.cs deleted file mode 100644 index 60105e5..0000000 --- a/RGB.NET.Devices.Asus/Enum/AsusLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Asus -{ - /// - /// Contains list of available logical layouts for asus keyboards. - /// - public enum AsusLogicalKeyboardLayout - { - TODO - }; -} diff --git a/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs index b5e80de..fcc1082 100644 --- a/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs @@ -10,6 +10,6 @@ namespace RGB.NET.Devices.Asus /// public enum AsusPhysicalKeyboardLayout { - TODO + Default } } diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs index cafd420..8b57013 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs @@ -24,7 +24,7 @@ namespace RGB.NET.Devices.Asus /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected AsusUpdateQueue UpdateQueue { get; set; } + protected AsusUpdateQueue? UpdateQueue { get; set; } #endregion @@ -52,7 +52,7 @@ namespace RGB.NET.Devices.Asus if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } @@ -66,8 +66,8 @@ namespace RGB.NET.Devices.Asus 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(ledsToUpdate.Where(x => x.Color.A > 0)); + /// public override void Dispose() { diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs index 42d61e6..e55c276 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using AuraServiceLib; +using AuraServiceLib; using RGB.NET.Core; namespace RGB.NET.Devices.Asus @@ -24,12 +23,8 @@ namespace RGB.NET.Devices.Asus /// public string Model { get; } - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - public IAuraSyncDevice Device { get; } #endregion @@ -43,7 +38,7 @@ namespace RGB.NET.Devices.Asus /// The backing this RGB.NET device. /// The manufacturer-name of the . /// The model-name of the . - internal AsusRGBDeviceInfo(RGBDeviceType deviceType, IAuraSyncDevice device, string model = null, string manufacturer = "Asus") + internal AsusRGBDeviceInfo(RGBDeviceType deviceType, IAuraSyncDevice device, string? model = null, string manufacturer = "Asus") { this.DeviceType = deviceType; this.Device = device; diff --git a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs index 40eb602..c114b52 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs @@ -36,14 +36,11 @@ namespace RGB.NET.Devices.Asus { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(_baseLedId + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 19.05.2019: Add a way to define a layout for this kind of devies + AddLed(_baseLedId + i, new Point(i * 10, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)_baseLedId; - + 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 9a3b260..1623fa7 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs @@ -15,7 +15,7 @@ namespace RGB.NET.Devices.Asus /// /// The device to be updated. /// - protected IAuraSyncDevice Device { get; private set; } + protected IAuraSyncDevice? Device { get; private set; } #endregion @@ -45,15 +45,16 @@ namespace RGB.NET.Devices.Asus /// protected override void Update(Dictionary dataSet) { + if (Device == null) return; + try { if ((Device.Type == (uint)AsusDeviceType.KEYBOARD_RGB) || (Device.Type == (uint)AsusDeviceType.NB_KB_RGB)) { - foreach (KeyValuePair data in dataSet) + foreach ((object key, Color value) in dataSet) { - AsusLedId index = (AsusLedId)data.Key; - IAuraSyncKeyboard keyboard = (IAuraSyncKeyboard)Device; - if (keyboard != null) + AsusLedId index = (AsusLedId)key; + if (Device is IAuraSyncKeyboard keyboard) { IAuraRgbLight light = index switch { @@ -72,7 +73,7 @@ namespace RGB.NET.Devices.Asus _ => light }; - (_, byte r, byte g, byte b) = data.Value.GetRGBBytes(); + (_, byte r, byte g, byte b) = value.GetRGBBytes(); light.Red = r; light.Green = g; light.Blue = b; @@ -81,12 +82,12 @@ namespace RGB.NET.Devices.Asus } else { - foreach (KeyValuePair data in dataSet) + foreach ((object key, Color value) in dataSet) { - int index = (int)data.Key; + int index = (int)key; IAuraRgbLight light = Device.Lights[index]; - (_, byte r, byte g, byte b) = data.Value.GetRGBBytes(); + (_, byte r, byte g, byte b) = value.GetRGBBytes(); light.Red = r; light.Green = g; light.Blue = b; diff --git a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs index f50f70f..8c0f98a 100644 --- a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs @@ -26,17 +26,13 @@ namespace RGB.NET.Devices.Asus /// protected override void InitializeLayout() { - //TODO DarthAffe 07.10.2017: Look for a good default layout int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.GraphicsCard1 + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\GraphicsCards", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + AddLed(LedId.GraphicsCard1 + i, new Point(i * 10, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; #endregion } diff --git a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs index a3727d1..96c4c87 100644 --- a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs @@ -26,17 +26,13 @@ namespace RGB.NET.Devices.Asus /// protected override void InitializeLayout() { - //TODO DarthAffe 07.10.2017: Look for a good default layout int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Headset1 + i, new Rectangle(i * 40, 0, 40, 8)); - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Headsets", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + AddLed(LedId.Headset1 + i, new Point(i * 40, 0), new Size(40, 8)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; #endregion } diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs index 2b48961..3b9f802 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Asus { internal static class AsusKeyboardLedMapping { - public static readonly Dictionary MAPPING = new Dictionary - { + public static readonly Dictionary MAPPING = new() + { { LedId.Keyboard_Escape, AsusLedId.KEY_ESCAPE }, { LedId.Keyboard_F1, AsusLedId.KEY_F1 }, { LedId.Keyboard_F2, AsusLedId.KEY_F2 }, diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs index 7c444cf..9a00a24 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs @@ -35,26 +35,23 @@ namespace RGB.NET.Devices.Asus { int pos = 0; foreach (IAuraRgbKey key in ((IAuraSyncKeyboard)DeviceInfo.Device).Keys) - InitializeLed(reversedMapping[(AsusLedId)key.Code], new Point(pos++ * 19, 0), new Size(19, 19)); + AddLed(reversedMapping[(AsusLedId)key.Code], new Point(pos++ * 19, 0), new Size(19, 19)); //UK Layout - InitializeLed(reversedMapping[AsusLedId.KEY_OEM_102], new Point(pos++ * 19, 0), new Size(19, 19)); + AddLed(reversedMapping[AsusLedId.KEY_OEM_102], new Point(pos++ * 19, 0), new Size(19, 19)); - InitializeLed(reversedMapping[AsusLedId.UNDOCUMENTED_1], new Point(pos * 19, 0), new Size(19, 19)); + AddLed(reversedMapping[AsusLedId.UNDOCUMENTED_1], new Point(pos * 19, 0), new Size(19, 19)); } else { int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Keyboard_Custom1 + i, new Point(i * 19, 0), new Size(19, 19)); + AddLed(LedId.Keyboard_Custom1 + i, new Point(i * 19, 0), new Size(19, 19)); } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Asus\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), DeviceInfo.LogicalLayout.ToString()); } /// - protected override object CreateLedCustomData(LedId ledId) + protected override object? GetLedCustomData(LedId ledId) { if (DeviceInfo.Device.Type == (uint)AsusDeviceType.NB_KB_4ZONE_RGB) return ledId - LedId.Keyboard_Custom1; diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs index 5b8a55e..122c0a9 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using AuraServiceLib; +using AuraServiceLib; using RGB.NET.Core; namespace RGB.NET.Devices.Asus @@ -15,12 +14,7 @@ namespace RGB.NET.Devices.Asus /// /// Gets the physical layout of the keyboard. /// - public AsusPhysicalKeyboardLayout PhysicalLayout { get; private set; } - - /// - /// Gets the logical layout of the keyboard. - /// - public AsusLogicalKeyboardLayout LogicalLayout { get; private set; } + public AsusPhysicalKeyboardLayout PhysicalLayout { get; } #endregion @@ -31,27 +25,10 @@ namespace RGB.NET.Devices.Asus /// Internal constructor of managed . /// /// The backing this RGB.NET device. - /// The of the layout this keyboard is using. - internal AsusKeyboardRGBDeviceInfo(IAuraSyncDevice device, CultureInfo culture) + internal AsusKeyboardRGBDeviceInfo(IAuraSyncDevice device, AsusPhysicalKeyboardLayout layout) : base(RGBDeviceType.Keyboard, device, device.Name) { - SetLayouts(culture.KeyboardLayoutId); - } - - #endregion - - #region Methods - - private void SetLayouts(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - //TODO DarthAffe 07.10.2017: Implement - default: - PhysicalLayout = AsusPhysicalKeyboardLayout.TODO; - LogicalLayout = AsusLogicalKeyboardLayout.TODO; - break; - } + this.PhysicalLayout = layout; } #endregion diff --git a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs index 2109aee..71ee547 100644 --- a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs @@ -26,18 +26,14 @@ namespace RGB.NET.Devices.Asus /// protected override void InitializeLayout() { - //TODO DarthAffe 07.10.2017: Look for a good default layout int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Mainboard1 + i, new Rectangle(i * 40, 0, 40, 8)); - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Mainboards", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + AddLed(LedId.Mainboard1 + i, new Point(i * 40, 0), new Size(40, 8)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; - + 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 030e547..cd97e88 100644 --- a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs @@ -26,16 +26,13 @@ namespace RGB.NET.Devices.Asus /// protected override void InitializeLayout() { - //TODO DarthAffe 07.10.2017: Look for a good default layout int ledCount = DeviceInfo.Device.Lights.Count; for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Mouse1 + i, new Rectangle(i * 10, 0, 10, 10)); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Mouses", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + AddLed(LedId.Mouse1 + i, new Point(i * 10, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; #endregion } diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs index 05546aa..f7e57dc 100644 --- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs +++ b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; +using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Helper; using RGB.NET.Devices.CoolerMaster.Native; @@ -19,7 +19,7 @@ namespace RGB.NET.Devices.CoolerMaster { #region Properties & Fields - private static CoolerMasterDeviceProvider _instance; + private static CoolerMasterDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -29,13 +29,13 @@ namespace RGB.NET.Devices.CoolerMaster /// 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 List { "x86/CMSDK.dll" }; + public static List PossibleX86NativePaths { get; } = new() { "x86/CMSDK.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 List { "x64/CMSDK.dll" }; + public static List PossibleX64NativePaths { get; } = new() { "x64/CMSDK.dll" }; /// /// @@ -43,30 +43,13 @@ namespace RGB.NET.Devices.CoolerMaster /// public bool IsInitialized { get; private set; } - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _CoolerMasterSDK.LoadedArchitecture; - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for cooler master devices. /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + public DeviceUpdateTrigger UpdateTrigger { get; } #endregion @@ -89,13 +72,13 @@ namespace RGB.NET.Devices.CoolerMaster #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); _CoolerMasterSDK.Reload(); if (_CoolerMasterSDK.GetSDKVersion() <= 0) return false; @@ -118,7 +101,7 @@ namespace RGB.NET.Devices.CoolerMaster { case RGBDeviceType.Keyboard: CoolerMasterPhysicalKeyboardLayout physicalLayout = _CoolerMasterSDK.GetDeviceLayout(index); - device = new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, physicalLayout, GetCulture())); + device = new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, physicalLayout)); break; case RGBDeviceType.Mouse: @@ -142,7 +125,7 @@ namespace RGB.NET.Devices.CoolerMaster catch { if (throwExceptions) throw; } } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -157,38 +140,16 @@ namespace RGB.NET.Devices.CoolerMaster return true; } - /// - public void ResetDevices() - { - if (IsInitialized) - foreach (IRGBDevice device in Devices) - { - try - { - CoolerMasterRGBDeviceInfo deviceInfo = (CoolerMasterRGBDeviceInfo)device.DeviceInfo; - _CoolerMasterSDK.EnableLedControl(false, deviceInfo.DeviceIndex); - _CoolerMasterSDK.EnableLedControl(true, deviceInfo.DeviceIndex); - } - catch {/* shit happens */} - } - } - /// public void Dispose() { - try { UpdateTrigger?.Dispose(); } + try { UpdateTrigger.Dispose(); } catch { /* at least we tried */ } - if (IsInitialized) - foreach (IRGBDevice device in Devices) - { - try - { - CoolerMasterRGBDeviceInfo deviceInfo = (CoolerMasterRGBDeviceInfo)device.DeviceInfo; - _CoolerMasterSDK.EnableLedControl(false, deviceInfo.DeviceIndex); - } - catch {/* shit happens */} - } + foreach (IRGBDevice device in Devices) + try { device.Dispose(); } + catch { /* at least we tried */ } + Devices = Enumerable.Empty(); // 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(); } diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProviderLoader.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProviderLoader.cs deleted file mode 100644 index d8c0b9e..0000000 --- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.CoolerMaster -{ - /// - /// Represents a device provider loaded used to dynamically load cooler-master devices into an application. - /// - public class CoolerMasterDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => CoolerMasterDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterLogicalKeyboardLayout.cs b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterLogicalKeyboardLayout.cs deleted file mode 100644 index c41ac93..0000000 --- a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.CoolerMaster -{ - /// - /// Contains list of available logical layouts for cooler master keyboards. - /// - public enum CoolerMasterLogicalKeyboardLayout - { - DE - }; -} diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs index d33351f..054981d 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs @@ -26,7 +26,7 @@ namespace RGB.NET.Devices.CoolerMaster /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected CoolerMasterUpdateQueue UpdateQueue { get; set; } + protected CoolerMasterUpdateQueue? UpdateQueue { get; set; } #endregion @@ -55,7 +55,7 @@ namespace RGB.NET.Devices.CoolerMaster if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } @@ -68,7 +68,7 @@ namespace RGB.NET.Devices.CoolerMaster 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(ledsToUpdate.Where(x => x.Color.A > 0)); /// /// diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs index 9e98e92..d95993e 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Helper; namespace RGB.NET.Devices.CoolerMaster @@ -24,12 +23,8 @@ namespace RGB.NET.Devices.CoolerMaster /// public string Model { get; } - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - /// /// Gets the of the . /// @@ -49,7 +44,7 @@ namespace RGB.NET.Devices.CoolerMaster this.DeviceType = deviceType; this.DeviceIndex = deviceIndex; - Model = deviceIndex.GetDescription(); + Model = deviceIndex.GetDescription() ?? "Unknown"; DeviceName = $"{Manufacturer} {Model}"; } diff --git a/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs b/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs index 9ebd427..9cd05ce 100644 --- a/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs +++ b/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs @@ -14,38 +14,29 @@ namespace RGB.NET.Devices.CoolerMaster.Helper /// Gets the value of the . /// /// The enum value to get the description from. - /// The generic enum-type /// The value of the or the result of the source. - internal static string GetDescription(this T source) - where T : struct - { - return source.GetAttribute()?.Description ?? source.ToString(); - } + internal static string? GetDescription(this Enum source) + => source.GetAttribute()?.Description ?? source.ToString(); /// /// Gets the value of the . /// /// The enum value to get the description from. - /// The generic enum-type /// The value of the or the result of the source. - internal static RGBDeviceType GetDeviceType(this T source) - where T : struct - { - return source.GetAttribute()?.DeviceType ?? RGBDeviceType.Unknown; - } + internal static RGBDeviceType GetDeviceType(this Enum source) + => source.GetAttribute()?.DeviceType ?? RGBDeviceType.Unknown; /// /// Gets the attribute of type T. /// /// The enum value to get the attribute from /// The generic attribute type - /// The generic enum-type /// The . - private static T GetAttribute(this TEnum source) + private static T? GetAttribute(this Enum source) where T : Attribute - where TEnum : struct { - FieldInfo fi = source.GetType().GetField(source.ToString()); + FieldInfo? fi = source.GetType().GetField(source.ToString()); + if (fi == null) return null; T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); return attributes.Length > 0 ? attributes[0] : null; } diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs index 57548f1..77da300 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs @@ -14,8 +14,8 @@ namespace RGB.NET.Devices.CoolerMaster #region MasterKeysL - private static readonly Dictionary MasterKeysL_US = new Dictionary - { + private static readonly Dictionary MasterKeysL_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -131,8 +131,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_NumPeriodAndDelete, (5,20) } }; - private static readonly Dictionary MasterKeysL_EU = new Dictionary - { + private static readonly Dictionary MasterKeysL_EU = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -253,8 +253,8 @@ namespace RGB.NET.Devices.CoolerMaster #region MasterKeysM - private static readonly Dictionary MasterKeysM_US = new Dictionary - { + private static readonly Dictionary MasterKeysM_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -354,8 +354,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_NumPeriodAndDelete, (5,17) } }; - private static readonly Dictionary MasterKeysM_EU = new Dictionary - { + private static readonly Dictionary MasterKeysM_EU = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -460,8 +460,8 @@ namespace RGB.NET.Devices.CoolerMaster #region MasterKeysS - private static readonly Dictionary MasterKeysS_US = new Dictionary - { + private static readonly Dictionary MasterKeysS_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -556,8 +556,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_ArrowRight, (5,17) } }; - private static readonly Dictionary MasterKeysS_EU = new Dictionary - { + private static readonly Dictionary MasterKeysS_EU = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -657,8 +657,8 @@ namespace RGB.NET.Devices.CoolerMaster #region MasterKeysMK750 - private static readonly Dictionary MasterKeysMK750_US = new Dictionary - { + private static readonly Dictionary MasterKeysMK750_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -801,8 +801,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_Custom22, (6,17) }, }; - private static readonly Dictionary MasterKeysMK750_EU = new Dictionary - { + private static readonly Dictionary MasterKeysMK750_EU = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -946,8 +946,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_Custom22, (6,17) } }; - private static readonly Dictionary MasterKeysMK750_JP = new Dictionary - { + private static readonly Dictionary MasterKeysMK750_JP = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -1099,8 +1099,8 @@ namespace RGB.NET.Devices.CoolerMaster #region CKxxx - private static readonly Dictionary CKxxx_US = new Dictionary - { + private static readonly Dictionary CKxxx_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -1212,8 +1212,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_NumPeriodAndDelete, (5,20) } }; - private static readonly Dictionary CKxxx_EU = new Dictionary - { + private static readonly Dictionary CKxxx_EU = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -1326,8 +1326,8 @@ namespace RGB.NET.Devices.CoolerMaster { LedId.Keyboard_NumPeriodAndDelete, (5,20) } }; - private static readonly Dictionary CKxxx_JP = new Dictionary - { + private static readonly Dictionary CKxxx_JP = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,1) }, { LedId.Keyboard_F2, (0,2) }, @@ -1450,7 +1450,7 @@ namespace RGB.NET.Devices.CoolerMaster /// Contains all the hardware-id mappings for CoolerMaster devices. /// public static readonly Dictionary>> Mapping = - new Dictionary>> + new() { { CoolerMasterDevicesIndexes.MasterKeys_L, new Dictionary> { diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs index 8a8c17a..cf67d76 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs @@ -27,22 +27,18 @@ namespace RGB.NET.Devices.CoolerMaster /// protected override void InitializeLayout() { - if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary> deviceMappings)) + if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary>? deviceMappings)) throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex}"); - if (!deviceMappings.TryGetValue(DeviceInfo.PhysicalLayout, out Dictionary mapping)) + if (!deviceMappings.TryGetValue(DeviceInfo.PhysicalLayout, out Dictionary? mapping)) throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex} with physical layout {DeviceInfo.PhysicalLayout}"); - - foreach (KeyValuePair led in mapping) - InitializeLed(led.Key, new Rectangle(led.Value.column * 19, led.Value.row * 19, 19, 19)); - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\CoolerMaster\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - DeviceInfo.LogicalLayout.ToString()); + foreach ((LedId ledId, (int row, int column)) in mapping) + AddLed(ledId, new Point(column * 19, row * 19), new Size(19, 19)); } /// - protected override object CreateLedCustomData(LedId ledId) => CoolerMasterKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; - + protected override object GetLedCustomData(LedId ledId) => CoolerMasterKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; + #endregion } } diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs index c13e4cc..baa3c1b 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.CoolerMaster { @@ -16,11 +15,6 @@ namespace RGB.NET.Devices.CoolerMaster /// public CoolerMasterPhysicalKeyboardLayout PhysicalLayout { get; } - /// - /// Gets the of the . - /// - public CoolerMasterLogicalKeyboardLayout LogicalLayout { get; private set; } - #endregion #region Constructors @@ -31,24 +25,10 @@ namespace RGB.NET.Devices.CoolerMaster /// /// The index of the . /// The of the . - /// The of the layout this keyboard is using - internal CoolerMasterKeyboardRGBDeviceInfo(CoolerMasterDevicesIndexes deviceIndex, CoolerMasterPhysicalKeyboardLayout physicalKeyboardLayout, CultureInfo culture) + internal CoolerMasterKeyboardRGBDeviceInfo(CoolerMasterDevicesIndexes deviceIndex, CoolerMasterPhysicalKeyboardLayout physicalKeyboardLayout) : base(RGBDeviceType.Keyboard, deviceIndex) { this.PhysicalLayout = physicalKeyboardLayout; - - SetLayouts(culture.KeyboardLayoutId); - } - - private void SetLayouts(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - //TODO DarthAffe 02.04.2017: Check all available keyboards and there layout-ids - default: - LogicalLayout = CoolerMasterLogicalKeyboardLayout.DE; - break; - } } #endregion diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs index 61bee7d..74fd5b2 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs @@ -15,7 +15,7 @@ namespace RGB.NET.Devices.CoolerMaster /// // ReSharper disable once InconsistentNaming public static readonly Dictionary> Mapping = - new Dictionary> + new() { { CoolerMasterDevicesIndexes.MasterMouse_L, new Dictionary { diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs index a59b1ce..e1efb77 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs @@ -30,15 +30,12 @@ namespace RGB.NET.Devices.CoolerMaster Dictionary mapping = CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex]; foreach (KeyValuePair led in mapping) - InitializeLed(led.Key, new Rectangle(led.Value.column * 19, led.Value.row * 19, 19, 19)); - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\CoolerMaster\Mice", $"{model}.xml"), null); + AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19)); } /// - protected override object CreateLedCustomData(LedId ledId) => CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex][ledId]; - + protected override object GetLedCustomData(LedId ledId) => CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex][ledId]; + #endregion } } diff --git a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs index ac23587..6cf86c6 100644 --- a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs +++ b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs @@ -16,12 +16,7 @@ namespace RGB.NET.Devices.CoolerMaster.Native #region Libary Management private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - + /// /// Reloads the SDK. /// @@ -37,7 +32,7 @@ namespace RGB.NET.Devices.CoolerMaster.Native // HACK: Load library at runtime to support both, x86 and x64 with one managed dll List possiblePathList = Environment.Is64BitProcess ? CoolerMasterDeviceProvider.PossibleX64NativePaths : CoolerMasterDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); if (dllPath == null) throw new RGBDeviceException($"Can't find the CoolerMaster-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); _dllHandle = LoadLibrary(dllPath); @@ -76,14 +71,14 @@ namespace RGB.NET.Devices.CoolerMaster.Native #region Pointers - private static GetSDKVersionPointer _getSDKVersionPointer; - private static SetControlDevicePointer _setControlDevicenPointer; - private static IsDevicePlugPointer _isDevicePlugPointer; - private static GetDeviceLayoutPointer _getDeviceLayoutPointer; - private static EnableLedControlPointer _enableLedControlPointer; - private static RefreshLedPointer _refreshLedPointer; - private static SetLedColorPointer _setLedColorPointer; - private static SetAllLedColorPointer _setAllLedColorPointer; + private static GetSDKVersionPointer? _getSDKVersionPointer; + private static SetControlDevicePointer? _setControlDevicenPointer; + private static IsDevicePlugPointer? _isDevicePlugPointer; + private static GetDeviceLayoutPointer? _getDeviceLayoutPointer; + private static EnableLedControlPointer? _enableLedControlPointer; + private static RefreshLedPointer? _refreshLedPointer; + private static SetLedColorPointer? _setLedColorPointer; + private static SetAllLedColorPointer? _setAllLedColorPointer; #endregion @@ -125,49 +120,49 @@ namespace RGB.NET.Devices.CoolerMaster.Native /// /// CM-SDK: Get SDK Dll's Version. /// - internal static int GetSDKVersion() => _getSDKVersionPointer(); + internal static int GetSDKVersion() => (_getSDKVersionPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(); /// /// CM-SDK: set operating device /// internal static void SetControlDevice(CoolerMasterDevicesIndexes devicesIndexes) - => _setControlDevicenPointer(devicesIndexes); + => (_setControlDevicenPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(devicesIndexes); /// /// CM-SDK: verify if the deviced is plugged in /// internal static bool IsDevicePlugged(CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _isDevicePlugPointer(devIndex); + => (_isDevicePlugPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(devIndex); /// /// CM-SDK: Obtain current device layout /// internal static CoolerMasterPhysicalKeyboardLayout GetDeviceLayout(CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _getDeviceLayoutPointer(devIndex); + => (_getDeviceLayoutPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(devIndex); /// /// CM-SDK: set control over device’s LED /// internal static bool EnableLedControl(bool value, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _enableLedControlPointer(value, devIndex); + => (_enableLedControlPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(value, devIndex); /// /// CM-SDK: Print out the lights setting from Buffer to LED /// internal static bool RefreshLed(bool autoRefresh, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _refreshLedPointer(autoRefresh, devIndex); + => (_refreshLedPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(autoRefresh, devIndex); /// /// CM-SDK: Set single Key LED color /// internal static bool SetLedColor(int row, int column, byte r, byte g, byte b, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _setLedColorPointer(row, column, r, g, b, devIndex); + => (_setLedColorPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(row, column, r, g, b, devIndex); /// /// CM-SDK: Set Keyboard "every LED" color /// internal static bool SetAllLedColor(_CoolerMasterColorMatrix colorMatrix, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _setAllLedColorPointer(colorMatrix, devIndex); + => (_setAllLedColorPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(colorMatrix, devIndex); // ReSharper restore EventExceptionNotDocumented diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index 74ac4ec..4f7a57a 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -4,6 +4,7 @@ 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.Corsair.Native; @@ -18,7 +19,7 @@ namespace RGB.NET.Devices.Corsair { #region Properties & Fields - private static CorsairDeviceProvider _instance; + private static CorsairDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -28,13 +29,13 @@ namespace RGB.NET.Devices.Corsair /// 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 List { "x86/CUESDK.dll", "x86/CUESDK_2015.dll", "x86/CUESDK_2013.dll" }; + public static List PossibleX86NativePaths { get; } = new() { "x86/CUESDK.dll", "x86/CUESDK_2015.dll", "x86/CUESDK_2013.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 List { "x64/CUESDK.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" }; + public static List PossibleX64NativePaths { get; } = new() { "x64/CUESDK.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" }; /// /// @@ -42,21 +43,10 @@ namespace RGB.NET.Devices.Corsair /// public bool IsInitialized { get; private set; } - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _CUESDK.LoadedArchitecture; - /// /// Gets the protocol details for the current SDK-connection. /// - public CorsairProtocolDetails ProtocolDetails { get; private set; } - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } + public CorsairProtocolDetails? ProtocolDetails { get; private set; } /// /// Gets the last error documented by CUE. @@ -64,7 +54,7 @@ namespace RGB.NET.Devices.Corsair public CorsairError LastError => _CUESDK.CorsairGetLastError(); /// - public IEnumerable Devices { get; private set; } + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for corsair devices. @@ -94,13 +84,13 @@ namespace RGB.NET.Devices.Corsair /// /// 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 exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); _CUESDK.Reload(); @@ -115,42 +105,30 @@ namespace RGB.NET.Devices.Corsair + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n" + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})"); - if (exclusiveAccessIfPossible) - { - if (!_CUESDK.CorsairRequestControl(CorsairAccessMode.ExclusiveLightingControl)) - throw new CUEException(LastError); - - HasExclusiveAccess = true; - } - else - HasExclusiveAccess = false; - - // DarthAffe 07.07.2018: 127 is CUE, we want to directly compete with it as in older versions. - if (!_CUESDK.CorsairSetLayerPriority(127)) + // DarthAffe 02.02.2021: 127 is iCUE + if (!_CUESDK.CorsairSetLayerPriority(128)) throw new CUEException(LastError); - Dictionary modelCounter = new Dictionary(); + 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 CorsairRGBDeviceInfo(i, RGBDeviceType.Unknown, nativeDeviceInfo, modelCounter); + _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; + CorsairDeviceUpdateQueue? deviceUpdateQueue = null; foreach (ICorsairRGBDevice device in GetRGBDevice(info, i, nativeDeviceInfo, modelCounter)) { if ((device == null) || !loadFilter.HasFlag(device.DeviceInfo.DeviceType)) continue; - if (deviceUpdateQueue == null) - deviceUpdateQueue = new CorsairDeviceUpdateQueue(UpdateTrigger, info.CorsairDeviceIndex); + deviceUpdateQueue ??= new CorsairDeviceUpdateQueue(UpdateTrigger, info.CorsairDeviceIndex); device.Initialize(deviceUpdateQueue); - AddSpecialParts(device); error = LastError; if (error != CorsairError.Success) @@ -162,7 +140,7 @@ namespace RGB.NET.Devices.Corsair catch { if (throwExceptions) throw; } } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -208,7 +186,7 @@ namespace RGB.NET.Devices.Corsair case CorsairDeviceType.Cooler: case CorsairDeviceType.CommanderPro: case CorsairDeviceType.LightningNodePro: - _CorsairChannelsInfo channelsInfo = nativeDeviceInfo.channels; + _CorsairChannelsInfo? channelsInfo = nativeDeviceInfo.channels; if (channelsInfo != null) { IntPtr channelInfoPtr = channelsInfo.channels; @@ -218,14 +196,14 @@ namespace RGB.NET.Devices.Corsair CorsairLedId referenceLed = GetChannelReferenceId(info.CorsairDeviceType, channel); if (referenceLed == CorsairLedId.Invalid) continue; - _CorsairChannelInfo channelInfo = (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo)); + _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++) { - _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo)); + _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!; yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter)); referenceLed += channelDeviceInfo.deviceLedCount; @@ -252,50 +230,34 @@ namespace RGB.NET.Devices.Corsair { if (deviceType == CorsairDeviceType.Cooler) return CorsairLedId.CustomLiquidCoolerChannel1Led1; - else + + return channel switch { - switch (channel) - { - case 0: return CorsairLedId.CustomDeviceChannel1Led1; - case 1: return CorsairLedId.CustomDeviceChannel2Led1; - case 2: return CorsairLedId.CustomDeviceChannel3Led1; - } - } - - return CorsairLedId.Invalid; - } - - private void AddSpecialParts(ICorsairRGBDevice device) - { - if (device.DeviceInfo.Model.Equals("K95 RGB Platinum", StringComparison.OrdinalIgnoreCase)) - device.AddSpecialDevicePart(new LightbarSpecialPart(device)); - } - - /// - public void ResetDevices() - { - if (IsInitialized) - try - { - _CUESDK.Reload(); - } - catch {/* shit happens */} + 0 => CorsairLedId.CustomDeviceChannel1Led1, + 1 => CorsairLedId.CustomDeviceChannel2Led1, + 2 => CorsairLedId.CustomDeviceChannel3Led1, + _ => CorsairLedId.Invalid + }; } private void Reset() { ProtocolDetails = null; - HasExclusiveAccess = false; - Devices = null; + Devices = Enumerable.Empty(); IsInitialized = false; } /// public void Dispose() { - try { UpdateTrigger?.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(); + try { _CUESDK.UnloadCUESDK(); } catch { /* at least we tried */ } } diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProviderLoader.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProviderLoader.cs deleted file mode 100644 index 4a1aa54..0000000 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - /// - /// Represents a device provider loaded used to dynamically load corsair devices into an application. - /// - public class CorsairDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => CorsairDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs index 5854623..0ea52b4 100644 --- a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs @@ -14,7 +14,7 @@ namespace RGB.NET.Devices.Corsair { #region Properties & Fields - private readonly Dictionary _idMapping = new Dictionary(); + private readonly Dictionary _idMapping = new(); #endregion @@ -42,15 +42,11 @@ namespace RGB.NET.Devices.Corsair { LedId ledId = referenceId + i; _idMapping.Add(ledId, DeviceInfo.ReferenceCorsairLed + i); - InitializeLed(ledId, new Rectangle(i * 10, 0, 10, 10)); + AddLed(ledId, new Point(i * 10, 0), new Size(10, 10)); } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Customs", $"{model}.xml"), null); } - - /// - protected override object CreateLedCustomData(LedId ledId) => _idMapping.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + + 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 664a6e6..ae1859a 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs @@ -40,11 +40,11 @@ namespace RGB.NET.Devices.Corsair { int structSize = Marshal.SizeOf(typeof(_CorsairLedColor)); IntPtr ptr = Marshal.AllocHGlobal(structSize * dataSet.Count); - IntPtr addPtr = new IntPtr(ptr.ToInt64()); + IntPtr addPtr = new(ptr.ToInt64()); foreach (KeyValuePair data in dataSet) { - _CorsairLedColor color = new _CorsairLedColor - { + _CorsairLedColor color = new() + { ledId = (int)data.Key, r = data.Value.GetR(), g = data.Value.GetG(), diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs b/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs index 3f66761..1bd2786 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs @@ -18,12 +18,12 @@ namespace RGB.NET.Devices.Corsair /// String containing version of SDK(like "1.0.0.1"). /// Always contains valid value even if there was no CUE found. /// - public string SdkVersion { get; } + public string? SdkVersion { get; } /// /// String containing version of CUE(like "1.0.0.1") or NULL if CUE was not found. /// - public string ServerVersion { get; } + public string? ServerVersion { get; } /// /// Integer that specifies version of protocol that is implemented by current SDK. diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs index ef12ad4..9dd74ea 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using RGB.NET.Core; -using RGB.NET.Devices.Corsair.Native; namespace RGB.NET.Devices.Corsair { @@ -27,13 +24,13 @@ namespace RGB.NET.Devices.Corsair /// Gets a dictionary containing all of the . /// // ReSharper disable once MemberCanBePrivate.Global - protected Dictionary InternalLedMapping { get; } = new Dictionary(); + 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; } + protected CorsairDeviceUpdateQueue? DeviceUpdateQueue { get; set; } #endregion @@ -45,7 +42,7 @@ namespace RGB.NET.Devices.Corsair /// 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; + public Led? this[CorsairLedId ledId] => InternalLedMapping.TryGetValue(ledId, out Led? led) ? led : null; #endregion @@ -75,14 +72,13 @@ namespace RGB.NET.Devices.Corsair foreach (Led led in LedMapping.Values) { - CorsairLedId ledId = (CorsairLedId)led.CustomData; - if (ledId != CorsairLedId.Invalid) + if (led.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid)) InternalLedMapping.Add(ledId, led); } if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } } @@ -94,7 +90,7 @@ namespace RGB.NET.Devices.Corsair /// protected override void UpdateLeds(IEnumerable ledsToUpdate) - => DeviceUpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid)))); + => DeviceUpdateQueue?.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid)))); /// public override void Dispose() diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs index 2e68418..5b579e8 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs @@ -37,11 +37,7 @@ namespace RGB.NET.Devices.Corsair /// public string Model { get; } - /// - public Uri Image { get; set; } - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + public object? LayoutMetadata { get; set; } /// /// Gets a flag that describes device capabilities. () @@ -64,7 +60,7 @@ namespace RGB.NET.Devices.Corsair this.CorsairDeviceIndex = deviceIndex; this.DeviceType = deviceType; this.CorsairDeviceType = nativeInfo.type; - this.Model = nativeInfo.model == IntPtr.Zero ? null : Regex.Replace(Marshal.PtrToStringAnsi(nativeInfo.model) ?? string.Empty, " ?DEMO", string.Empty, RegexOptions.IgnoreCase); + this.Model = nativeInfo.model == IntPtr.Zero ? string.Empty : Regex.Replace(Marshal.PtrToStringAnsi(nativeInfo.model) ?? string.Empty, " ?DEMO", string.Empty, RegexOptions.IgnoreCase); this.CapsMask = (CorsairDeviceCaps)nativeInfo.capsMask; DeviceName = GetUniqueModelName(modelCounter); @@ -95,9 +91,9 @@ namespace RGB.NET.Devices.Corsair private string GetUniqueModelName(Dictionary modelCounter) { - if (modelCounter.TryGetValue(Model, out int counter)) + if (modelCounter.TryGetValue(Model, out int _)) { - counter = ++modelCounter[Model]; + int counter = ++modelCounter[Model]; return $"{Manufacturer} {Model} {counter}"; } else diff --git a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs index 8152a2c..7a39b28 100644 --- a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs @@ -29,14 +29,11 @@ namespace RGB.NET.Devices.Corsair /// protected override void InitializeLayout() { - InitializeLed(LedId.Headset1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Headset2, new Rectangle(10, 0, 10, 10)); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Headsets", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + AddLed(LedId.Headset1, new Point(0, 0), new Size(10, 10)); + AddLed(LedId.Headset2, new Point(10, 0), new Size(10, 10)); } - /// - protected override object CreateLedCustomData(LedId ledId) => HeadsetIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + protected override object GetLedCustomData(LedId ledId) => HeadsetIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; #endregion } diff --git a/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs b/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs index d446f09..7448184 100644 --- a/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs +++ b/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Corsair { internal static class HeadsetIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.Headset1, CorsairLedId.LeftLogo }, { LedId.Headset2, CorsairLedId.RightLogo }, }; diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs index d7e28c9..966fc77 100644 --- a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs @@ -34,28 +34,33 @@ namespace RGB.NET.Devices.Corsair /// protected override void InitializeLayout() { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + if (nativeLedPositions == null) return; int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); IntPtr ptr = nativeLedPositions.pLedPosition; - List<_CorsairLedPosition> positions = new List<_CorsairLedPosition>(); + List<_CorsairLedPosition> positions = new(); for (int i = 0; i < nativeLedPositions.numberOfLed; i++) { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + _CorsairLedPosition? ledPosition = (_CorsairLedPosition?)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + if (ledPosition == null) continue; + ptr = new IntPtr(ptr.ToInt64() + structSize); positions.Add(ledPosition); } Dictionary mapping = HeadsetStandIdMapping.DEFAULT.SwapKeyValue(); foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.LedId)) - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\HeadsetStands", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + { + LedId ledId = mapping.TryGetValue(ledPosition.LedId, out LedId id) ? id : LedId.Invalid; + Rectangle rectangle = ledPosition.ToRectangle(); + AddLed(ledId, rectangle.Location, rectangle.Size); + } } /// - protected override object CreateLedCustomData(LedId ledId) => HeadsetStandIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + protected override object GetLedCustomData(LedId ledId) => HeadsetStandIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; #endregion } diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs b/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs index 619f823..4987118 100644 --- a/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs +++ b/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Corsair { internal static class HeadsetStandIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.HeadsetStand1, CorsairLedId.HeadsetStandZone1 }, { LedId.HeadsetStand2, CorsairLedId.HeadsetStandZone2 }, { LedId.HeadsetStand3, CorsairLedId.HeadsetStandZone3 }, diff --git a/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs b/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs index 2bc44f5..936d560 100644 --- a/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs +++ b/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs @@ -5,6 +5,9 @@ namespace RGB.NET.Devices.Corsair { internal static class DictionaryExtension { - public static Dictionary SwapKeyValue(this Dictionary dictionary) => dictionary.ToDictionary(x => x.Value, x => x.Key); + public static Dictionary SwapKeyValue(this Dictionary dictionary) + where TKey : notnull + where TValue : notnull + => dictionary.ToDictionary(x => x.Value, x => x.Key); } } diff --git a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs index c1bb52a..60febaa 100644 --- a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs @@ -33,7 +33,8 @@ namespace RGB.NET.Devices.Corsair /// protected override void InitializeLayout() { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + if (nativeLedPositions == null) return; int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); IntPtr ptr = nativeLedPositions.pLedPosition; @@ -41,19 +42,18 @@ namespace RGB.NET.Devices.Corsair Dictionary mapping = KeyboardIdMapping.DEFAULT.SwapKeyValue(); for (int i = 0; i < nativeLedPositions.numberOfLed; i++) { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); + _CorsairLedPosition? ledPosition = (_CorsairLedPosition?)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + if (ledPosition == null) continue; + + LedId ledId = mapping.TryGetValue(ledPosition.LedId, out LedId id) ? id : LedId.Invalid; + Rectangle rectangle = ledPosition.ToRectangle(); + AddLed(ledId, rectangle.Location, rectangle.Size); ptr = new IntPtr(ptr.ToInt64() + structSize); } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Corsair\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - DeviceInfo.LogicalLayout.ToString()); } - /// - protected override object CreateLedCustomData(LedId ledId) => KeyboardIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + protected override object GetLedCustomData(LedId ledId) => KeyboardIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; #endregion } diff --git a/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs b/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs index 547cfef..d7855f6 100644 --- a/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs +++ b/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Corsair { internal static class KeyboardIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.Invalid, CorsairLedId.Invalid }, { LedId.Logo, CorsairLedId.Logo }, { LedId.Keyboard_Escape, CorsairLedId.Escape }, diff --git a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs index 836e055..f174b8c 100644 --- a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs @@ -33,7 +33,8 @@ namespace RGB.NET.Devices.Corsair /// protected override void InitializeLayout() { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + if (nativeLedPositions == null) return; int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); IntPtr ptr = nativeLedPositions.pLedPosition; @@ -41,18 +42,18 @@ namespace RGB.NET.Devices.Corsair Dictionary mapping = MemoryIdMapping.DEFAULT.SwapKeyValue(); for (int i = 0; i < nativeLedPositions.numberOfLed; i++) { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); + _CorsairLedPosition? ledPosition = (_CorsairLedPosition?)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + if (ledPosition == null) continue; + + LedId ledId = mapping.TryGetValue(ledPosition.LedId, out LedId id) ? id : LedId.Invalid; + Rectangle rectangle = ledPosition.ToRectangle(); + AddLed(ledId, rectangle.Location, rectangle.Size); ptr = new IntPtr(ptr.ToInt64() + structSize); } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Memory", $"{model}.xml"), null); } - /// - protected override object CreateLedCustomData(LedId ledId) => MemoryIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + protected override object GetLedCustomData(LedId ledId) => MemoryIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; #endregion } diff --git a/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs b/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs index b7d7db4..50750cd 100644 --- a/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs +++ b/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Corsair { internal static class MemoryIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.Invalid, CorsairLedId.Invalid }, { LedId.DRAM1, CorsairLedId.DRAM1 }, { LedId.DRAM2, CorsairLedId.DRAM2 }, diff --git a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs index 292d7d8..f9bfa42 100644 --- a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs @@ -33,32 +33,29 @@ namespace RGB.NET.Devices.Corsair switch (DeviceInfo.PhysicalLayout) { case CorsairPhysicalMouseLayout.Zones1: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); + AddLed(LedId.Mouse1, new Point(0, 0), new Size(10, 10)); break; case CorsairPhysicalMouseLayout.Zones2: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Mouse2, new Rectangle(10, 0, 10, 10)); + AddLed(LedId.Mouse1, new Point(0, 0), new Size(10, 10)); + AddLed(LedId.Mouse2, new Point(10, 0), new Size(10, 10)); break; case CorsairPhysicalMouseLayout.Zones3: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Mouse2, new Rectangle(10, 0, 10, 10)); - InitializeLed(LedId.Mouse3, new Rectangle(20, 0, 10, 10)); + AddLed(LedId.Mouse1, new Point(0, 0), new Size(10, 10)); + AddLed(LedId.Mouse2, new Point(10, 0), new Size(10, 10)); + AddLed(LedId.Mouse3, new Point(20, 0), new Size(10, 10)); break; case CorsairPhysicalMouseLayout.Zones4: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Mouse2, new Rectangle(10, 0, 10, 10)); - InitializeLed(LedId.Mouse3, new Rectangle(20, 0, 10, 10)); - InitializeLed(LedId.Mouse4, new Rectangle(30, 0, 10, 10)); + AddLed(LedId.Mouse1, new Point(0, 0), new Size(10, 10)); + AddLed(LedId.Mouse2, new Point(10, 0), new Size(10, 10)); + AddLed(LedId.Mouse3, new Point(20, 0), new Size(10, 10)); + AddLed(LedId.Mouse4, new Point(30, 0), new Size(10, 10)); break; default: throw new RGBDeviceException($"Can't initialize mouse with layout '{DeviceInfo.PhysicalLayout}'"); } - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Mice", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); } - /// - protected override object CreateLedCustomData(LedId ledId) + protected override object GetLedCustomData(LedId ledId) { if (string.Equals(DeviceInfo.Model, "GLAIVE RGB", StringComparison.OrdinalIgnoreCase)) return MouseIdMapping.GLAIVE.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; diff --git a/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs b/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs index 00dea5b..95982fd 100644 --- a/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs +++ b/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Corsair { internal static class MouseIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.Mouse1, CorsairLedId.B1 }, { LedId.Mouse2, CorsairLedId.B2 }, { LedId.Mouse3, CorsairLedId.B3 }, @@ -15,15 +15,15 @@ namespace RGB.NET.Devices.Corsair { LedId.Mouse6, CorsairLedId.B6 }, }; - internal static readonly Dictionary GLAIVE = new Dictionary - { + internal static readonly Dictionary GLAIVE = new() + { { LedId.Mouse1, CorsairLedId.B1 }, { LedId.Mouse2, CorsairLedId.B2 }, { LedId.Mouse3, CorsairLedId.B5 }, }; - internal static readonly Dictionary M65_RGB_ELITE = new Dictionary - { + internal static readonly Dictionary M65_RGB_ELITE = new() + { { LedId.Mouse1, CorsairLedId.B1 }, { LedId.Mouse2, CorsairLedId.B3 }, }; diff --git a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs index b245ca1..00b526d 100644 --- a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs @@ -34,28 +34,32 @@ namespace RGB.NET.Devices.Corsair /// protected override void InitializeLayout() { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + if (nativeLedPositions == null) return; int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); IntPtr ptr = nativeLedPositions.pLedPosition; - List<_CorsairLedPosition> positions = new List<_CorsairLedPosition>(); + List<_CorsairLedPosition> positions = new(); for (int i = 0; i < nativeLedPositions.numberOfLed; i++) { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + _CorsairLedPosition? ledPosition = (_CorsairLedPosition?)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + if (ledPosition == null) continue; + ptr = new IntPtr(ptr.ToInt64() + structSize); positions.Add(ledPosition); } Dictionary mapping = MousepadIdMapping.DEFAULT.SwapKeyValue(); foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.LedId)) - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Mousepads", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + { + LedId ledId = mapping.TryGetValue(ledPosition.LedId, out LedId id) ? id : LedId.Invalid; + Rectangle rectangle = ledPosition.ToRectangle(); + AddLed(ledId, rectangle.Location, rectangle.Size); + } } - /// - protected override object CreateLedCustomData(LedId ledId) => MousepadIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + protected override object GetLedCustomData(LedId ledId) => MousepadIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; #endregion } diff --git a/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs b/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs index 3b49ad6..a415df6 100644 --- a/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs +++ b/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Corsair { internal static class MousepadIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.Mousepad1, CorsairLedId.Zone1 }, { LedId.Mousepad2, CorsairLedId.Zone2 }, { LedId.Mousepad3, CorsairLedId.Zone3 }, diff --git a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs index 9b217e4..e8a0656 100644 --- a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs +++ b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs @@ -16,12 +16,7 @@ namespace RGB.NET.Devices.Corsair.Native #region Libary Management private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - + /// /// Reloads the SDK. /// @@ -37,7 +32,7 @@ namespace RGB.NET.Devices.Corsair.Native // HACK: Load library at runtime to support both, x86 and x64 with one managed dll List possiblePathList = Environment.Is64BitProcess ? CorsairDeviceProvider.PossibleX64NativePaths : CorsairDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); _dllHandle = LoadLibrary(dllPath); @@ -80,18 +75,18 @@ namespace RGB.NET.Devices.Corsair.Native #region Pointers - private static CorsairSetLedsColorsBufferByDeviceIndexPointer _corsairSetLedsColorsBufferByDeviceIndexPointer; - private static CorsairSetLedsColorsFlushBufferPointer _corsairSetLedsColorsFlushBufferPointer; - private static CorsairGetLedsColorsByDeviceIndexPointer _corsairGetLedsColorsByDeviceIndexPointer; - private static CorsairSetLayerPriorityPointer _corsairSetLayerPriorityPointer; - private static CorsairGetDeviceCountPointer _corsairGetDeviceCountPointer; - private static CorsairGetDeviceInfoPointer _corsairGetDeviceInfoPointer; - private static CorsairGetLedIdForKeyNamePointer _corsairGetLedIdForKeyNamePointer; - private static CorsairGetLedPositionsByDeviceIndexPointer _corsairGetLedPositionsByDeviceIndexPointer; - private static CorsairRequestControlPointer _corsairRequestControlPointer; - private static CorsairReleaseControlPointer _corsairReleaseControlPointer; - private static CorsairPerformProtocolHandshakePointer _corsairPerformProtocolHandshakePointer; - private static CorsairGetLastErrorPointer _corsairGetLastErrorPointer; + private static CorsairSetLedsColorsBufferByDeviceIndexPointer? _corsairSetLedsColorsBufferByDeviceIndexPointer; + private static CorsairSetLedsColorsFlushBufferPointer? _corsairSetLedsColorsFlushBufferPointer; + private static CorsairGetLedsColorsByDeviceIndexPointer? _corsairGetLedsColorsByDeviceIndexPointer; + private static CorsairSetLayerPriorityPointer? _corsairSetLayerPriorityPointer; + private static CorsairGetDeviceCountPointer? _corsairGetDeviceCountPointer; + private static CorsairGetDeviceInfoPointer? _corsairGetDeviceInfoPointer; + private static CorsairGetLedIdForKeyNamePointer? _corsairGetLedIdForKeyNamePointer; + private static CorsairGetLedPositionsByDeviceIndexPointer? _corsairGetLedPositionsByDeviceIndexPointer; + private static CorsairRequestControlPointer? _corsairRequestControlPointer; + private static CorsairReleaseControlPointer? _corsairReleaseControlPointer; + private static CorsairPerformProtocolHandshakePointer? _corsairPerformProtocolHandshakePointer; + private static CorsairGetLastErrorPointer? _corsairGetLastErrorPointer; #endregion @@ -144,68 +139,70 @@ namespace RGB.NET.Devices.Corsair.Native /// and follows after one or more calls of CorsairSetLedsColorsBufferByDeviceIndex to set the LEDs buffer. /// This function does not take logical layout into account. /// - internal static bool CorsairSetLedsColorsBufferByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) => _corsairSetLedsColorsBufferByDeviceIndexPointer(deviceIndex, size, ledsColors); + internal static bool CorsairSetLedsColorsBufferByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) + => (_corsairSetLedsColorsBufferByDeviceIndexPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex, size, ledsColors); /// /// CUE-SDK: writes to the devices LEDs colors buffer which is previously filled by the CorsairSetLedsColorsBufferByDeviceIndex function. /// This function executes synchronously, if you are concerned about delays consider using CorsairSetLedsColorsFlushBufferAsync /// - internal static bool CorsairSetLedsColorsFlushBuffer() => _corsairSetLedsColorsFlushBufferPointer(); + internal static bool CorsairSetLedsColorsFlushBuffer() => (_corsairSetLedsColorsFlushBufferPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(); /// /// CUE-SDK: get current color for the list of requested LEDs. /// The color should represent the actual state of the hardware LED, which could be a combination of SDK and/or CUE input. /// This function works for keyboard, mouse, mousemat, headset, headset stand and DIY-devices. /// - internal static bool CorsairGetLedsColorsByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) => _corsairGetLedsColorsByDeviceIndexPointer(deviceIndex, size, ledsColors); + internal static bool CorsairGetLedsColorsByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) + => (_corsairGetLedsColorsByDeviceIndexPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex, size, ledsColors); /// /// CUE-SDK: set layer priority for this shared client. /// By default CUE has priority of 127 and all shared clients have priority of 128 if they don’t call this function. /// Layers with higher priority value are shown on top of layers with lower priority. /// - internal static bool CorsairSetLayerPriority(int priority) => _corsairSetLayerPriorityPointer(priority); + internal static bool CorsairSetLayerPriority(int priority) => (_corsairSetLayerPriorityPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(priority); /// /// CUE-SDK: returns number of connected Corsair devices that support lighting control. /// - internal static int CorsairGetDeviceCount() => _corsairGetDeviceCountPointer(); + internal static int CorsairGetDeviceCount() => (_corsairGetDeviceCountPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(); /// /// CUE-SDK: returns information about device at provided index. /// - internal static IntPtr CorsairGetDeviceInfo(int deviceIndex) => _corsairGetDeviceInfoPointer(deviceIndex); + internal static IntPtr CorsairGetDeviceInfo(int deviceIndex) => (_corsairGetDeviceInfoPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex); /// /// CUE-SDK: provides list of keyboard or mousepad LEDs with their physical positions. /// - internal static IntPtr CorsairGetLedPositionsByDeviceIndex(int deviceIndex) => _corsairGetLedPositionsByDeviceIndexPointer(deviceIndex); + internal static IntPtr CorsairGetLedPositionsByDeviceIndex(int deviceIndex) => (_corsairGetLedPositionsByDeviceIndexPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(deviceIndex); /// /// CUE-SDK: retrieves led id for key name taking logical layout into account. /// - internal static CorsairLedId CorsairGetLedIdForKeyName(char keyName) => _corsairGetLedIdForKeyNamePointer(keyName); + internal static CorsairLedId CorsairGetLedIdForKeyName(char keyName) => (_corsairGetLedIdForKeyNamePointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(keyName); /// /// CUE-SDK: requestes control using specified access mode. /// By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control. /// - internal static bool CorsairRequestControl(CorsairAccessMode accessMode) => _corsairRequestControlPointer(accessMode); + internal static bool CorsairRequestControl(CorsairAccessMode accessMode) => (_corsairRequestControlPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(accessMode); /// /// CUE-SDK: releases previously requested control for specified access mode. /// - internal static bool CorsairReleaseControl(CorsairAccessMode accessMode) => _corsairReleaseControlPointer(accessMode); + internal static bool CorsairReleaseControl(CorsairAccessMode accessMode) => (_corsairReleaseControlPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(accessMode); /// /// CUE-SDK: checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE. /// - internal static _CorsairProtocolDetails CorsairPerformProtocolHandshake() => _corsairPerformProtocolHandshakePointer(); + internal static _CorsairProtocolDetails CorsairPerformProtocolHandshake() => (_corsairPerformProtocolHandshakePointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(); /// /// CUE-SDK: returns last error that occured while using any of Corsair* functions. /// - internal static CorsairError CorsairGetLastError() => _corsairGetLastErrorPointer(); + internal static CorsairError CorsairGetLastError() => (_corsairGetLastErrorPointer ?? throw new RGBDeviceException("The Corsair-SDK is not initialized.")).Invoke(); // ReSharper restore EventExceptionNotDocumented diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs index d584d73..418e9f6 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs @@ -47,6 +47,6 @@ namespace RGB.NET.Devices.Corsair.Native /// /// CUE-SDK: structure that describes channels of the DIY-devices /// - internal _CorsairChannelsInfo channels; + internal _CorsairChannelsInfo? channels; } } diff --git a/RGB.NET.Devices.Corsair/SpecialParts/LightbarSpecialPart.cs b/RGB.NET.Devices.Corsair/SpecialParts/LightbarSpecialPart.cs deleted file mode 100644 index 705bac0..0000000 --- a/RGB.NET.Devices.Corsair/SpecialParts/LightbarSpecialPart.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ReSharper disable UnusedMember.Global -// ReSharper disable MemberCanBePrivate.Global - -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - /// - /// - /// Represents a lightbar attached to a - /// - public class LightbarSpecialPart : IRGBDeviceSpecialPart - { - #region Properties & Fields - - private List _leds; - /// - /// Gets a readonly collection of all of this . - /// - public IEnumerable Leds => new ReadOnlyCollection(_leds); - - private List _left; - /// - /// Gets a readonly collection of all in the left half of this . - /// - public IEnumerable Left => new ReadOnlyCollection(_left); - - private List _right; - /// - /// Gets a readonly collection of all in the right half of this . - /// - public IEnumerable Right => new ReadOnlyCollection(_right); - - /// - /// Gets the Center of this . - /// - public Led Center { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The device associated with this . - public LightbarSpecialPart(IRGBDevice device) - { - _leds = device.Where(led => ((CorsairLedId)led.CustomData >= CorsairLedId.Lightbar1) && ((CorsairLedId)led.CustomData <= CorsairLedId.Lightbar19)).ToList(); - _left = _leds.Where(led => (CorsairLedId)led.CustomData < CorsairLedId.Lightbar10).ToList(); - _right = _leds.Where(led => (CorsairLedId)led.CustomData > CorsairLedId.Lightbar10).ToList(); - Center = _leds.FirstOrDefault(led => (CorsairLedId)led.CustomData == CorsairLedId.Lightbar10); - } - - #endregion - - #region Methods - - /// - /// - /// Returns an enumerator that iterates over all of the . - /// - /// An enumerator for all of the . - public IEnumerator GetEnumerator() => _leds.GetEnumerator(); - - /// - /// - /// Returns an enumerator that iterates over all of the . - /// - /// An enumerator for all of the . - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - #endregion - } -} diff --git a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs index a151778..4720e1e 100644 --- a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs +++ b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.DMX.E131; @@ -17,7 +18,7 @@ namespace RGB.NET.Devices.DMX { #region Properties & Fields - private static DMXDeviceProvider _instance; + private static DMXDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -27,20 +28,17 @@ namespace RGB.NET.Devices.DMX public bool IsInitialized { get; private set; } /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// Gets a list of all defined device-definitions. /// - public List DeviceDefinitions { get; } = new List(); + public List DeviceDefinitions { get; } = new(); /// /// The used to trigger the updates for dmx devices. /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + public DeviceUpdateTrigger UpdateTrigger { get; } #endregion @@ -69,7 +67,7 @@ namespace RGB.NET.Devices.DMX public void AddDeviceDefinition(IDMXDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; @@ -87,7 +85,7 @@ namespace RGB.NET.Devices.DMX { if (e131DMXDeviceDefinition.Leds.Count > 0) { - E131Device device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds); + E131Device device = new(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds); device.Initialize(UpdateTrigger); devices.Add(device); } @@ -110,15 +108,16 @@ namespace RGB.NET.Devices.DMX return true; } - /// - public void ResetDevices() - { } - /// public void Dispose() { - try { UpdateTrigger?.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/DMXDeviceProviderLoader.cs b/RGB.NET.Devices.DMX/DMXDeviceProviderLoader.cs deleted file mode 100644 index 193cc6b..0000000 --- a/RGB.NET.Devices.DMX/DMXDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.DMX -{ - /// - /// Represents a device provider loaded used to dynamically load DMX devices into an application. - /// - public class DMXDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => DMXDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs b/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs index 8e7fb9b..ca37238 100644 --- a/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs +++ b/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs @@ -45,7 +45,7 @@ namespace RGB.NET.Devices.DMX.E131 /// Gets or sets the CID of the device (null will generate a random CID) /// // ReSharper disable once InconsistentNaming - public byte[] CID { get; set; } + public byte[]? CID { get; set; } /// /// Gets or sets the universe the device belongs to. @@ -55,7 +55,7 @@ namespace RGB.NET.Devices.DMX.E131 /// /// Gets or sets the led-mappings used to create the device. /// - public Dictionary getValueFunc)>> Leds { get; } = new Dictionary getValueFunc)>>(); + public Dictionary getValueFunc)>> Leds { get; } = new(); #endregion diff --git a/RGB.NET.Devices.DMX/E131/E131Device.cs b/RGB.NET.Devices.DMX/E131/E131Device.cs index a4a69d2..edb078e 100644 --- a/RGB.NET.Devices.DMX/E131/E131Device.cs +++ b/RGB.NET.Devices.DMX/E131/E131Device.cs @@ -17,7 +17,7 @@ namespace RGB.NET.Devices.DMX.E131 private readonly Dictionary getValueFunc)>> _ledMappings; - private E131UpdateQueue _updateQueue; + private E131UpdateQueue? _updateQueue; #endregion @@ -38,13 +38,11 @@ namespace RGB.NET.Devices.DMX.E131 { int count = 0; foreach (LedId id in _ledMappings.Keys) - InitializeLed(id, new Rectangle((count++) * 10, 0, 10, 10)); - - //TODO DarthAffe 18.02.2018: Allow to load a layout. + AddLed(id, new Point((count++) * 10, 0), new Size(10, 10)); if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } @@ -54,10 +52,11 @@ namespace RGB.NET.Devices.DMX.E131 } /// - protected override object CreateLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]); + 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)); + protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); /// public override void Dispose() diff --git a/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs b/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs index eb486a4..dc5c33e 100644 --- a/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs +++ b/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs @@ -33,11 +33,7 @@ namespace RGB.NET.Devices.DMX.E131 /// public string Model { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } /// /// The hostname of the device. @@ -70,15 +66,17 @@ namespace RGB.NET.Devices.DMX.E131 this.Model = deviceDefinition.Model; this.Hostname = deviceDefinition.Hostname; this.Port = deviceDefinition.Port; - this.CID = deviceDefinition.CID; this.Universe = deviceDefinition.Universe; + byte[]? cid = deviceDefinition.CID; if ((CID == null) || (CID.Length != CID_LENGTH)) { CID = new byte[CID_LENGTH]; new Random().NextBytes(CID); } + CID = cid!; + DeviceName = $"{Manufacturer} {Model}"; } diff --git a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs index 24a82fe..66ec439 100644 --- a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs +++ b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs @@ -4,7 +4,9 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using RGB.NET.Core; +using RGB.NET.Layout; namespace RGB.NET.Devices.Debug { @@ -16,7 +18,7 @@ namespace RGB.NET.Devices.Debug { #region Properties & Fields - private static DebugDeviceProvider _instance; + private static DebugDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -26,13 +28,9 @@ namespace RGB.NET.Devices.Debug public bool IsInitialized { get; private set; } /// - public IEnumerable Devices { get; private set; } + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); - /// - public bool HasExclusiveAccess { get; private set; } - - private List<(string layout, string imageLayout, Action> updateLedsAction)> _fakeDeviceDefinitions - = new List<(string layout, string imageLayout, Action> updateLedsAction)>(); + private List<(IDeviceLayout layout, string imageLayout, Action>? updateLedsAction)> _fakeDeviceDefinitions = new(); #endregion @@ -58,7 +56,7 @@ namespace RGB.NET.Devices.Debug /// The path of the layout file to be used. /// The image-layout to load. /// A action emulating led-updates. - public void AddFakeDeviceDefinition(string layout, string imageLayout, Action> updateLedsAction = null) + public void AddFakeDeviceDefinition(IDeviceLayout layout, string imageLayout, Action>? updateLedsAction = null) => _fakeDeviceDefinitions.Add((layout, imageLayout, updateLedsAction)); /// @@ -67,18 +65,15 @@ namespace RGB.NET.Devices.Debug public void ClearFakeDeviceDefinitions() => _fakeDeviceDefinitions.Clear(); /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false) { IsInitialized = false; try { - HasExclusiveAccess = exclusiveAccessIfPossible; - - List devices = new List(); - foreach ((string layout, string imageLayout, Action> updateLedsAction) in _fakeDeviceDefinitions) + List devices = new(); + foreach ((IDeviceLayout layout, string imageLayout, Action>? updateLedsAction) in _fakeDeviceDefinitions) { - DebugRGBDevice device = new DebugRGBDevice(layout, updateLedsAction); - device.Initialize(layout, imageLayout); + DebugRGBDevice device = new(layout, updateLedsAction); devices.Add(device); } diff --git a/RGB.NET.Devices.Debug/DebugDeviceProviderLoader.cs b/RGB.NET.Devices.Debug/DebugDeviceProviderLoader.cs deleted file mode 100644 index 819a084..0000000 --- a/RGB.NET.Devices.Debug/DebugDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Debug -{ - /// - /// Represents a device provider loaded used to dynamically load debug devices into an application. - /// - public class DebugDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => DebugDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Debug/DebugRGBDevice.cs b/RGB.NET.Devices.Debug/DebugRGBDevice.cs index 7d787d7..b87c3d6 100644 --- a/RGB.NET.Devices.Debug/DebugRGBDevice.cs +++ b/RGB.NET.Devices.Debug/DebugRGBDevice.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using RGB.NET.Core; -using RGB.NET.Core.Layout; +using RGB.NET.Layout; namespace RGB.NET.Devices.Debug { @@ -16,12 +16,9 @@ namespace RGB.NET.Devices.Debug /// public override DebugRGBDeviceInfo DeviceInfo { get; } - /// - /// Gets the path of the layout used to mock this - /// - public string LayoutPath { get; } - - private Action> _updateLedsAction; + public IDeviceLayout Layout { get; } + + private Action>? _updateLedsAction; #endregion @@ -29,21 +26,20 @@ namespace RGB.NET.Devices.Debug /// /// Internal constructor of . /// - internal DebugRGBDevice(string layoutPath, Action> updateLedsAction = null) + internal DebugRGBDevice(IDeviceLayout layout, Action>? updateLedsAction = null) { - this.LayoutPath = layoutPath; + this.Layout = layout; this._updateLedsAction = updateLedsAction; - DeviceLayout layout = DeviceLayout.Load(layoutPath); - DeviceInfo = new DebugRGBDeviceInfo(layout.Type, layout.Vendor, layout.Model, layout.Lighting); + DeviceInfo = new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData); + + Layout.ApplyTo(this); } #endregion #region Methods - internal void Initialize(string layoutPath, string imageLayout) => ApplyLayoutFromFile(layoutPath, imageLayout, true); - /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateLedsAction?.Invoke(ledsToUpdate); diff --git a/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs b/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs index d7f5a74..b411f91 100644 --- a/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Debug { @@ -23,11 +22,7 @@ namespace RGB.NET.Devices.Debug /// public string Model { get; } - /// - public RGBDeviceLighting Lighting { get; } - - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } #endregion @@ -39,15 +34,14 @@ namespace RGB.NET.Devices.Debug /// The of the device. /// The manufacturer of the device. /// The model of the device. - /// The of the device. - internal DebugRGBDeviceInfo(RGBDeviceType deviceType, string manufacturer, string model, RGBDeviceLighting lighting, string deviceName = null) + internal DebugRGBDeviceInfo(RGBDeviceType deviceType, string manufacturer, string model, object? customData) { this.DeviceType = deviceType; this.Manufacturer = manufacturer; this.Model = model; - this.Lighting = lighting; + this.LayoutMetadata = customData; - DeviceName = deviceName ?? $"{Manufacturer} {Model}"; + DeviceName = $"{Manufacturer} {Model}"; } #endregion diff --git a/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj b/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj index 68768fc..646da10 100644 --- a/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj +++ b/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj @@ -52,5 +52,6 @@ + \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs index 74104fa..eacb6b6 100644 --- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs @@ -1,5 +1,4 @@ -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Logitech { @@ -23,7 +22,7 @@ namespace RGB.NET.Devices.Logitech /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue UpdateQueue { get; set; } + protected UpdateQueue? UpdateQueue { get; set; } #endregion @@ -45,31 +44,11 @@ namespace RGB.NET.Devices.Logitech /// /// Initializes the device. /// - public void Initialize(UpdateQueue updateQueue) + public virtual void Initialize(UpdateQueue updateQueue) { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - UpdateQueue = updateQueue; } - /// - /// Initializes the and of the device. - /// - protected virtual void InitializeLayout() - { - if (!(DeviceInfo is LogitechRGBDeviceInfo info)) return; - - string layout = info.ImageLayout; - string layoutPath = info.LayoutPath; - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Logitech", $"{layoutPath}.xml"), layout, true); - } - /// public override void Dispose() { diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs index 1a9bce7..bdf0614 100644 --- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Logitech { @@ -23,24 +22,8 @@ namespace RGB.NET.Devices.Logitech /// public string Model { get; } - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } - /// - public RGBDeviceLighting Lighting - { - get - { - if (DeviceCaps.HasFlag(LogitechDeviceCaps.PerKeyRGB)) - return RGBDeviceLighting.Key; - - if (DeviceCaps.HasFlag(LogitechDeviceCaps.DeviceRGB)) - return RGBDeviceLighting.Device; - - return RGBDeviceLighting.None; - } - } - /// /// Gets a flag that describes device capabilities. () /// @@ -51,16 +34,6 @@ namespace RGB.NET.Devices.Logitech /// public int Zones { get; } - /// - /// Gets the layout used to decide which images to load. - /// - internal string ImageLayout { get; } - - /// - /// Gets the path/name of the layout-file. - /// - internal string LayoutPath { get; } - #endregion #region Constructors @@ -74,15 +47,12 @@ namespace RGB.NET.Devices.Logitech /// The amount of zones the device is able to control. /// The layout used to decide which images to load. /// The path/name of the layout-file. - internal LogitechRGBDeviceInfo(RGBDeviceType deviceType, string model, LogitechDeviceCaps deviceCaps, - int zones, string imageLayout, string layoutPath) + internal LogitechRGBDeviceInfo(RGBDeviceType deviceType, string model, LogitechDeviceCaps deviceCaps, int zones) { this.DeviceType = deviceType; this.Model = model; this.DeviceCaps = deviceCaps; this.Zones = zones; - this.ImageLayout = imageLayout; - this.LayoutPath = layoutPath; DeviceName = $"{Manufacturer} {Model}"; } diff --git a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs index 5684fd7..800cc3e 100644 --- a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs +++ b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs @@ -5,83 +5,81 @@ using RGB.NET.Core; namespace RGB.NET.Devices.Logitech.HID { - //TODO DarthAffe 04.02.2017: Rewrite this once the SDK supports per-device lighting to get all the devices connected. internal static class DeviceChecker { #region Constants private const int VENDOR_ID = 0x046D; - //TODO DarthAffe 14.11.2017: Add devices - private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> PER_KEY_DEVICES - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> - { - ("G910", RGBDeviceType.Keyboard, 0xC32B, 0, "DE", @"Keyboards\G910\UK"), //TODO DarthAffe 15.11.2017: Somehow detect the current layout - ("G910v2", RGBDeviceType.Keyboard, 0xC335, 0, "DE", @"Keyboards\G910\UK"), - ("G915", RGBDeviceType.Keyboard, 0xC541, 0, "DE", @"Keyboards\G915\UK"), - ("G810", RGBDeviceType.Keyboard, 0xC337, 0, "DE", @"Keyboards\G810\UK"), - ("G810", RGBDeviceType.Keyboard, 0xC331, 0, "DE", @"Keyboards\G810\UK"), - ("G610", RGBDeviceType.Keyboard, 0xC333, 0, "DE", @"Keyboards\G610\UK"), - ("G512", RGBDeviceType.Keyboard, 0xC33C, 0, "DE", @"Keyboards\G512\UK"), - ("G512 SE", RGBDeviceType.Keyboard, 0xC342, 0, "DE", @"Keyboards\G512SE\UK"), - ("G410", RGBDeviceType.Keyboard, 0xC330, 0, "DE", @"Keyboards\G410\UK"), - ("G213", RGBDeviceType.Keyboard, 0xC336, 0, "DE", @"Keyboards\G213\UK"), - ("Pro", RGBDeviceType.Keyboard, 0xC339, 0, "DE", @"Keyboards\Pro\UK"), - ("G915 TKL", RGBDeviceType.Keyboard, 0xC343, 0, "DE", @"Keyboards\G915TKL\UK"), - ("Lightspeed Keyboard Dongle", RGBDeviceType.Keyboard, 0xC545, 0, "DE", @"Keyboards\G915\UK"), - }; + private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones)> PER_KEY_DEVICES + = new() + { + ("G910", RGBDeviceType.Keyboard, 0xC32B, 0), + ("G910v2", RGBDeviceType.Keyboard, 0xC335, 0), + ("G915", RGBDeviceType.Keyboard, 0xC541, 0), + ("G810", RGBDeviceType.Keyboard, 0xC337, 0), + ("G810", RGBDeviceType.Keyboard, 0xC331, 0), + ("G610", RGBDeviceType.Keyboard, 0xC333, 0), + ("G512", RGBDeviceType.Keyboard, 0xC33C, 0), + ("G512 SE", RGBDeviceType.Keyboard, 0xC342, 0), + ("G410", RGBDeviceType.Keyboard, 0xC330, 0), + ("G213", RGBDeviceType.Keyboard, 0xC336, 0), + ("Pro", RGBDeviceType.Keyboard, 0xC339, 0), + ("G915 TKL", RGBDeviceType.Keyboard, 0xC343, 0), + ("Lightspeed Keyboard Dongle", RGBDeviceType.Keyboard, 0xC545, 0), + }; - private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> PER_DEVICE_DEVICES - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> - { - ("G19", RGBDeviceType.Keyboard, 0xC228, 0, "DE", @"Keyboards\G19\UK"), - ("G19s", RGBDeviceType.Keyboard, 0xC229, 0, "DE", @"Keyboards\G19s\UK"), - ("G600", RGBDeviceType.Mouse, 0xC24A, 0, "default", @"Mice\G600"), - ("G300s", RGBDeviceType.Mouse, 0xC246, 0, "default", @"Mice\G300s"), - ("G510", RGBDeviceType.Keyboard, 0xC22D, 0, "DE", @"Keyboards\G510\UK"), - ("G510s", RGBDeviceType.Keyboard, 0xC22E, 0, "DE", @"Keyboards\G510s\UK"), - ("G13", RGBDeviceType.Keypad, 0xC21C, 0, "DE", @"Keypads\G13\UK"), - ("G110", RGBDeviceType.Keyboard, 0xC22B, 0, "DE", @"Keyboards\G110\UK"), - ("G710+", RGBDeviceType.Keyboard, 0xC24D, 0, "DE", @"Keyboards\G710+\UK"), - ("G105", RGBDeviceType.Keyboard, 0xC248, 0, "DE", @"Keyboards\G105\UK"), - ("G15", RGBDeviceType.Keyboard, 0xC222, 0, "DE", @"Keyboards\G15\UK"), - ("G11", RGBDeviceType.Keyboard, 0xC225, 0, "DE", @"Keyboards\G11\UK"), - }; + private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones)> PER_DEVICE_DEVICES + = new() + { + ("G19", RGBDeviceType.Keyboard, 0xC228, 0), + ("G19s", RGBDeviceType.Keyboard, 0xC229, 0), + ("G600", RGBDeviceType.Mouse, 0xC24A, 0), + ("G300s", RGBDeviceType.Mouse, 0xC246, 0), + ("G510", RGBDeviceType.Keyboard, 0xC22D, 0), + ("G510s", RGBDeviceType.Keyboard, 0xC22E, 0), + ("G13", RGBDeviceType.Keypad, 0xC21C, 0), + ("G110", RGBDeviceType.Keyboard, 0xC22B, 0), + ("G710+", RGBDeviceType.Keyboard, 0xC24D, 0), + ("G105", RGBDeviceType.Keyboard, 0xC248, 0), + ("G15", RGBDeviceType.Keyboard, 0xC222, 0), + ("G11", RGBDeviceType.Keyboard, 0xC225, 0), + }; - private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> ZONE_DEVICES - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> - { - ("G213", RGBDeviceType.Keyboard, 0xC336, 5, "default", @"Keyboards\G213"), - ("G903", RGBDeviceType.Mouse, 0xC086, 2, "default", @"Mice\G903"), - ("Lightspeed Mouse Dongle", RGBDeviceType.Mouse, 0xC539, 2, "default", @"Mice\G900"), - ("G703", RGBDeviceType.Mouse, 0xC087, 2, "default", @"Mice\G703"), - ("G502 HERO", RGBDeviceType.Mouse, 0xC08B, 2, "default", @"Mice\G502"), - ("G502 Lightspeed", RGBDeviceType.Mouse, 0xC08D, 2, "default", @"Mice\G502"), - ("G502", RGBDeviceType.Mouse, 0xC332, 2, "default", @"Mice\G502"), - ("G403", RGBDeviceType.Mouse, 0xC083, 2, "default", @"Mice\G403"), - ("G303", RGBDeviceType.Mouse, 0xC080, 2, "default", @"Mice\G303"), - ("G203", RGBDeviceType.Mouse, 0xC084, 1, "default", @"Mice\G203"), - ("G Pro", RGBDeviceType.Mouse, 0xC085, 1, "default", @"Mice\GPro"), - ("G Pro Wireless", RGBDeviceType.Mouse, 0xC088, 2, "default", @"Mice\GProWireless"), - ("G Pro Hero", RGBDeviceType.Mouse, 0xC08C, 1, "default", @"Mice\GProHero"), - ("G633", RGBDeviceType.Headset, 0x0A5C, 2, "default", @"Headsets\G633"), - ("G933", RGBDeviceType.Headset, 0x0A5B, 2, "default", @"Headsets\G933"), - ("G935", RGBDeviceType.Headset, 0x0A87, 2, "default", @"Headsets\G935"), - ("G560", RGBDeviceType.Speaker, 0x0A78, 4, "default", @"Speakers\G560"), - }; + private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones)> ZONE_DEVICES + = new() + { + ("G213", RGBDeviceType.Keyboard, 0xC336, 5), + ("G903", RGBDeviceType.Mouse, 0xC086, 2), + ("Lightspeed Mouse Dongle", RGBDeviceType.Mouse, 0xC539, 2), + ("G703", RGBDeviceType.Mouse, 0xC087, 2), + ("G502 HERO", RGBDeviceType.Mouse, 0xC08B, 2), + ("G502 Lightspeed", RGBDeviceType.Mouse, 0xC08D, 2), + ("G502", RGBDeviceType.Mouse, 0xC332, 2), + ("G403", RGBDeviceType.Mouse, 0xC083, 2), + ("G303", RGBDeviceType.Mouse, 0xC080, 2), + ("G203", RGBDeviceType.Mouse, 0xC084, 1), + ("G Pro", RGBDeviceType.Mouse, 0xC085, 1), + ("G Pro Wireless", RGBDeviceType.Mouse, 0xC088, 2), + ("G Pro Hero", RGBDeviceType.Mouse, 0xC08C, 1), + ("G633", RGBDeviceType.Headset, 0x0A5C, 2), + ("G933", RGBDeviceType.Headset, 0x0A5B, 2), + ("G935", RGBDeviceType.Headset, 0x0A87, 2), + ("G560", RGBDeviceType.Speaker, 0x0A78, 4), + }; #endregion #region Properties & Fields public static bool IsPerKeyDeviceConnected { get; private set; } - public static (string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) PerKeyDeviceData { get; private set; } + public static (string model, RGBDeviceType deviceType, int id, int zones) PerKeyDeviceData { get; private set; } public static bool IsPerDeviceDeviceConnected { get; private set; } - public static (string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) PerDeviceDeviceData { get; private set; } + public static (string model, RGBDeviceType deviceType, int id, int zones) PerDeviceDeviceData { get; private set; } public static bool IsZoneDeviceConnected { get; private set; } - public static IEnumerable<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> ZoneDeviceData { get; private set; } + public static IEnumerable<(string model, RGBDeviceType deviceType, int id, int zones)> ZoneDeviceData { get; private set; } = Enumerable.Empty<(string model, RGBDeviceType deviceType, int id, int zones)>(); #endregion @@ -91,7 +89,7 @@ namespace RGB.NET.Devices.Logitech.HID { List ids = DeviceList.Local.GetHidDevices(VENDOR_ID).Select(x => x.ProductID).Distinct().ToList(); - foreach ((string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) deviceData in PER_KEY_DEVICES) + foreach ((string model, RGBDeviceType deviceType, int id, int zones) deviceData in PER_KEY_DEVICES) if (ids.Contains(deviceData.id)) { IsPerKeyDeviceConnected = true; @@ -99,7 +97,7 @@ namespace RGB.NET.Devices.Logitech.HID break; } - foreach ((string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) deviceData in PER_DEVICE_DEVICES) + foreach ((string model, RGBDeviceType deviceType, int id, int zones) deviceData in PER_DEVICE_DEVICES) if (ids.Contains(deviceData.id)) { IsPerDeviceDeviceConnected = true; @@ -107,21 +105,19 @@ namespace RGB.NET.Devices.Logitech.HID break; } - Dictionary> connectedZoneDevices - = new Dictionary>(); - foreach ((string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) deviceData in ZONE_DEVICES) + Dictionary> connectedZoneDevices = new(); + foreach ((string model, RGBDeviceType deviceType, int id, int zones) deviceData in ZONE_DEVICES) { if (ids.Contains(deviceData.id)) { IsZoneDeviceConnected = true; - if (!connectedZoneDevices.TryGetValue(deviceData.deviceType, out List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> deviceList)) - connectedZoneDevices.Add(deviceData.deviceType, deviceList = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)>()); + if (!connectedZoneDevices.TryGetValue(deviceData.deviceType, out List<(string model, RGBDeviceType deviceType, int id, int zones)>? deviceList)) + connectedZoneDevices.Add(deviceData.deviceType, deviceList = new List<(string model, RGBDeviceType deviceType, int id, int zones)>()); deviceList.Add(deviceData); } } - List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> zoneDeviceData - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)>(); - foreach (KeyValuePair> connectedZoneDevice in connectedZoneDevices) + List<(string model, RGBDeviceType deviceType, int id, int zones)> zoneDeviceData = new(); + foreach (KeyValuePair> connectedZoneDevice in connectedZoneDevices) { int maxZones = connectedZoneDevice.Value.Max(x => x.zones); zoneDeviceData.Add(connectedZoneDevice.Value.First(x => x.zones == maxZones)); diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs index 5169eb3..8e57da6 100644 --- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs +++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; +using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Logitech.HID; using RGB.NET.Devices.Logitech.Native; @@ -19,7 +19,7 @@ namespace RGB.NET.Devices.Logitech { #region Properties & Fields - private static LogitechDeviceProvider _instance; + private static LogitechDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -29,40 +29,27 @@ namespace RGB.NET.Devices.Logitech /// 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 List { "x86/LogitechLedEnginesWrapper.dll" }; + public static List PossibleX86NativePaths { get; } = new() { "x86/LogitechLedEnginesWrapper.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 List { "x64/LogitechLedEnginesWrapper.dll" }; + public static List PossibleX64NativePaths { get; } = new() { "x64/LogitechLedEnginesWrapper.dll" }; /// public bool IsInitialized { get; private set; } - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _LogitechGSDK.LoadedArchitecture; - /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; // Exclusive access isn't possible for logitech devices. - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for logitech devices. /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + 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 Dictionary(); + private readonly Dictionary _zoneUpdateQueues = new(); private LogitechPerDeviceUpdateQueue _perDeviceUpdateQueue; private LogitechPerKeyUpdateQueue _perKeyUpdateQueue; @@ -89,7 +76,7 @@ namespace RGB.NET.Devices.Logitech #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { try { @@ -102,7 +89,7 @@ namespace RGB.NET.Devices.Logitech try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); _LogitechGSDK.Reload(); if (!_LogitechGSDK.LogiLedInit()) return false; @@ -116,10 +103,10 @@ namespace RGB.NET.Devices.Logitech { if (DeviceChecker.IsPerKeyDeviceConnected) { - (string model, RGBDeviceType deviceType, int _, int _, string imageLayout, string layoutPath) = DeviceChecker.PerKeyDeviceData; + (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, imageLayout, layoutPath)); + ILogitechRGBDevice device = new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0)); device.Initialize(_perKeyUpdateQueue); devices.Add(device); } @@ -131,10 +118,10 @@ namespace RGB.NET.Devices.Logitech { if (DeviceChecker.IsPerDeviceDeviceConnected) { - (string model, RGBDeviceType deviceType, int _, int _, string imageLayout, string layoutPath) = DeviceChecker.PerDeviceDeviceData; + (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, imageLayout, layoutPath)); + ILogitechRGBDevice device = new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0)); device.Initialize(_perDeviceUpdateQueue); devices.Add(device); } @@ -146,13 +133,13 @@ namespace RGB.NET.Devices.Logitech { if (DeviceChecker.IsZoneDeviceConnected) { - foreach ((string model, RGBDeviceType deviceType, int _, int zones, string imageLayout, string layoutPath) in DeviceChecker.ZoneDeviceData) + foreach ((string model, RGBDeviceType deviceType, int _, int zones) in DeviceChecker.ZoneDeviceData) try { if (loadFilter.HasFlag(deviceType)) { - LogitechZoneUpdateQueue updateQueue = new LogitechZoneUpdateQueue(UpdateTrigger, deviceType); - ILogitechRGBDevice device = new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones, imageLayout, layoutPath)); + 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); @@ -163,7 +150,7 @@ namespace RGB.NET.Devices.Logitech } catch { if (throwExceptions) throw; } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -178,15 +165,17 @@ namespace RGB.NET.Devices.Logitech return true; } - /// - public void ResetDevices() => _LogitechGSDK.LogiLedRestoreLighting(); - /// public void Dispose() { - try { UpdateTrigger?.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(); + try { _LogitechGSDK.LogiLedRestoreLighting(); } catch { /* at least we tried */ } diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProviderLoader.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProviderLoader.cs deleted file mode 100644 index e79691b..0000000 --- a/RGB.NET.Devices.Logitech/LogitechDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Logitech -{ - /// - /// Represents a device provider loaded used to dynamically load logitech devices into an application. - /// - public class LogitechDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => LogitechDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs index 8f1b826..0fd1c05 100644 --- a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs +++ b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs @@ -17,12 +17,7 @@ namespace RGB.NET.Devices.Logitech.Native #region Libary Management private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - + /// /// Reloads the SDK. /// @@ -38,7 +33,7 @@ namespace RGB.NET.Devices.Logitech.Native // HACK: Load library at runtime to support both, x86 and x64 with one managed dll List possiblePathList = Environment.Is64BitProcess ? LogitechDeviceProvider.PossibleX64NativePaths : LogitechDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); if (dllPath == null) throw new RGBDeviceException($"Can't find the Logitech-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); _dllHandle = LoadLibrary(dllPath); @@ -81,16 +76,16 @@ namespace RGB.NET.Devices.Logitech.Native #region Pointers - private static LogiLedInitPointer _logiLedInitPointer; - private static LogiLedShutdownPointer _logiLedShutdownPointer; - private static LogiLedSetTargetDevicePointer _logiLedSetTargetDevicePointer; - private static LogiLedGetSdkVersionPointer _logiLedGetSdkVersionPointer; - private static LogiLedSaveCurrentLightingPointer _lgiLedSaveCurrentLightingPointer; - private static LogiLedRestoreLightingPointer _logiLedRestoreLightingPointer; - private static LogiLedSetLightingPointer _logiLedSetLightingPointer; - private static LogiLedSetLightingForKeyWithKeyNamePointer _logiLedSetLightingForKeyWithKeyNamePointer; - private static LogiLedSetLightingFromBitmapPointer _logiLedSetLightingFromBitmapPointer; - private static LogiLedSetLightingForTargetZonePointer _logiLedSetLightingForTargetZonePointer; + private static LogiLedInitPointer? _logiLedInitPointer; + private static LogiLedShutdownPointer? _logiLedShutdownPointer; + private static LogiLedSetTargetDevicePointer? _logiLedSetTargetDevicePointer; + private static LogiLedGetSdkVersionPointer? _logiLedGetSdkVersionPointer; + private static LogiLedSaveCurrentLightingPointer? _lgiLedSaveCurrentLightingPointer; + private static LogiLedRestoreLightingPointer? _logiLedRestoreLightingPointer; + private static LogiLedSetLightingPointer? _logiLedSetLightingPointer; + private static LogiLedSetLightingForKeyWithKeyNamePointer? _logiLedSetLightingForKeyWithKeyNamePointer; + private static LogiLedSetLightingFromBitmapPointer? _logiLedSetLightingFromBitmapPointer; + private static LogiLedSetLightingForTargetZonePointer? _logiLedSetLightingForTargetZonePointer; #endregion @@ -130,11 +125,11 @@ namespace RGB.NET.Devices.Logitech.Native // ReSharper disable EventExceptionNotDocumented - internal static bool LogiLedInit() => _logiLedInitPointer(); + internal static bool LogiLedInit() => (_logiLedInitPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(); - internal static void LogiLedShutdown() => _logiLedShutdownPointer(); + internal static void LogiLedShutdown() => (_logiLedShutdownPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(); - internal static bool LogiLedSetTargetDevice(LogitechDeviceCaps targetDevice) => _logiLedSetTargetDevicePointer((int)targetDevice); + internal static bool LogiLedSetTargetDevice(LogitechDeviceCaps targetDevice) => (_logiLedSetTargetDevicePointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke((int)targetDevice); internal static string LogiLedGetSdkVersion() { @@ -146,21 +141,23 @@ namespace RGB.NET.Devices.Logitech.Native return $"{major}.{minor}.{build}"; } - internal static bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum) => _logiLedGetSdkVersionPointer(ref majorNum, ref minorNum, ref buildNum); + internal static bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum) => + (_logiLedGetSdkVersionPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(ref majorNum, ref minorNum, ref buildNum); - internal static bool LogiLedSaveCurrentLighting() => _lgiLedSaveCurrentLightingPointer(); + internal static bool LogiLedSaveCurrentLighting() => (_lgiLedSaveCurrentLightingPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(); - internal static bool LogiLedRestoreLighting() => _logiLedRestoreLightingPointer(); + internal static bool LogiLedRestoreLighting() => (_logiLedRestoreLightingPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(); - internal static bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage) => _logiLedSetLightingPointer(redPercentage, greenPercentage, bluePercentage); + internal static bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage) => + (_logiLedSetLightingPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(redPercentage, greenPercentage, bluePercentage); internal static bool LogiLedSetLightingForKeyWithKeyName(int keyCode, int redPercentage, int greenPercentage, int bluePercentage) - => _logiLedSetLightingForKeyWithKeyNamePointer(keyCode, redPercentage, greenPercentage, bluePercentage); + => (_logiLedSetLightingForKeyWithKeyNamePointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(keyCode, redPercentage, greenPercentage, bluePercentage); - internal static bool LogiLedSetLightingFromBitmap(byte[] bitmap) => _logiLedSetLightingFromBitmapPointer(bitmap); + internal static bool LogiLedSetLightingFromBitmap(byte[] bitmap) => (_logiLedSetLightingFromBitmapPointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(bitmap); internal static bool LogiLedSetLightingForTargetZone(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage) - => _logiLedSetLightingForTargetZonePointer(deviceType, zone, redPercentage, greenPercentage, bluePercentage); + => (_logiLedSetLightingForTargetZonePointer ?? throw new RGBDeviceException("The Logitech-GSDK is not initialized.")).Invoke(deviceType, zone, redPercentage, greenPercentage, bluePercentage); // ReSharper restore EventExceptionNotDocumented diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs index 42ff262..416e18e 100644 --- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs @@ -26,19 +26,17 @@ namespace RGB.NET.Devices.Logitech #region Methods /// - protected override void InitializeLayout() + public override void Initialize(UpdateQueue updateQueue) { - base.InitializeLayout(); + base.Initialize(updateQueue); - if (LedMapping.Count == 0) - InitializeLed(LedId.Custom1, new Rectangle(0, 0, 10, 10)); + AddLed(LedId.Custom1, new Point(0, 0), new Size(10, 10)); } + /// + protected override object GetLedCustomData(LedId ledId) => (ledId, LogitechLedId.DEVICE); /// - protected override object CreateLedCustomData(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(ledsToUpdate.Where(x => x.Color.A > 0).Take(1)); #endregion } diff --git a/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs b/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs index 9bd9a6e..dcfba20 100644 --- a/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs +++ b/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs @@ -14,8 +14,8 @@ namespace RGB.NET.Devices.Logitech #region Properties & Fields - internal static Dictionary BitmapOffset { get; } = new Dictionary - { + internal static Dictionary BitmapOffset { get; } = new() + { { LedId.Keyboard_Escape, 0 }, { LedId.Keyboard_F1, 4 }, { LedId.Keyboard_F2, 8 }, diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs index e5e3f40..2b5a85d 100644 --- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs @@ -26,10 +26,10 @@ namespace RGB.NET.Devices.Logitech #region Methods /// - protected override object CreateLedCustomData(LedId ledId) => (ledId, PerKeyIdMapping.DEFAULT.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : LogitechLedId.Invalid); + 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(ledsToUpdate.Where(x => x.Color.A > 0)); #endregion } diff --git a/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs b/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs index 68d2cf4..9f8afbc 100644 --- a/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs +++ b/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Logitech { internal static class PerKeyIdMapping { - internal static readonly Dictionary DEFAULT = new Dictionary - { + internal static readonly Dictionary DEFAULT = new() + { { LedId.Invalid, LogitechLedId.Invalid }, { LedId.Keyboard_Escape, LogitechLedId.ESC }, { LedId.Keyboard_F1, LogitechLedId.F1 }, diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs index 419e796..4b0da4f 100644 --- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs @@ -12,13 +12,13 @@ namespace RGB.NET.Devices.Logitech { #region Constants - private static readonly Dictionary BASE_LED_MAPPING = new Dictionary + private static readonly Dictionary BASE_LED_MAPPING = new() { - {RGBDeviceType.Keyboard, LedId.Keyboard_Programmable1}, - {RGBDeviceType.Mouse, LedId.Mouse1}, - {RGBDeviceType.Headset, LedId.Headset1}, - {RGBDeviceType.Mousepad, LedId.Mousepad1}, - {RGBDeviceType.Speaker, LedId.Speaker1} + { RGBDeviceType.Keyboard, LedId.Keyboard_Programmable1 }, + { RGBDeviceType.Mouse, LedId.Mouse1 }, + { RGBDeviceType.Headset, LedId.Headset1 }, + { RGBDeviceType.Mousepad, LedId.Mousepad1 }, + { RGBDeviceType.Speaker, LedId.Speaker1 } }; #endregion @@ -47,19 +47,19 @@ namespace RGB.NET.Devices.Logitech #region Methods /// - protected override void InitializeLayout() + public override void Initialize(UpdateQueue updateQueue) { - for (int i = 0; i < DeviceInfo.Zones; i++) - InitializeLed(_baseLedId + i, new Rectangle(i * 10, 0, 10, 10)); + base.Initialize(updateQueue); - base.InitializeLayout(); + for (int i = 0; i < DeviceInfo.Zones; i++) + AddLed(_baseLedId + i, new Point(i * 10, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)(ledId - _baseLedId); + 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(ledsToUpdate.Where(x => x.Color.A > 0)); #endregion } diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs index a95ca98..c3fb9ef 100644 --- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs @@ -12,8 +12,8 @@ namespace RGB.NET.Devices.Logitech { #region Constants - private static readonly Dictionary DEVICE_TYPE_MAPPING = new Dictionary - { + private static readonly Dictionary DEVICE_TYPE_MAPPING = new() + { {RGBDeviceType.Keyboard, LogitechDeviceType.Keyboard}, {RGBDeviceType.Mouse, LogitechDeviceType.Mouse}, {RGBDeviceType.Headset, LogitechDeviceType.Headset}, diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index 258bf84..a6933cc 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -24,7 +24,7 @@ namespace RGB.NET.Devices.Msi /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected MsiDeviceUpdateQueue DeviceUpdateQueue { get; set; } + protected MsiDeviceUpdateQueue? DeviceUpdateQueue { get; set; } #endregion @@ -54,7 +54,7 @@ namespace RGB.NET.Devices.Msi if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } } @@ -66,7 +66,7 @@ namespace RGB.NET.Devices.Msi /// protected override void UpdateLeds(IEnumerable ledsToUpdate) - => DeviceUpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int))); + => DeviceUpdateQueue?.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int))); /// public override void Dispose() diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs index 3790298..480e8c1 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Msi { @@ -29,10 +28,7 @@ namespace RGB.NET.Devices.Msi public string Model { get; } /// - public Uri Image { get; set; } - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + public object? LayoutMetadata { get; set; } #endregion diff --git a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs index 3b295f4..8a41f90 100644 --- a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs @@ -37,16 +37,13 @@ namespace RGB.NET.Devices.Msi //Hex3l: Every led is a video card adapter. _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); - InitializeLed(LedId.GraphicsCard1 + i, new Rectangle(i * 10, 0, 10, 10)); + AddLed(LedId.GraphicsCard1 + i, new Point(i * 10, 0), new Size(10, 10)); } - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\MSI\GraphicsCard\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; - + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; + #endregion } } diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs index 04e7787..5cf8b00 100644 --- a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs @@ -35,16 +35,13 @@ namespace RGB.NET.Devices.Msi const string LED_STYLE = "Steady"; _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); - InitializeLed(LedId.Mainboard1 + i, new Rectangle(i * 40, 0, 40, 8)); + AddLed(LedId.Mainboard1 + i, new Point(i * 40, 0), new Size(40, 8)); } - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\MSI\Mainboards\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; - + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; + #endregion } } diff --git a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs index 1438f3a..dd4b702 100644 --- a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs @@ -35,16 +35,13 @@ namespace RGB.NET.Devices.Msi const string LED_STYLE = "Steady"; _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); - InitializeLed(LedId.Mouse1 + i, new Rectangle(i * 10, 0, 10, 10)); + AddLed(LedId.Mouse1 + i, new Point(i * 10, 0), new Size(10, 10)); } - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\MSI\Mouses\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; - + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; + #endregion } } diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index ffc9506..a5b718f 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; +using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Msi.Exceptions; using RGB.NET.Devices.Msi.Native; @@ -19,7 +19,7 @@ namespace RGB.NET.Devices.Msi { #region Properties & Fields - private static MsiDeviceProvider _instance; + private static MsiDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -29,13 +29,13 @@ namespace RGB.NET.Devices.Msi /// 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 List { "x86/MysticLight_SDK.dll" }; + public static List PossibleX86NativePaths { get; } = new() { "x86/MysticLight_SDK.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 List { "x64/MysticLight_SDK.dll" }; + public static List PossibleX64NativePaths { get; } = new() { "x64/MysticLight_SDK.dll" }; /// /// @@ -43,24 +43,8 @@ namespace RGB.NET.Devices.Msi /// public bool IsInitialized { get; private set; } - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _MsiSDK.LoadedArchitecture; - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for corsair devices. @@ -88,13 +72,13 @@ namespace RGB.NET.Devices.Msi #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); _MsiSDK.Reload(); @@ -117,7 +101,7 @@ namespace RGB.NET.Devices.Msi //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 MsiDeviceUpdateQueue(UpdateTrigger, deviceType); + MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType); IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard")); motherboard.Initialize(updateQueue, ledCount); devices.Add(motherboard); @@ -127,7 +111,7 @@ namespace RGB.NET.Devices.Msi //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 MsiDeviceUpdateQueue(UpdateTrigger, deviceType); + MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType); IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard")); graphicscard.Initialize(updateQueue, ledCount); devices.Add(graphicscard); @@ -137,7 +121,7 @@ namespace RGB.NET.Devices.Msi //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 MsiDeviceUpdateQueue(UpdateTrigger, deviceType); + MsiDeviceUpdateQueue updateQueue = new(UpdateTrigger, deviceType); IMsiRGBDevice mouses = new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse")); mouses.Initialize(updateQueue, ledCount); devices.Add(mouses); @@ -148,7 +132,7 @@ namespace RGB.NET.Devices.Msi catch { if (throwExceptions) throw; } } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -165,18 +149,17 @@ namespace RGB.NET.Devices.Msi private void ThrowMsiError(int errorCode) => throw new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)); - /// - public void ResetDevices() - { - //TODO DarthAffe 11.11.2017: Implement - } - /// public void Dispose() { - try { UpdateTrigger?.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(); + try { _MsiSDK.UnloadMsiSDK(); } catch { /* at least we tried */ } } diff --git a/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs b/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs deleted file mode 100644 index b059f85..0000000 --- a/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Msi -{ - /// - /// Represents a device provider loaded used to dynamically load MSI devices into an application. - /// - public class MsiDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => MsiDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs index 930352f..3bede30 100644 --- a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs +++ b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs @@ -17,11 +17,6 @@ namespace RGB.NET.Devices.Msi.Native private static IntPtr _dllHandle = IntPtr.Zero; - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - /// /// Reloads the SDK. /// @@ -37,10 +32,10 @@ namespace RGB.NET.Devices.Msi.Native // HACK: Load library at runtime to support both, x86 and x64 with one managed dll List possiblePathList = Environment.Is64BitProcess ? MsiDeviceProvider.PossibleX64NativePaths : MsiDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); if (dllPath == null) throw new RGBDeviceException($"Can't find the Msi-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); + SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))!); _dllHandle = LoadLibrary(dllPath); @@ -87,20 +82,20 @@ namespace RGB.NET.Devices.Msi.Native #region Pointers - private static InitializePointer _initializePointer; - private static GetDeviceInfoPointer _getDeviceInfoPointer; - private static GetLedInfoPointer _getLedInfoPointer; - private static GetLedColorPointer _getLedColorPointer; - private static GetLedStylePointer _getLedStylePointer; - private static GetLedMaxBrightPointer _getLedMaxBrightPointer; - private static GetLedBrightPointer _getLedBrightPointer; - private static GetLedMaxSpeedPointer _getLedMaxSpeedPointer; - private static GetLedSpeedPointer _getLedSpeedPointer; - private static SetLedColorPointer _setLedColorPointer; - private static SetLedStylePointer _setLedStylePointer; - private static SetLedBrightPointer _setLedBrightPointer; - private static SetLedSpeedPointer _setLedSpeedPointer; - private static GetErrorMessagePointer _getErrorMessagePointer; + private static InitializePointer? _initializePointer; + private static GetDeviceInfoPointer? _getDeviceInfoPointer; + private static GetLedInfoPointer? _getLedInfoPointer; + private static GetLedColorPointer? _getLedColorPointer; + private static GetLedStylePointer? _getLedStylePointer; + private static GetLedMaxBrightPointer? _getLedMaxBrightPointer; + private static GetLedBrightPointer? _getLedBrightPointer; + private static GetLedMaxSpeedPointer? _getLedMaxSpeedPointer; + private static GetLedSpeedPointer? _getLedSpeedPointer; + private static SetLedColorPointer? _setLedColorPointer; + private static SetLedStylePointer? _setLedStylePointer; + private static SetLedBrightPointer? _setLedBrightPointer; + private static SetLedSpeedPointer? _setLedSpeedPointer; + private static GetErrorMessagePointer? _getErrorMessagePointer; #endregion @@ -192,11 +187,11 @@ namespace RGB.NET.Devices.Msi.Native #endregion - internal static int Initialize() => _initializePointer(); + internal static int Initialize() => (_initializePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(); internal static int GetDeviceInfo(out string[] pDevType, out int[] pLedCount) { // HACK - SDK GetDeviceInfo returns a string[] for ledCount, so we'll parse that to int. - int result = _getDeviceInfoPointer(out pDevType, out string[] ledCount); + int result = (_getDeviceInfoPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(out pDevType, out string[] ledCount); pLedCount = new int[ledCount.Length]; for (int i = 0; i < ledCount.Length; i++) @@ -205,21 +200,21 @@ namespace RGB.NET.Devices.Msi.Native return result; } - internal static int GetLedInfo(string type, int index, out string pName, out string[] pLedStyles) => _getLedInfoPointer(type, index, out pName, out pLedStyles); - internal static int GetLedColor(string type, int index, out int r, out int g, out int b) => _getLedColorPointer(type, index, out r, out g, out b); - internal static int GetLedStyle(string type, int index, out string style) => _getLedStylePointer(type, index, out style); - internal static int GetLedMaxBright(string type, int index, out int maxLevel) => _getLedMaxBrightPointer(type, index, out maxLevel); - internal static int GetLedBright(string type, int index, out int currentLevel) => _getLedBrightPointer(type, index, out currentLevel); - internal static int GetLedMaxSpeed(string type, int index, out int maxSpeed) => _getLedMaxSpeedPointer(type, index, out maxSpeed); - internal static int GetLedSpeed(string type, int index, out int currentSpeed) => _getLedSpeedPointer(type, index, out currentSpeed); - internal static int SetLedColor(string type, int index, int r, int g, int b) => _setLedColorPointer(type, index, r, g, b); - internal static int SetLedStyle(string type, int index, string style) => _setLedStylePointer(type, index, style); - internal static int SetLedBright(string type, int index, int level) => _setLedBrightPointer(type, index, level); - internal static int SetLedSpeed(string type, int index, int speed) => _setLedSpeedPointer(type, index, speed); + internal static int GetLedInfo(string type, int index, out string pName, out string[] pLedStyles) => (_getLedInfoPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out pName, out pLedStyles); + internal static int GetLedColor(string type, int index, out int r, out int g, out int b) => (_getLedColorPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out r, out g, out b); + internal static int GetLedStyle(string type, int index, out string style) => (_getLedStylePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out style); + internal static int GetLedMaxBright(string type, int index, out int maxLevel) => (_getLedMaxBrightPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out maxLevel); + internal static int GetLedBright(string type, int index, out int currentLevel) => (_getLedBrightPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out currentLevel); + internal static int GetLedMaxSpeed(string type, int index, out int maxSpeed) => (_getLedMaxSpeedPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out maxSpeed); + internal static int GetLedSpeed(string type, int index, out int currentSpeed) => (_getLedSpeedPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out currentSpeed); + internal static int SetLedColor(string type, int index, int r, int g, int b) => (_setLedColorPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, r, g, b); + internal static int SetLedStyle(string type, int index, string style) => (_setLedStylePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, style); + internal static int SetLedBright(string type, int index, int level) => (_setLedBrightPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, level); + internal static int SetLedSpeed(string type, int index, int speed) => (_setLedSpeedPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, speed); internal static string GetErrorMessage(int errorCode) { - _getErrorMessagePointer(errorCode, out string description); + (_getErrorMessagePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(errorCode, out string description); return description; } diff --git a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings index 5db6073..bec0f75 100644 --- a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings +++ b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings @@ -2,4 +2,5 @@ True True True - True \ No newline at end of file + True + True \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs index 6e34359..5ce5547 100644 --- a/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs +++ b/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs @@ -47,9 +47,9 @@ namespace RGB.NET.Devices.Novation /// Sends the specified message to the device this queue is performing updates for. /// /// The message to send. - protected virtual void SendMessage(ShortMessage message) + protected virtual void SendMessage(ShortMessage? message) { - if (message != null) + if (message != null) _outputDevice.SendShort(message.Message); } @@ -59,7 +59,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(KeyValuePair data); /// public override void Dispose() diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs index d1f7679..c41c77e 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs @@ -25,7 +25,7 @@ namespace RGB.NET.Devices.Novation /// The used to update this . /// // ReSharper disable once MemberCanBePrivate.Global - protected MidiUpdateQueue UpdateQueue { get; set; } + protected MidiUpdateQueue? UpdateQueue { get; set; } #endregion @@ -53,7 +53,7 @@ namespace RGB.NET.Devices.Novation if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } @@ -71,12 +71,12 @@ namespace RGB.NET.Devices.Novation 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(ledsToUpdate.Where(x => x.Color.A > 0)); /// /// Resets the back to default. /// - public virtual void Reset() => UpdateQueue.Reset(); + public virtual void Reset() => UpdateQueue?.Reset(); /// /// diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs index 8e613bb..9d06dfe 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.Novation { @@ -24,11 +23,8 @@ namespace RGB.NET.Devices.Novation public string Model { get; } /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - /// /// Gets the of the . /// diff --git a/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs index 5dd9d54..2998059 100644 --- a/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs +++ b/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs @@ -152,7 +152,7 @@ namespace RGB.NET.Devices.Novation #region Methods /// - protected override ShortMessage CreateMessage(KeyValuePair data) + protected override ShortMessage? CreateMessage(KeyValuePair data) { (byte mode, byte id) = ((byte, byte))data.Key; if (mode == 0x00) return null; diff --git a/RGB.NET.Devices.Novation/Helper/EnumExtension.cs b/RGB.NET.Devices.Novation/Helper/EnumExtension.cs index a3f432a..caeecfa 100644 --- a/RGB.NET.Devices.Novation/Helper/EnumExtension.cs +++ b/RGB.NET.Devices.Novation/Helper/EnumExtension.cs @@ -14,7 +14,7 @@ namespace RGB.NET.Devices.Novation /// /// The enum value to get the description from. /// The value of the of the source. - internal static string GetDeviceId(this Enum source) => source.GetAttribute()?.Id; + internal static string? GetDeviceId(this Enum source) => source.GetAttribute()?.Id; /// /// Gets the value of the . @@ -36,10 +36,11 @@ namespace RGB.NET.Devices.Novation /// The enum value to get the attribute from /// The generic attribute type /// The . - private static T GetAttribute(this Enum source) + private static T? GetAttribute(this Enum source) where T : Attribute { - FieldInfo fi = source.GetType().GetField(source.ToString()); + FieldInfo? fi = source.GetType().GetField(source.ToString()); + if (fi == null) return null; T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); return attributes.Length > 0 ? attributes[0] : null; } diff --git a/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs b/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs index 39aa29f..6a2a83c 100644 --- a/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs +++ b/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Novation { internal static class LaunchpadIdMapping { - internal static readonly Dictionary LEGACY = new Dictionary - { + internal static readonly Dictionary LEGACY = new() + { { LedId.Invalid, (0x00, 0xFF, 8, 0) }, { LedId.LedMatrix1, (0x90, 0x00, 0, 1) }, @@ -93,8 +93,8 @@ namespace RGB.NET.Devices.Novation { LedId.Custom16, (0x90, 0x78, 8, 8) }, //Scene8 }; - internal static readonly Dictionary CURRENT = new Dictionary - { + internal static readonly Dictionary CURRENT = new() + { { LedId.Invalid, (0x00, 0xFF, 8, 0) }, { LedId.LedMatrix1, (0x90, 81, 0, 1) }, diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs index e00f114..39271aa 100644 --- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs @@ -34,15 +34,12 @@ namespace RGB.NET.Devices.Novation foreach (LedId ledId in mapping.Keys) { (_, _, int x, int y) = mapping[ledId]; - InitializeLed(ledId, new Point(BUTTON_SIZE * x, BUTTON_SIZE * y), new Size(BUTTON_SIZE)); + AddLed(ledId, new Point(BUTTON_SIZE * x, BUTTON_SIZE * y), new Size(BUTTON_SIZE)); } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Novation\Launchpads", $"{model.ToUpper()}.xml"), "Default"); } /// - protected override object CreateLedCustomData(LedId ledId) => GetDeviceMapping().TryGetValue(ledId, out (byte mode, byte id, int _, int __) data) ? (data.mode, data.id) : ((byte)0x00, (byte)0x00); + protected override object GetLedCustomData(LedId ledId) => GetDeviceMapping().TryGetValue(ledId, out (byte mode, byte id, int _, int __) data) ? (data.mode, data.id) : ((byte)0x00, (byte)0x00); protected virtual Dictionary GetDeviceMapping() => DeviceInfo.LedIdMapping switch diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs index 4e031fe..89ef95d 100644 --- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs +++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs @@ -18,7 +18,7 @@ namespace RGB.NET.Devices.Novation { #region Properties & Fields - private static NovationDeviceProvider _instance; + private static NovationDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -31,18 +31,12 @@ namespace RGB.NET.Devices.Novation public bool IsInitialized { get; private set; } /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for novation devices. /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + public DeviceUpdateTrigger UpdateTrigger { get; } #endregion @@ -65,13 +59,13 @@ namespace RGB.NET.Devices.Novation #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); IList devices = new List(); @@ -85,7 +79,7 @@ namespace RGB.NET.Devices.Novation NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices)) .Cast() - .FirstOrDefault(x => x.GetDeviceId().ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant())); + .FirstOrDefault(x => x.GetDeviceId()?.ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant()) ?? false); if (deviceId == null) continue; @@ -99,7 +93,7 @@ namespace RGB.NET.Devices.Novation catch { if (throwExceptions) throw; } } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; } @@ -112,22 +106,17 @@ namespace RGB.NET.Devices.Novation return true; } - - /// - public void ResetDevices() - { - foreach (IRGBDevice device in Devices) - { - NovationLaunchpadRGBDevice novationDevice = device as NovationLaunchpadRGBDevice; - novationDevice?.Reset(); - } - } - + /// public void Dispose() { - try { UpdateTrigger?.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.Novation/NovationDeviceProviderLoader.cs b/RGB.NET.Devices.Novation/NovationDeviceProviderLoader.cs deleted file mode 100644 index f2fc28d..0000000 --- a/RGB.NET.Devices.Novation/NovationDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Novation -{ - /// - /// Represents a device provider loaded used to dynamically load novation devices into an application. - /// - public class NovationDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => NovationDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs index 853b222..79165d3 100644 --- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs +++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs @@ -30,16 +30,12 @@ namespace RGB.NET.Devices.Razer /// protected override void InitializeLayout() { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\ChromaLink", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - for (int i = 0; i < _Defines.CHROMALINK_MAX_LEDS; i++) - InitializeLed(LedId.Custom1 + i, new Rectangle(i * 11, 0, 10, 10)); + for (int i = 0; i < _Defines.CHROMALINK_MAX_LEDS; i++) + AddLed(LedId.Custom1 + i, new Point(i * 11, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1; /// protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerChromaLinkUpdateQueue(updateTrigger, DeviceInfo.DeviceId); diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs index a9ade2b..7455aa4 100644 --- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs @@ -34,7 +34,8 @@ namespace RGB.NET.Devices.Razer foreach (KeyValuePair data in dataSet) colors[(int)data.Key] = new _Color(data.Value); - _ChromaLinkCustomEffect effectParams = new _ChromaLinkCustomEffect { Color = colors }; + _ChromaLinkCustomEffect effectParams = new() + { Color = colors }; IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); Marshal.StructureToPtr(effectParams, ptr, false); diff --git a/RGB.NET.Devices.Razer/Enum/RazerLogicalKeyboardLayout.cs b/RGB.NET.Devices.Razer/Enum/RazerLogicalKeyboardLayout.cs deleted file mode 100644 index 1ec9382..0000000 --- a/RGB.NET.Devices.Razer/Enum/RazerLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Razer -{ - /// - /// Contains list of available logical layouts for razer keyboards. - /// - public enum RazerLogicalKeyboardLayout - { - TODO - }; -} diff --git a/RGB.NET.Devices.Razer/Enum/RazerPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Razer/Enum/RazerPhysicalKeyboardLayout.cs deleted file mode 100644 index 090a2db..0000000 --- a/RGB.NET.Devices.Razer/Enum/RazerPhysicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable UnusedMember.Global -// ReSharper disable InconsistentNaming - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Razer -{ - /// - /// Contains list of available physical layouts for razer keyboards. - /// - public enum RazerPhysicalKeyboardLayout - { - TODO - } -} diff --git a/RGB.NET.Devices.Razer/Generic/Devices.cs b/RGB.NET.Devices.Razer/Generic/Devices.cs index a1eeeff..bb596b1 100644 --- a/RGB.NET.Devices.Razer/Generic/Devices.cs +++ b/RGB.NET.Devices.Razer/Generic/Devices.cs @@ -5,8 +5,8 @@ namespace RGB.NET.Devices.Razer { internal class Devices { - public static readonly List<(Guid guid, string model)> KEYBOARDS = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> KEYBOARDS = new() + { (new Guid("2EA1BB63-CA28-428D-9F06-196B88330BBB"), "Blackwidow Chroma"), (new Guid("ED1C1B82-BFBE-418F-B49D-D03F05B149DF"), "Razer Blackwidow Chroma Tournament Edition"), (new Guid("18C5AD9B-4326-4828-92C4-2669A66D2283"), "Razer Deathstalker "), @@ -22,8 +22,8 @@ namespace RGB.NET.Devices.Razer (new Guid("16BB5ABD-C1CD-4CB3-BDF7-62438748BD98"), "Razer Blackwidow Elite") }; - public static readonly List<(Guid guid, string model)> MICE = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> MICE = new() + { (new Guid("7EC00450-E0EE-4289-89D5-0D879C19061A"), "Razer Mamba Chroma Tournament Edition"), (new Guid("AEC50D91-B1F1-452F-8E16-7B73F376FDF3"), "Razer Deathadder Chroma "), (new Guid("FF8A5929-4512-4257-8D59-C647BF9935D0"), "Razer Diamondback"), @@ -35,35 +35,35 @@ namespace RGB.NET.Devices.Razer (new Guid("77834867-3237-4A9F-AD77-4A46C4183003"), "Razer DeathAdder Elite Chroma") }; - public static readonly List<(Guid guid, string model)> HEADSETS = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> HEADSETS = new() + { (new Guid("DF3164D7-5408-4A0E-8A7F-A7412F26BEBF"), "Razer ManO'War"), (new Guid("CD1E09A5-D5E6-4A6C-A93B-E6D9BF1D2092"), "Razer Kraken 7.1 Chroma"), (new Guid("7FB8A36E-9E74-4BB3-8C86-CAC7F7891EBD"), "Razer Kraken 7.1 Chroma Refresh"), (new Guid("FB357780-4617-43A7-960F-D1190ED54806"), "Razer Kraken Kitty") }; - public static readonly List<(Guid guid, string model)> MOUSEMATS = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> MOUSEMATS = new() + { (new Guid("80F95A94-73D2-48CA-AE9A-0986789A9AF2"), "Razer Firefly") }; - public static readonly List<(Guid guid, string model)> KEYPADS = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> KEYPADS = new() + { (new Guid("9D24B0AB-0162-466C-9640-7A924AA4D9FD"), "Razer Orbweaver"), (new Guid("00F0545C-E180-4AD1-8E8A-419061CE505E"), "Razer Tartarus") }; - public static readonly List<(Guid guid, string model)> CHROMALINKS = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> CHROMALINKS = new() + { (new Guid("0201203B-62F3-4C50-83DD-598BABD208E0"), "Core Chroma"), (new Guid("35F6F18D-1AE5-436C-A575-AB44A127903A"), "Lenovo Y900"), (new Guid("47DB1FA7-6B9B-4EE6-B6F4-4071A3B2053B"), "Lenovo Y27"), (new Guid("BB2E9C9B-B0D2-461A-BA52-230B5D6C3609"), "Chroma Box") }; - public static readonly List<(Guid guid, string model)> SPEAKERS = new List<(Guid guid, string model)> - { + public static readonly List<(Guid guid, string model)> SPEAKERS = new() + { (new Guid("45B308F2-CD44-4594-8375-4D5945AD880E"), "Nommo Chroma"), (new Guid("3017280B-D7F9-4D7B-930E-7B47181B46B5"), "Nommo Chroma Pro") }; diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs index e537caf..25dc2f9 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs @@ -24,7 +24,7 @@ namespace RGB.NET.Devices.Razer /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected RazerUpdateQueue UpdateQueue { get; set; } + protected RazerUpdateQueue? UpdateQueue { get; set; } #endregion @@ -54,7 +54,7 @@ namespace RGB.NET.Devices.Razer if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } @@ -74,12 +74,12 @@ namespace RGB.NET.Devices.Razer 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(ledsToUpdate.Where(x => x.Color.A > 0)); /// /// Resets the device. /// - public void Reset() => UpdateQueue.Reset(); + public void Reset() => UpdateQueue?.Reset(); /// public override void Dispose() diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs index 4336bfb..8281158 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs @@ -29,10 +29,7 @@ namespace RGB.NET.Devices.Razer public string Model { get; } /// - public Uri Image { get; set; } - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + public object? LayoutMetadata { get; set; } #endregion diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs index 25fbfd4..27ebbb0 100644 --- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs @@ -30,16 +30,12 @@ namespace RGB.NET.Devices.Razer /// protected override void InitializeLayout() { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Headset", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - for (int i = 0; i < _Defines.HEADSET_MAX_LEDS; i++) - InitializeLed(LedId.Headset1 + i, new Rectangle(i * 11, 0, 10, 10)); + for (int i = 0; i < _Defines.HEADSET_MAX_LEDS; i++) + AddLed(LedId.Headset1 + i, new Point(i * 11, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; /// protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerHeadsetUpdateQueue(updateTrigger, DeviceInfo.DeviceId); diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs index 91563e1..7e5d9b7 100644 --- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs @@ -34,7 +34,8 @@ namespace RGB.NET.Devices.Razer foreach (KeyValuePair data in dataSet) colors[(int)data.Key] = new _Color(data.Value); - _HeadsetCustomEffect effectParams = new _HeadsetCustomEffect { Color = colors }; + _HeadsetCustomEffect effectParams = new() + { 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 8c6aab6..2ca30a0 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs @@ -30,22 +30,13 @@ namespace RGB.NET.Devices.Razer /// protected override void InitializeLayout() { - //string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - //ApplyLayoutFromFile(PathHelper.GetAbsolutePath( - // $@"Layouts\Razer\Keyboards\{model}\{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - // DeviceInfo.LogicalLayout.ToString(), PathHelper.GetAbsolutePath(@"Images\Razer\Keyboards")); - - //TODO DarthAffe 13.12.2017: Correctly select ids - if (LedMapping.Count == 0) - { - for (int i = 0; i < _Defines.KEYBOARD_MAX_ROW; i++) - for (int j = 0; j < _Defines.KEYBOARD_MAX_COLUMN; j++) - InitializeLed(LedId.Keyboard_Escape + ((i * _Defines.KEYBOARD_MAX_COLUMN) + j), new Rectangle(j * 20, i * 20, 19, 19)); - } + for (int i = 0; i < _Defines.KEYBOARD_MAX_ROW; i++) + for (int j = 0; j < _Defines.KEYBOARD_MAX_COLUMN; j++) + AddLed(LedId.Keyboard_Escape + ((i * _Defines.KEYBOARD_MAX_COLUMN) + j), new Point(j * 20, i * 20), new Size(19, 19)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape; /// protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeyboardUpdateQueue(updateTrigger, DeviceInfo.DeviceId); diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs index 1057ecc..b65676a 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs @@ -2,7 +2,6 @@ // ReSharper disable UnusedMember.Global using System; -using System.Globalization; using RGB.NET.Core; namespace RGB.NET.Devices.Razer @@ -13,20 +12,6 @@ namespace RGB.NET.Devices.Razer /// public class RazerKeyboardRGBDeviceInfo : RazerRGBDeviceInfo { - #region Properties & Fields - - /// - /// Gets the physical layout of the keyboard. - /// - public RazerPhysicalKeyboardLayout PhysicalLayout { get; private set; } - - /// - /// Gets the logical layout of the keyboard as set in CUE settings. - /// - public RazerLogicalKeyboardLayout LogicalLayout { get; private set; } - - #endregion - #region Constructors /// @@ -35,28 +20,9 @@ namespace RGB.NET.Devices.Razer /// /// The Id of the . /// The model of the . - /// The of the layout this keyboard is using. - internal RazerKeyboardRGBDeviceInfo(Guid deviceId, string model, CultureInfo culture) + internal RazerKeyboardRGBDeviceInfo(Guid deviceId, string model) : base(deviceId, RGBDeviceType.Keyboard, model) - { - SetLayouts(culture.KeyboardLayoutId); - } - - #endregion - - #region Methods - - private void SetLayouts(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - //TODO DarthAffe 07.10.2017: Implement - default: - PhysicalLayout = RazerPhysicalKeyboardLayout.TODO; - LogicalLayout = RazerLogicalKeyboardLayout.TODO; - break; - } - } + { } #endregion } diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs index 9e00530..e87a987 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs @@ -34,7 +34,8 @@ namespace RGB.NET.Devices.Razer foreach (KeyValuePair data in dataSet) colors[(int)data.Key] = new _Color(data.Value); - _KeyboardCustomEffect effectParams = new _KeyboardCustomEffect { 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 be86e2d..2fac949 100644 --- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs @@ -30,19 +30,13 @@ namespace RGB.NET.Devices.Razer /// protected override void InitializeLayout() { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Keypad", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - { - for (int i = 0; i < _Defines.KEYPAD_MAX_ROW; i++) - for (int j = 0; j < _Defines.KEYPAD_MAX_COLUMN; j++) - InitializeLed(LedId.Keypad1 + ((i * _Defines.KEYPAD_MAX_COLUMN) + j), new Rectangle(j * 20, i * 20, 19, 19)); - } + for (int i = 0; i < _Defines.KEYPAD_MAX_ROW; i++) + for (int j = 0; j < _Defines.KEYPAD_MAX_COLUMN; j++) + AddLed(LedId.Keypad1 + ((i * _Defines.KEYPAD_MAX_COLUMN) + j), new Point(j * 20, i * 20), new Size(19, 19)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1; /// protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeypadUpdateQueue(updateTrigger, DeviceInfo.DeviceId); diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs index 2efd757..f0e884d 100644 --- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs @@ -34,7 +34,8 @@ namespace RGB.NET.Devices.Razer foreach (KeyValuePair data in dataSet) colors[(int)data.Key] = new _Color(data.Value); - _KeypadCustomEffect effectParams = new _KeypadCustomEffect { 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 6562467..983d90f 100644 --- a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs @@ -30,19 +30,13 @@ namespace RGB.NET.Devices.Razer /// protected override void InitializeLayout() { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Mice", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - { - for (int i = 0; i < _Defines.MOUSE_MAX_ROW; i++) - for (int j = 0; j < _Defines.MOUSE_MAX_COLUMN; j++) - InitializeLed(LedId.Mouse1 + ((i * _Defines.MOUSE_MAX_COLUMN) + j), new Rectangle(j * 11, i * 11, 10, 10)); - } + for (int i = 0; i < _Defines.MOUSE_MAX_ROW; i++) + for (int j = 0; j < _Defines.MOUSE_MAX_COLUMN; j++) + AddLed(LedId.Mouse1 + ((i * _Defines.MOUSE_MAX_COLUMN) + j), new Point(j * 11, i * 11), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; /// protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMouseUpdateQueue(updateTrigger, DeviceInfo.DeviceId); diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs index f1b039d..95547d8 100644 --- a/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs @@ -34,7 +34,8 @@ namespace RGB.NET.Devices.Razer foreach (KeyValuePair data in dataSet) colors[(int)data.Key] = new _Color(data.Value); - _MouseCustomEffect effectParams = new _MouseCustomEffect { 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 d9c4d81..285e211 100644 --- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs @@ -30,16 +30,12 @@ namespace RGB.NET.Devices.Razer /// protected override void InitializeLayout() { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Mousepad", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - for (int i = 0; i < _Defines.MOUSEPAD_MAX_LEDS; i++) - InitializeLed(LedId.Mousepad1 + i, new Rectangle(i * 11, 0, 10, 10)); + for (int i = 0; i < _Defines.MOUSEPAD_MAX_LEDS; i++) + AddLed(LedId.Mousepad1 + i, new Point(i * 11, 0), new Size(10, 10)); } /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1; + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1; /// protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMousepadUpdateQueue(updateTrigger, DeviceInfo.DeviceId); diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs index f7ddb04..419099b 100644 --- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs @@ -34,7 +34,8 @@ namespace RGB.NET.Devices.Razer foreach (KeyValuePair data in dataSet) colors[(int)data.Key] = new _Color(data.Value); - _MousepadCustomEffect effectParams = new _MousepadCustomEffect { 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/Native/_RazerSDK.cs b/RGB.NET.Devices.Razer/Native/_RazerSDK.cs index ca096e5..2b9c1ef 100644 --- a/RGB.NET.Devices.Razer/Native/_RazerSDK.cs +++ b/RGB.NET.Devices.Razer/Native/_RazerSDK.cs @@ -17,11 +17,6 @@ namespace RGB.NET.Devices.Razer.Native private static IntPtr _dllHandle = IntPtr.Zero; - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - /// /// Reloads the SDK. /// @@ -78,16 +73,16 @@ namespace RGB.NET.Devices.Razer.Native #region Pointers - private static InitPointer _initPointer; - private static UnInitPointer _unInitPointer; - private static QueryDevicePointer _queryDevicePointer; - private static CreateEffectPointer _createEffectPointer; - private static CreateHeadsetEffectPointer _createHeadsetEffectPointer; - private static CreateChromaLinkEffectPointer _createChromaLinkEffectPointer; - private static CreateKeyboardEffectPointer _createKeyboardEffectPointer; - private static CreateMousepadEffectPointer _createMousepadEffectPointer; - private static SetEffectPointer _setEffectPointer; - private static DeleteEffectPointer _deleteEffectPointer; + private static InitPointer? _initPointer; + private static UnInitPointer? _unInitPointer; + private static QueryDevicePointer? _queryDevicePointer; + private static CreateEffectPointer? _createEffectPointer; + private static CreateHeadsetEffectPointer? _createHeadsetEffectPointer; + private static CreateChromaLinkEffectPointer? _createChromaLinkEffectPointer; + private static CreateKeyboardEffectPointer? _createKeyboardEffectPointer; + private static CreateMousepadEffectPointer? _createMousepadEffectPointer; + private static SetEffectPointer? _setEffectPointer; + private static DeleteEffectPointer? _deleteEffectPointer; #endregion @@ -130,12 +125,12 @@ namespace RGB.NET.Devices.Razer.Native /// /// Razer-SDK: Initialize Chroma SDK. /// - internal static RazerError Init() => _initPointer(); + internal static RazerError Init() => (_initPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(); /// /// Razer-SDK: UnInitialize Chroma SDK. /// - internal static RazerError UnInit() => _unInitPointer(); + internal static RazerError UnInit() => (_unInitPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(); /// /// Razer-SDK: Query for device information. @@ -145,27 +140,27 @@ namespace RGB.NET.Devices.Razer.Native int structSize = Marshal.SizeOf(typeof(_DeviceInfo)); IntPtr deviceInfoPtr = Marshal.AllocHGlobal(structSize); - RazerError error = _queryDevicePointer(deviceId, deviceInfoPtr); + RazerError error = (_queryDevicePointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(deviceId, deviceInfoPtr); - deviceInfo = (_DeviceInfo)Marshal.PtrToStructure(deviceInfoPtr, typeof(_DeviceInfo)); + deviceInfo = (_DeviceInfo)Marshal.PtrToStructure(deviceInfoPtr, typeof(_DeviceInfo))!; Marshal.FreeHGlobal(deviceInfoPtr); return error; } - internal static RazerError CreateEffect(Guid deviceId, int effectType, IntPtr param, ref Guid effectId) => _createEffectPointer(deviceId, effectType, param, ref effectId); + internal static RazerError CreateEffect(Guid deviceId, int effectType, IntPtr param, ref Guid effectId) => (_createEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(deviceId, effectType, param, ref effectId); - internal static RazerError CreateHeadsetEffect(int effectType, IntPtr param, ref Guid effectId) => _createHeadsetEffectPointer(effectType, param, ref effectId); + internal static RazerError CreateHeadsetEffect(int effectType, IntPtr param, ref Guid effectId) => (_createHeadsetEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId); - internal static RazerError CreateChromaLinkEffect(int effectType, IntPtr param, ref Guid effectId) => _createChromaLinkEffectPointer(effectType, param, ref effectId); + internal static RazerError CreateChromaLinkEffect(int effectType, IntPtr param, ref Guid effectId) => (_createChromaLinkEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId); - internal static RazerError CreateKeyboardEffect(int effectType, IntPtr param, ref Guid effectId) => _createKeyboardEffectPointer(effectType, param, ref effectId); + internal static RazerError CreateKeyboardEffect(int effectType, IntPtr param, ref Guid effectId) => (_createKeyboardEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId); - internal static RazerError CreateMousepadEffect(int effectType, IntPtr param, ref Guid effectId) => _createMousepadEffectPointer(effectType, param, ref effectId); + internal static RazerError CreateMousepadEffect(int effectType, IntPtr param, ref Guid effectId) => (_createMousepadEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectType, param, ref effectId); - internal static RazerError SetEffect(Guid effectId) => _setEffectPointer(effectId); + internal static RazerError SetEffect(Guid effectId) => (_setEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectId); - internal static RazerError DeleteEffect(Guid effectId) => _deleteEffectPointer(effectId); + internal static RazerError DeleteEffect(Guid effectId) => (_deleteEffectPointer ?? throw new RGBDeviceException("The Razer-SDK is not initialized.")).Invoke(effectId); // ReSharper restore EventExceptionNotDocumented diff --git a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs index a155248..a44c4e2 100644 --- a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs +++ b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; @@ -20,7 +19,7 @@ namespace RGB.NET.Devices.Razer { #region Properties & Fields - private static RazerDeviceProvider _instance; + private static RazerDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -30,13 +29,13 @@ 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 List { @"%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 List { @"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll" }; + public static List PossibleX64NativePaths { get; } = new() { @"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll" }; /// /// @@ -44,24 +43,8 @@ namespace RGB.NET.Devices.Razer /// public bool IsInitialized { get; private set; } - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _RazerSDK.LoadedArchitecture; - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// Forces to load the devices represented by the emulator even if they aren't reported to exist. @@ -71,7 +54,7 @@ namespace RGB.NET.Devices.Razer /// /// The used to trigger the updates for razer devices. /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + public DeviceUpdateTrigger UpdateTrigger { get; } #endregion @@ -94,7 +77,7 @@ namespace RGB.NET.Devices.Razer #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { if (IsInitialized) TryUnInit(); @@ -103,7 +86,7 @@ namespace RGB.NET.Devices.Razer try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); _RazerSDK.Reload(); @@ -121,7 +104,7 @@ namespace RGB.NET.Devices.Razer if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) && (!LoadEmulatorDevices || (Razer.Devices.KEYBOARDS.FirstOrDefault().guid != guid))) continue; - RazerKeyboardRGBDevice device = new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(guid, model, GetCulture())); + RazerKeyboardRGBDevice device = new(new RazerKeyboardRGBDeviceInfo(guid, model)); device.Initialize(UpdateTrigger); devices.Add(device); } @@ -134,7 +117,7 @@ namespace RGB.NET.Devices.Razer if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) && (!LoadEmulatorDevices || (Razer.Devices.MICE.FirstOrDefault().guid != guid))) continue; - RazerMouseRGBDevice device = new RazerMouseRGBDevice(new RazerMouseRGBDeviceInfo(guid, model)); + RazerMouseRGBDevice device = new(new RazerMouseRGBDeviceInfo(guid, model)); device.Initialize(UpdateTrigger); devices.Add(device); } @@ -147,7 +130,7 @@ namespace RGB.NET.Devices.Razer if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) && (!LoadEmulatorDevices || (Razer.Devices.HEADSETS.FirstOrDefault().guid != guid))) continue; - RazerHeadsetRGBDevice device = new RazerHeadsetRGBDevice(new RazerHeadsetRGBDeviceInfo(guid, model)); + RazerHeadsetRGBDevice device = new(new RazerHeadsetRGBDeviceInfo(guid, model)); device.Initialize(UpdateTrigger); devices.Add(device); } @@ -160,7 +143,7 @@ namespace RGB.NET.Devices.Razer if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) && (!LoadEmulatorDevices || (Razer.Devices.MOUSEMATS.FirstOrDefault().guid != guid))) continue; - RazerMousepadRGBDevice device = new RazerMousepadRGBDevice(new RazerMousepadRGBDeviceInfo(guid, model)); + RazerMousepadRGBDevice device = new(new RazerMousepadRGBDeviceInfo(guid, model)); device.Initialize(UpdateTrigger); devices.Add(device); } @@ -173,7 +156,7 @@ namespace RGB.NET.Devices.Razer if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) && (!LoadEmulatorDevices || (Razer.Devices.KEYPADS.FirstOrDefault().guid != guid))) continue; - RazerKeypadRGBDevice device = new RazerKeypadRGBDevice(new RazerKeypadRGBDeviceInfo(guid, model)); + RazerKeypadRGBDevice device = new(new RazerKeypadRGBDeviceInfo(guid, model)); device.Initialize(UpdateTrigger); devices.Add(device); } @@ -186,13 +169,13 @@ namespace RGB.NET.Devices.Razer if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) && (!LoadEmulatorDevices || (Razer.Devices.CHROMALINKS.FirstOrDefault().guid != guid))) continue; - RazerChromaLinkRGBDevice device = new RazerChromaLinkRGBDevice(new RazerChromaLinkRGBDeviceInfo(guid, model)); + RazerChromaLinkRGBDevice device = new(new RazerChromaLinkRGBDeviceInfo(guid, model)); device.Initialize(UpdateTrigger); devices.Add(device); } catch { if (throwExceptions) throw; } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; } @@ -205,14 +188,7 @@ namespace RGB.NET.Devices.Razer return true; } - - /// - public void ResetDevices() - { - foreach (IRGBDevice device in Devices) - ((IRazerRGBDevice)device).Reset(); - } - + private void ThrowRazerError(RazerError errorCode) => throw new RazerException(errorCode); private void TryUnInit() @@ -224,9 +200,14 @@ namespace RGB.NET.Devices.Razer /// public void Dispose() { - try { UpdateTrigger?.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(); + TryUnInit(); // DarthAffe 03.03.2020: Fails with an access-violation - verify if an unload is already triggered by uninit diff --git a/RGB.NET.Devices.Razer/RazerDeviceProviderLoader.cs b/RGB.NET.Devices.Razer/RazerDeviceProviderLoader.cs deleted file mode 100644 index 2f3d306..0000000 --- a/RGB.NET.Devices.Razer/RazerDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// Represents a device provider loaded used to dynamically load razer devices into an application. - /// - public class RazerDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => RazerDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs b/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs index 2fde5f8..f5f9c52 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs @@ -5,6 +5,6 @@ namespace RGB.NET.Devices.SteelSeries.API.Model internal class CoreProps { [JsonPropertyName("address")] - public string Address { get; set; } + public string? Address { get; set; } } } diff --git a/RGB.NET.Devices.SteelSeries/API/Model/Event.cs b/RGB.NET.Devices.SteelSeries/API/Model/Event.cs index 2e5f043..0a7935c 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/Event.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/Event.cs @@ -8,13 +8,13 @@ namespace RGB.NET.Devices.SteelSeries.API.Model #region Properties & Fields [JsonPropertyName("game")] - public string Game { get; set; } + public string? Game { get; set; } [JsonPropertyName("event")] - public string Name { get; set; } + public string? Name { get; set; } [JsonPropertyName("data")] - public Dictionary Data { get; } = new Dictionary(); + public Dictionary Data { get; } = new(); #endregion diff --git a/RGB.NET.Devices.SteelSeries/API/Model/Game.cs b/RGB.NET.Devices.SteelSeries/API/Model/Game.cs index 33c62b1..fc418da 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/Game.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/Game.cs @@ -7,10 +7,10 @@ namespace RGB.NET.Devices.SteelSeries.API.Model #region Properties & Fields [JsonPropertyName("game")] - public string Name { get; set; } + public string? Name { get; set; } [JsonPropertyName("game_display_name")] - public string DisplayName { get; set; } + public string? DisplayName { get; set; } #endregion diff --git a/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs b/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs index f84b4b5..7ccf389 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs @@ -7,10 +7,10 @@ namespace RGB.NET.Devices.SteelSeries.API.Model #region Properties & Fields [JsonPropertyName("game")] - public string Game { get; set; } + public string? Game { get; set; } [JsonPropertyName("golisp")] - public string Handler { get; set; } + public string? Handler { get; set; } #endregion diff --git a/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs b/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs index 012d749..4d36107 100644 --- a/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs +++ b/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs @@ -6,7 +6,6 @@ using System.Net.Http; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; -using System.Text.Json.Serialization; using RGB.NET.Devices.SteelSeries.API.Model; namespace RGB.NET.Devices.SteelSeries.API @@ -55,10 +54,10 @@ namespace RGB.NET.Devices.SteelSeries.API #region Properties & Fields // ReSharper disable InconsistentNaming - private static readonly HttpClient _client = new HttpClient(); - private static readonly Game _game = new Game(GAME_NAME, GAME_DISPLAYNAME); - private static readonly Event _event = new Event(_game, EVENT_NAME); - private static string _baseUrl; + private static readonly HttpClient _client = new(); + private static readonly Game _game = new(GAME_NAME, GAME_DISPLAYNAME); + private static readonly Event _event = new(_game, EVENT_NAME); + private static string? _baseUrl; internal static bool IsInitialized => !string.IsNullOrWhiteSpace(_baseUrl); @@ -74,7 +73,7 @@ namespace RGB.NET.Devices.SteelSeries.API string corePropsPath = GetCorePropsPath(); if (!string.IsNullOrWhiteSpace(corePropsPath) && File.Exists(corePropsPath)) { - CoreProps coreProps = JsonSerializer.Deserialize(File.ReadAllText(corePropsPath)); + CoreProps? coreProps = JsonSerializer.Deserialize(File.ReadAllText(corePropsPath)); _baseUrl = coreProps?.Address; if (_baseUrl != null) { @@ -93,12 +92,12 @@ namespace RGB.NET.Devices.SteelSeries.API return IsInitialized; } - internal static void UpdateLeds(string device, Dictionary data) + internal static void UpdateLeds(string device, IList<(string zone, int[] color)> data) { _event.Data.Clear(); _event.Data.Add("value", device); - _event.Data.Add("colors", data.Values.ToList()); - _event.Data.Add("zones", data.Keys.ToList()); + _event.Data.Add("colors", data.Select(x => x.color).ToList()); + _event.Data.Add("zones", data.Select(x => x.zone).ToList()); TriggerEvent(_event); } diff --git a/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs b/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs index 3331a50..ce41a96 100644 --- a/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs +++ b/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs @@ -10,31 +10,31 @@ namespace RGB.NET.Devices.SteelSeries #region Properties & Fields // ReSharper disable InconsistentNaming - private static readonly Dictionary _deviceTypeNames = new Dictionary(); - private static readonly Dictionary _ledIdNames = new Dictionary(); + private static readonly Dictionary _deviceTypeNames = new(); + private static readonly Dictionary _ledIdNames = new(); // ReSharper restore InconsistentNaming #endregion #region Methods - internal static string GetAPIName(this SteelSeriesDeviceType deviceType) + internal static string? GetAPIName(this SteelSeriesDeviceType deviceType) { - if (!_deviceTypeNames.TryGetValue(deviceType, out string apiName)) + if (!_deviceTypeNames.TryGetValue(deviceType, out string? apiName)) _deviceTypeNames.Add(deviceType, apiName = GetAPIName(typeof(SteelSeriesDeviceType), deviceType)); return apiName; } - internal static string GetAPIName(this SteelSeriesLedId ledId) + internal static string? GetAPIName(this SteelSeriesLedId ledId) { - if (!_ledIdNames.TryGetValue(ledId, out string apiName)) + if (!_ledIdNames.TryGetValue(ledId, out string? apiName)) _ledIdNames.Add(ledId, apiName = GetAPIName(typeof(SteelSeriesLedId), ledId)); return apiName; } - private static string GetAPIName(Type type, Enum value) + private static string? GetAPIName(Type type, Enum value) { MemberInfo[] memInfo = type.GetMember(value.ToString()); if (memInfo.Length == 0) return null; diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs index c2befb6..25de272 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs @@ -35,9 +35,9 @@ namespace RGB.NET.Devices.SteelSeries #region Methods - protected override void OnUpdate(object sender, CustomUpdateData customData) + protected override void OnUpdate(object? sender, CustomUpdateData customData) { - if ((customData != null) && (customData["refresh"] as bool? ?? false)) + if (customData["refresh"] as bool? ?? false) SteelSeriesSDK.SendHeartbeat(); else base.OnUpdate(sender, customData); @@ -45,7 +45,7 @@ namespace RGB.NET.Devices.SteelSeries /// protected override void Update(Dictionary dataSet) - => SteelSeriesSDK.UpdateLeds(_deviceType, dataSet.ToDictionary(x => ((SteelSeriesLedId)x.Key).GetAPIName(), x => x.Value.ToIntArray())); + => SteelSeriesSDK.UpdateLeds(_deviceType, dataSet.Select(x => (((SteelSeriesLedId)x.Key).GetAPIName(), x.Value.ToIntArray())).Where(x => x.Item1 != null).ToList()!); #endregion } diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs index c6a6823..cf33016 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs @@ -71,7 +71,7 @@ namespace RGB.NET.Devices.SteelSeries } /// - protected override void OnUpdate(CustomUpdateData updateData = null) + protected override void OnUpdate(CustomUpdateData? updateData = null) { base.OnUpdate(updateData); _lastUpdateTimestamp = Stopwatch.GetTimestamp(); diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs index ec59fd3..255dd90 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs @@ -13,7 +13,7 @@ namespace RGB.NET.Devices.SteelSeries { #region Properties & Fields - private Dictionary _ledMapping; + private Dictionary _ledMapping = new(); /// /// @@ -25,7 +25,7 @@ namespace RGB.NET.Devices.SteelSeries /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue UpdateQueue { get; set; } + protected UpdateQueue? UpdateQueue { get; set; } #endregion @@ -53,35 +53,22 @@ namespace RGB.NET.Devices.SteelSeries int counter = 0; foreach (KeyValuePair mapping in ledMapping) - InitializeLed(mapping.Key, new Rectangle((counter++) * 10, 0, 10, 10)); - - InitializeLayout(); + AddLed(mapping.Key, new Point((counter++) * 10, 0), new Size(10, 10)); if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } UpdateQueue = updateQueue; } - protected override object CreateLedCustomData(LedId ledId) => _ledMapping[ledId]; + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); - - /// - /// Initializes the and of the device. - /// - protected virtual void InitializeLayout() - { - if (!(DeviceInfo is SteelSeriesRGBDeviceInfo info)) return; - - string layout = info.ImageLayout; - string layoutPath = info.LayoutPath; - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\SteelSeries", $"{layoutPath}.xml"), layout, true); - } + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); /// public override void Dispose() diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs index cb356c7..96ba1f1 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.SteelSeries { @@ -24,23 +23,10 @@ namespace RGB.NET.Devices.SteelSeries public string Model { get; } /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - public SteelSeriesDeviceType SteelSeriesDeviceType { get; } - - /// - /// Gets the layout used to decide which images to load. - /// - internal string ImageLayout { get; } - - /// - /// Gets the path/name of the layout-file. - /// - internal string LayoutPath { get; } - + #endregion #region Constructors @@ -53,13 +39,11 @@ namespace RGB.NET.Devices.SteelSeries /// The lighting-capabilities of the device. /// The layout used to decide which images to load. /// The path/name of the layout-file. - internal SteelSeriesRGBDeviceInfo(RGBDeviceType deviceType, string model, SteelSeriesDeviceType steelSeriesDeviceType, string imageLayout, string layoutPath) + internal SteelSeriesRGBDeviceInfo(RGBDeviceType deviceType, string model, SteelSeriesDeviceType steelSeriesDeviceType) { this.DeviceType = deviceType; this.Model = model; this.SteelSeriesDeviceType = steelSeriesDeviceType; - this.ImageLayout = imageLayout; - this.LayoutPath = layoutPath; DeviceName = $"{Manufacturer} {Model}"; } diff --git a/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs b/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs index 16192db..deca9f3 100644 --- a/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs +++ b/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs @@ -2,7 +2,7 @@ using System.Linq; using HidSharp; using RGB.NET.Core; -using DeviceDataList = System.Collections.Generic.List<(string model, RGB.NET.Core.RGBDeviceType deviceType, int id, RGB.NET.Devices.SteelSeries.SteelSeriesDeviceType steelSeriesDeviceType, string imageLayout, string layoutPath, System.Collections.Generic.Dictionary ledMapping)>; +using DeviceDataList = System.Collections.Generic.List<(string model, RGB.NET.Core.RGBDeviceType deviceType, int id, RGB.NET.Devices.SteelSeries.SteelSeriesDeviceType steelSeriesDeviceType, System.Collections.Generic.Dictionary ledMapping)>; using LedMapping = System.Collections.Generic.Dictionary; namespace RGB.NET.Devices.SteelSeries.HID @@ -11,7 +11,7 @@ namespace RGB.NET.Devices.SteelSeries.HID { #region Constants - private static readonly LedMapping KEYBOARD_MAPPING_UK = new LedMapping + private static readonly LedMapping KEYBOARD_MAPPING_UK = new() { { LedId.Logo, SteelSeriesLedId.Logo }, { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, @@ -121,7 +121,7 @@ namespace RGB.NET.Devices.SteelSeries.HID { LedId.Keyboard_NumPeriodAndDelete, SteelSeriesLedId.KeypadPeriod } }; - private static readonly LedMapping KEYBOARD_TKL_MAPPING_UK = new LedMapping + private static readonly LedMapping KEYBOARD_TKL_MAPPING_UK = new() { { LedId.Logo, SteelSeriesLedId.Logo }, { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, @@ -214,87 +214,87 @@ namespace RGB.NET.Devices.SteelSeries.HID { LedId.Keyboard_ArrowRight, SteelSeriesLedId.RightArrow } }; - private static readonly LedMapping MOUSE_ONE_ZONE = new LedMapping + private static readonly LedMapping MOUSE_ONE_ZONE = new() { - {LedId.Mouse1, SteelSeriesLedId.ZoneOne} + { LedId.Mouse1, SteelSeriesLedId.ZoneOne } }; - private static readonly LedMapping MOUSE_TWO_ZONE = new LedMapping - { - {LedId.Mouse1, SteelSeriesLedId.ZoneOne}, - {LedId.Mouse2, SteelSeriesLedId.ZoneTwo} - }; + private static readonly LedMapping MOUSE_TWO_ZONE = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo } + }; - private static readonly LedMapping MOUSE_THREE_ZONE = new LedMapping - { - {LedId.Mouse1, SteelSeriesLedId.ZoneOne}, - {LedId.Mouse2, SteelSeriesLedId.ZoneTwo}, - {LedId.Mouse3, SteelSeriesLedId.ZoneThree} - }; - - private static readonly LedMapping MOUSE_EIGHT_ZONE = new LedMapping - { - { LedId.Mouse1, SteelSeriesLedId.ZoneOne}, - { LedId.Mouse2, SteelSeriesLedId.ZoneTwo}, - { LedId.Mouse3, SteelSeriesLedId.ZoneThree}, - { LedId.Mouse4, SteelSeriesLedId.ZoneFour}, - { LedId.Mouse5, SteelSeriesLedId.ZoneFive}, - { LedId.Mouse6, SteelSeriesLedId.ZoneSix}, - { LedId.Mouse7, SteelSeriesLedId.ZoneSeven}, - { LedId.Mouse8, SteelSeriesLedId.ZoneEight} - }; - - private static readonly LedMapping HEADSET_TWO_ZONE = new LedMapping + private static readonly LedMapping MOUSE_THREE_ZONE = new() { - {LedId.Headset1, SteelSeriesLedId.ZoneOne}, - {LedId.Headset2, SteelSeriesLedId.ZoneTwo} + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo }, + { LedId.Mouse3, SteelSeriesLedId.ZoneThree } }; - + + private static readonly LedMapping MOUSE_EIGHT_ZONE = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo }, + { LedId.Mouse3, SteelSeriesLedId.ZoneThree }, + { LedId.Mouse4, SteelSeriesLedId.ZoneFour }, + { LedId.Mouse5, SteelSeriesLedId.ZoneFive }, + { LedId.Mouse6, SteelSeriesLedId.ZoneSix }, + { LedId.Mouse7, SteelSeriesLedId.ZoneSeven }, + { LedId.Mouse8, SteelSeriesLedId.ZoneEight } + }; + + private static readonly LedMapping HEADSET_TWO_ZONE = new() + { + { LedId.Headset1, SteelSeriesLedId.ZoneOne }, + { LedId.Headset2, SteelSeriesLedId.ZoneTwo } + }; + private const int VENDOR_ID = 0x1038; //TODO DarthAffe 16.02.2019: Add devices - private static readonly DeviceDataList DEVICES = new DeviceDataList + private static readonly DeviceDataList DEVICES = new() { //Mice - ("Aerox 3", RGBDeviceType.Mouse, 0x1836, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Aerox3", MOUSE_THREE_ZONE), - ("Aerox 3 Wireless", RGBDeviceType.Mouse, 0x183A, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Aerox3Wireless", MOUSE_THREE_ZONE), - ("Rival 100", RGBDeviceType.Mouse, 0x1702, SteelSeriesDeviceType.OneZone, "default", @"Mice\Rival100", MOUSE_ONE_ZONE), - ("Rival 105", RGBDeviceType.Mouse, 0x1814, SteelSeriesDeviceType.OneZone, "default", @"Mice\Rival105", MOUSE_ONE_ZONE), - ("Rival 106", RGBDeviceType.Mouse, 0x1816, SteelSeriesDeviceType.OneZone, "default", @"Mice\Rival106", MOUSE_ONE_ZONE), - ("Rival 110", RGBDeviceType.Mouse, 0x1729, SteelSeriesDeviceType.OneZone, "default", @"Mice\Rival110", MOUSE_ONE_ZONE), - ("Rival 150", RGBDeviceType.Mouse, 0x0472, SteelSeriesDeviceType.OneZone, "default", @"Mice\Rival150", MOUSE_ONE_ZONE), - ("Rival 300", RGBDeviceType.Mouse, 0x1710, SteelSeriesDeviceType.TwoZone, "default", @"Mice\Rival300", MOUSE_TWO_ZONE), - ("Rival 310", RGBDeviceType.Mouse, 0x1720, SteelSeriesDeviceType.TwoZone, "default", @"Mice\Rival310", MOUSE_TWO_ZONE), - ("Rival 500", RGBDeviceType.Mouse, 0x170E, SteelSeriesDeviceType.TwoZone, "default", @"Mice\Rival500", MOUSE_TWO_ZONE), - ("Rival 600", RGBDeviceType.Mouse, 0x1724, SteelSeriesDeviceType.EightZone, "default", @"Mice\Rival600", MOUSE_EIGHT_ZONE), - ("Rival 700", RGBDeviceType.Mouse, 0x1700, SteelSeriesDeviceType.TwoZone, "default", @"Mice\Rival700", MOUSE_TWO_ZONE), - ("Rival 3 (Old Firmware)", RGBDeviceType.Mouse, 0x1824, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Rival3", MOUSE_THREE_ZONE), - ("Rival 3", RGBDeviceType.Mouse, 0x184C, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Rival3", MOUSE_THREE_ZONE), - ("Rival 3 Wireless", RGBDeviceType.Mouse, 0x1830, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Rival3Wireless", MOUSE_THREE_ZONE), - ("Sensei Ten", RGBDeviceType.Mouse, 0x1832, SteelSeriesDeviceType.TwoZone, "default", @"Mice\SenseiTen", MOUSE_TWO_ZONE), + ("Aerox 3", RGBDeviceType.Mouse, 0x1836, SteelSeriesDeviceType.ThreeZone, MOUSE_THREE_ZONE), + ("Aerox 3 Wireless", RGBDeviceType.Mouse, 0x183A, SteelSeriesDeviceType.ThreeZone, MOUSE_THREE_ZONE), + ("Rival 100", RGBDeviceType.Mouse, 0x1702, SteelSeriesDeviceType.OneZone, MOUSE_ONE_ZONE), + ("Rival 105", RGBDeviceType.Mouse, 0x1814, SteelSeriesDeviceType.OneZone, MOUSE_ONE_ZONE), + ("Rival 106", RGBDeviceType.Mouse, 0x1816, SteelSeriesDeviceType.OneZone, MOUSE_ONE_ZONE), + ("Rival 110", RGBDeviceType.Mouse, 0x1729, SteelSeriesDeviceType.OneZone, MOUSE_ONE_ZONE), + ("Rival 150", RGBDeviceType.Mouse, 0x0472, SteelSeriesDeviceType.OneZone, MOUSE_ONE_ZONE), + ("Rival 300", RGBDeviceType.Mouse, 0x1710, SteelSeriesDeviceType.TwoZone, MOUSE_TWO_ZONE), + ("Rival 310", RGBDeviceType.Mouse, 0x1720, SteelSeriesDeviceType.TwoZone, MOUSE_TWO_ZONE), + ("Rival 500", RGBDeviceType.Mouse, 0x170E, SteelSeriesDeviceType.TwoZone, MOUSE_TWO_ZONE), + ("Rival 600", RGBDeviceType.Mouse, 0x1724, SteelSeriesDeviceType.EightZone, MOUSE_EIGHT_ZONE), + ("Rival 700", RGBDeviceType.Mouse, 0x1700, SteelSeriesDeviceType.TwoZone, MOUSE_TWO_ZONE), + ("Rival 3 (Old Firmware)", RGBDeviceType.Mouse, 0x1824, SteelSeriesDeviceType.ThreeZone, MOUSE_THREE_ZONE), + ("Rival 3", RGBDeviceType.Mouse, 0x184C, SteelSeriesDeviceType.ThreeZone, MOUSE_THREE_ZONE), + ("Rival 3 Wireless", RGBDeviceType.Mouse, 0x1830, SteelSeriesDeviceType.ThreeZone, MOUSE_THREE_ZONE), + ("Sensei Ten", RGBDeviceType.Mouse, 0x1832, SteelSeriesDeviceType.TwoZone, MOUSE_TWO_ZONE), //Keyboards - ("Apex 5", RGBDeviceType.Keyboard, 0x161C, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\5\UK", KEYBOARD_MAPPING_UK), - ("Apex 7", RGBDeviceType.Keyboard, 0x1612, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\7\UK", KEYBOARD_MAPPING_UK), - ("Apex 7 TKL", RGBDeviceType.Keyboard, 0x1618, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\7TKL\UK", KEYBOARD_TKL_MAPPING_UK), - ("Apex M750", RGBDeviceType.Keyboard, 0x0616, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\M750\UK", KEYBOARD_MAPPING_UK), - ("Apex M800", RGBDeviceType.Keyboard, 0x1600, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\M800\UK", KEYBOARD_MAPPING_UK), - ("Apex Pro", RGBDeviceType.Keyboard, 0x1610, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\Pro\UK", KEYBOARD_MAPPING_UK), - ("Apex Pro TKL", RGBDeviceType.Keyboard, 0x1614, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\ProTKL\UK", KEYBOARD_TKL_MAPPING_UK), + ("Apex 5", RGBDeviceType.Keyboard, 0x161C, SteelSeriesDeviceType.PerKey, KEYBOARD_MAPPING_UK), + ("Apex 7", RGBDeviceType.Keyboard, 0x1612, SteelSeriesDeviceType.PerKey, KEYBOARD_MAPPING_UK), + ("Apex 7 TKL", RGBDeviceType.Keyboard, 0x1618, SteelSeriesDeviceType.PerKey, KEYBOARD_TKL_MAPPING_UK), + ("Apex M750", RGBDeviceType.Keyboard, 0x0616, SteelSeriesDeviceType.PerKey, KEYBOARD_MAPPING_UK), + ("Apex M800", RGBDeviceType.Keyboard, 0x1600, SteelSeriesDeviceType.PerKey, KEYBOARD_MAPPING_UK), + ("Apex Pro", RGBDeviceType.Keyboard, 0x1610, SteelSeriesDeviceType.PerKey, KEYBOARD_MAPPING_UK), + ("Apex Pro TKL", RGBDeviceType.Keyboard, 0x1614, SteelSeriesDeviceType.PerKey, KEYBOARD_TKL_MAPPING_UK), //Headsets - ("Arctis 5", RGBDeviceType.Headset, 0x12AA, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Game", RGBDeviceType.Headset, 0x1250, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Game - Dota 2 edition", RGBDeviceType.Headset, 0x1251, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Game - PUBG edition", RGBDeviceType.Headset, 0x12A8, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis Pro Game", RGBDeviceType.Headset, 0x1252, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), + ("Arctis 5", RGBDeviceType.Headset, 0x12AA, SteelSeriesDeviceType.TwoZone, HEADSET_TWO_ZONE), + ("Arctis 5 Game", RGBDeviceType.Headset, 0x1250, SteelSeriesDeviceType.TwoZone, HEADSET_TWO_ZONE), + ("Arctis 5 Game - Dota 2 edition", RGBDeviceType.Headset, 0x1251, SteelSeriesDeviceType.TwoZone, HEADSET_TWO_ZONE), + ("Arctis 5 Game - PUBG edition", RGBDeviceType.Headset, 0x12A8, SteelSeriesDeviceType.TwoZone, HEADSET_TWO_ZONE), + ("Arctis Pro Game", RGBDeviceType.Headset, 0x1252, SteelSeriesDeviceType.TwoZone, HEADSET_TWO_ZONE), }; #endregion #region Properties & Fields - public static DeviceDataList ConnectedDevices { get; } = new DeviceDataList(); + public static DeviceDataList ConnectedDevices { get; } = new(); #endregion @@ -304,7 +304,7 @@ namespace RGB.NET.Devices.SteelSeries.HID { ConnectedDevices.Clear(); - HashSet ids = new HashSet(DeviceList.Local.GetHidDevices(VENDOR_ID).Select(x => x.ProductID).Distinct()); + HashSet ids = new(DeviceList.Local.GetHidDevices(VENDOR_ID).Select(x => x.ProductID).Distinct()); DeviceDataList connectedDevices = DEVICES.Where(d => ids.Contains(d.id) && loadFilter.HasFlag(d.deviceType)).ToList(); List connectedDeviceTypes = connectedDevices.Select(d => d.steelSeriesDeviceType).ToList(); diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs index 21402dd..f42885f 100644 --- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs +++ b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs @@ -1,6 +1,7 @@ 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; @@ -15,7 +16,7 @@ namespace RGB.NET.Devices.SteelSeries { #region Properties & Fields - private static SteelSeriesDeviceProvider _instance; + private static SteelSeriesDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -28,13 +29,7 @@ namespace RGB.NET.Devices.SteelSeries public bool IsInitialized { get; private set; } /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// The used to trigger the updates for SteelSeries devices. @@ -62,13 +57,13 @@ namespace RGB.NET.Devices.SteelSeries #region Methods /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { try { IsInitialized = false; - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); if (!SteelSeriesSDK.IsInitialized) SteelSeriesSDK.Initialize(); @@ -78,17 +73,18 @@ namespace RGB.NET.Devices.SteelSeries try { - foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, string imageLayout, string layoutPath, Dictionary ledMapping) in DeviceChecker.ConnectedDevices) + foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, Dictionary ledMapping) in DeviceChecker.ConnectedDevices) { - ISteelSeriesRGBDevice device = new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(deviceType, model, steelSeriesDeviceType, imageLayout, layoutPath)); - SteelSeriesDeviceUpdateQueue updateQueue = new SteelSeriesDeviceUpdateQueue(UpdateTrigger, steelSeriesDeviceType.GetAPIName()); + 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(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -102,24 +98,18 @@ namespace RGB.NET.Devices.SteelSeries return true; } - - /// - public void ResetDevices() - { - if (IsInitialized) - try - { - SteelSeriesSDK.ResetLeds(); - } - catch {/* shit happens */} - } - + /// public void Dispose() { - try { UpdateTrigger?.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(); + try { SteelSeriesSDK.Dispose(); } catch { /* shit happens */ } } diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProviderLoader.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProviderLoader.cs deleted file mode 100644 index ffe1938..0000000 --- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProviderLoader.cs +++ /dev/null @@ -1,25 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.SteelSeries -{ - /// - /// Represents a device provider loaded used to dynamically load steelseries devices into an application. - /// - // ReSharper disable once UnusedMember.Global - public class SteelSeriesDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => SteelSeriesDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs index c940db4..53327cb 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs @@ -53,22 +53,20 @@ namespace RGB.NET.Devices.WS281X.Arduino internal void Initialize(int ledCount) { for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.LedStripe1 + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 23.12.2018: Allow to load a layout. + AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } } /// - protected override object CreateLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); + protected override object GetLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); /// - protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : null; + 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)); @@ -76,7 +74,7 @@ namespace RGB.NET.Devices.WS281X.Arduino /// public override void Dispose() { - try { UpdateQueue?.Dispose(); } + try { UpdateQueue.Dispose(); } catch { /* at least we tried */ } base.Dispose(); diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs index 9fbb965..2a78759 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.WS281X.Arduino { @@ -25,10 +24,7 @@ namespace RGB.NET.Devices.WS281X.Arduino public string Model => "WS2812 USB"; /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } #endregion diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs index 6b2c1cb..ebe5a76 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs @@ -21,7 +21,7 @@ namespace RGB.NET.Devices.WS281X.Arduino #region Properties & Fields - private readonly Dictionary _dataBuffer = new Dictionary(); + private readonly Dictionary _dataBuffer = new(); #endregion @@ -42,7 +42,7 @@ namespace RGB.NET.Devices.WS281X.Arduino #region Methods /// - protected override void OnStartup(object sender, CustomUpdateData customData) + protected override void OnStartup(object? sender, CustomUpdateData customData) { base.OnStartup(sender, customData); @@ -56,7 +56,7 @@ namespace RGB.NET.Devices.WS281X.Arduino .GroupBy(x => x.Item1.channel)) { int channel = channelData.Key; - if (!_dataBuffer.TryGetValue(channel, out byte[] dataBuffer) || (dataBuffer.Length != ((dataSet.Count * 3) + 1))) + if (!_dataBuffer.TryGetValue(channel, out byte[]? dataBuffer) || (dataBuffer.Length != ((dataSet.Count * 3) + 1))) _dataBuffer[channel] = dataBuffer = new byte[(dataSet.Count * 3) + 1]; dataBuffer[0] = (byte)((channel << 4) | UPDATE_COMMAND[0]); diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs index ff1b88f..c6aa63c 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs @@ -24,18 +24,18 @@ namespace RGB.NET.Devices.WS281X.Arduino /// /// Gets the name of the serial-port to connect to. /// - public string Port => SerialConnection?.Port; + public string Port => SerialConnection.Port; /// /// Gets the baud-rate used by the serial-connection. /// - public int BaudRate => SerialConnection?.BaudRate ?? 0; + public int BaudRate => SerialConnection.BaudRate; /// /// Gets or sets the name used by this device. /// This allows to use {0} as a placeholder for a incrementing number if multiple devices are created. /// - public string Name { get; set; } + public string? Name { get; set; } #endregion @@ -67,13 +67,13 @@ namespace RGB.NET.Devices.WS281X.Arduino /// public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) { - ArduinoWS2812USBUpdateQueue queue = new ArduinoWS2812USBUpdateQueue(updateTrigger, SerialConnection); + 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 ArduinoWS2812USBDevice(new ArduinoWS2812USBDeviceInfo(name), queue, channel); + ArduinoWS2812USBDevice device = new(new ArduinoWS2812USBDeviceInfo(name), queue, channel); device.Initialize(ledCount); yield return device; } diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs index 51f6d56..f76ab40 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs @@ -50,19 +50,17 @@ namespace RGB.NET.Devices.WS281X.Bitwizard internal void Initialize(int ledCount) { for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.LedStripe1 + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 23.12.2018: Allow to load a layout. + AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } } /// - protected override object CreateLedCustomData(LedId ledId) => _ledOffset + ((int)ledId - (int)LedId.LedStripe1); + 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)); @@ -70,7 +68,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// public override void Dispose() { - try { UpdateQueue?.Dispose(); } + try { UpdateQueue.Dispose(); } catch { /* at least we tried */ } base.Dispose(); diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs index 311b0d4..0f980f7 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.WS281X.Bitwizard { @@ -25,10 +24,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard public string Model => "WS2812 USB"; /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } #endregion diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs index dd6acc0..242b6d1 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs @@ -28,7 +28,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard #region Methods /// - protected override void OnStartup(object sender, CustomUpdateData customData) + protected override void OnStartup(object? sender, CustomUpdateData customData) { base.OnStartup(sender, customData); @@ -38,8 +38,8 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// protected override IEnumerable GetCommands(Dictionary dataSet) { - foreach (KeyValuePair data in dataSet) - yield return $"pix {(int)data.Key} {data.Value.AsRGBHexString(false)}"; + foreach ((object key, Color value) in dataSet) + yield return $"pix {(int)key} {value.AsRGBHexString(false)}"; } #endregion diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs index f4f784c..3a46ac1 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs @@ -24,17 +24,17 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// /// Gets the name of the serial-port to connect to. /// - public string Port => SerialConnection?.Port; + public string Port => SerialConnection.Port; /// /// Gets the baud-rate used by the serial-connection. /// - public int BaudRate => SerialConnection?.BaudRate ?? 0; + public int BaudRate => SerialConnection.BaudRate; /// /// Gets or sets the name used by this device. /// - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the pin sed to control the leds. @@ -82,10 +82,10 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) { - BitwizardWS2812USBUpdateQueue queue = new BitwizardWS2812USBUpdateQueue(updateTrigger, SerialConnection); + BitwizardWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection); string name = Name ?? $"Bitwizard WS2812 USB ({Port})"; int ledOffset = Pin * MaxStripLength; - BitwizardWS2812USBDevice device = new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset); + BitwizardWS2812USBDevice device = new(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset); device.Initialize(StripLength); yield return device; } diff --git a/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs b/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs index 0f343da..b3f2b4e 100644 --- a/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.IO.Ports; using RGB.NET.Core; namespace RGB.NET.Devices.WS281X @@ -46,7 +45,7 @@ namespace RGB.NET.Devices.WS281X #region Methods /// - protected override void OnStartup(object sender, CustomUpdateData customData) + protected override void OnStartup(object? sender, CustomUpdateData customData) { base.OnStartup(sender, customData); diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs index 4b03b81..6b24a74 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs @@ -53,22 +53,20 @@ namespace RGB.NET.Devices.WS281X.NodeMCU internal void Initialize(int ledCount) { for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); - - //TODO DarthAffe 23.12.2018: Allow to load a layout. + AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } } /// - protected override object CreateLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); + protected override object GetLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); /// - protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : null; + 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)); @@ -76,7 +74,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU /// public override void Dispose() { - try { UpdateQueue?.Dispose(); } + try { UpdateQueue.Dispose(); } catch { /* at least we tried */ } base.Dispose(); diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs index 935dcf9..ed18fb6 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; namespace RGB.NET.Devices.WS281X.NodeMCU { @@ -25,10 +24,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU public string Model => "WS2812 WLAN"; /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } #endregion diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs index f5feffe..2c020c4 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs @@ -20,11 +20,11 @@ namespace RGB.NET.Devices.WS281X.NodeMCU private readonly string _hostname; - private HttpClient _httpClient = new HttpClient(); - private UdpClient _udpClient; + private HttpClient _httpClient = new(); + private UdpClient? _udpClient; - private readonly Dictionary _dataBuffer = new Dictionary(); - private readonly Dictionary _sequenceNumbers = new Dictionary(); + private readonly Dictionary _dataBuffer = new(); + private readonly Dictionary _sequenceNumbers = new(); private readonly Action _sendDataAction; @@ -69,7 +69,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU #region Methods /// - protected override void OnStartup(object sender, CustomUpdateData customData) + protected override void OnStartup(object? sender, CustomUpdateData customData) { base.OnStartup(sender, customData); @@ -90,7 +90,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU private void SendHttp(byte[] buffer) { string data = Convert.ToBase64String(buffer); - lock (_httpClient) _httpClient?.PostAsync(GetUrl("update"), new StringContent(data, Encoding.ASCII)).Wait(); + lock (_httpClient) _httpClient.PostAsync(GetUrl("update"), new StringContent(data, Encoding.ASCII)).Wait(); } private void SendUdp(byte[] buffer) @@ -149,7 +149,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU private void EnableUdp(int port) { _httpClient.PostAsync(GetUrl("enableUDP"), new StringContent(port.ToString(), Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Wait(); - _udpClient.Connect(_hostname, port); + _udpClient?.Connect(_hostname, port); } private byte GetSequenceNumber(int channel) @@ -166,14 +166,11 @@ namespace RGB.NET.Devices.WS281X.NodeMCU { base.Dispose(); -#if NETSTANDARD _udpClient?.Dispose(); -#endif _udpClient = null; ResetDevice(); _httpClient.Dispose(); - _httpClient = null; } } diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs index f573eab..b87f39e 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs @@ -36,7 +36,7 @@ namespace RGB.NET.Devices.WS281X.NodeMCU /// Gets or sets the name used by this device. /// This allows to use {0} as a placeholder for a incrementing number if multiple devices are created. /// - public string Name { get; set; } + public string? Name { get; set; } #endregion @@ -72,7 +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 NodeMCUWS2812USBDevice(new NodeMCUWS2812USBDeviceInfo(name), queue, channel); + NodeMCUWS2812USBDevice device = new(new NodeMCUWS2812USBDeviceInfo(name), queue, channel); device.Initialize(ledCount); yield return device; } diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs index 3875cf4..aeee841 100644 --- a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs +++ b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs @@ -3,8 +3,8 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using RGB.NET.Core; -using RGB.NET.Devices.WS281X.NodeMCU; namespace RGB.NET.Devices.WS281X { @@ -17,7 +17,7 @@ namespace RGB.NET.Devices.WS281X { #region Properties & Fields - private static WS281XDeviceProvider _instance; + private static WS281XDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -27,17 +27,14 @@ namespace RGB.NET.Devices.WS281X public bool IsInitialized { get; private set; } /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; + public IEnumerable Devices { get; private set; } = Enumerable.Empty(); /// /// Gets a list of all defined device-definitions. /// // ReSharper disable once CollectionNeverUpdated.Global // ReSharper disable once ReturnTypeCanBeEnumerable.Global - public List DeviceDefinitions { get; } = new List(); + public List DeviceDefinitions { get; } = new(); /// /// The used to trigger the updates for corsair devices. @@ -72,15 +69,15 @@ namespace RGB.NET.Devices.WS281X public void AddDeviceDefinition(IWS281XDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); - List devices = new List(); + List devices = new(); foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions) { try @@ -89,7 +86,7 @@ namespace RGB.NET.Devices.WS281X } catch { if (throwExceptions) throw; } } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -103,21 +100,18 @@ namespace RGB.NET.Devices.WS281X return true; } - - /// - public void ResetDevices() - { - foreach (IRGBDevice device in Devices) - if (device is NodeMCUWS2812USBDevice nodemcuDevice) - nodemcuDevice.UpdateQueue.ResetDevice(); - } - + /// public void Dispose() { - try { UpdateTrigger?.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(); + DeviceDefinitions.Clear(); } diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProviderLoader.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProviderLoader.cs deleted file mode 100644 index 10781a9..0000000 --- a/RGB.NET.Devices.WS281X/WS281XDeviceProviderLoader.cs +++ /dev/null @@ -1,27 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.WS281X -{ - /// - /// - /// Represents a device provider loaded used to dynamically load WS281X devices into an application. - /// - // ReSharper disable once UnusedMember.Global - // ReSharper disable once InconsistentNaming - public class WS281XDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => WS281XDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs deleted file mode 100644 index 640bfee..0000000 --- a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs +++ /dev/null @@ -1,21 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Wooting.Enum -{ - /// - /// Contains list of available logical layouts for cooler master keyboards. - /// - /// - /// Based on what is available in the shop: https://wooting.store/collections/wooting-keyboards/products/wooting-two - /// - public enum WootingLogicalKeyboardLayout - { - US = 0, - UK = 1, - DE = 2, - ND = 3 - }; -} diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs index b766da8..b466ac8 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs @@ -23,7 +23,7 @@ namespace RGB.NET.Devices.Wooting.Generic /// Gets or sets the update queue performing updates for this device. /// // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue UpdateQueue { get; set; } + protected UpdateQueue? UpdateQueue { get; set; } #endregion @@ -51,7 +51,7 @@ namespace RGB.NET.Devices.Wooting.Generic if (Size == Size.Invalid) { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); + Rectangle ledRectangle = new(this.Select(x => x.LedRectangle)); Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); } diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs index 750daca..a91ba03 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Helper; @@ -26,11 +25,8 @@ namespace RGB.NET.Devices.Wooting.Generic public string Model { get; } /// - public Uri Image { get; set; } + public object? LayoutMetadata { get; set; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - /// /// Gets the of the . /// diff --git a/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs b/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs index 7c2e8b3..f0d186b 100644 --- a/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs +++ b/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs @@ -1,7 +1,6 @@ using System; using System.ComponentModel; using System.Reflection; -using RGB.NET.Core; namespace RGB.NET.Devices.Wooting.Helper { @@ -14,26 +13,21 @@ namespace RGB.NET.Devices.Wooting.Helper /// Gets the value of the . /// /// The enum value to get the description from. - /// The generic enum-type - /// The value of the or the result of the source. - internal static string GetDescription(this T source) - where T : struct - { - return source.GetAttribute()?.Description ?? source.ToString(); - } - + /// The value of the or the result of the source. + internal static string GetDescription(this System.Enum source) + => source.GetAttribute()?.Description ?? source.ToString(); + /// /// Gets the attribute of type T. /// /// The enum value to get the attribute from /// The generic attribute type - /// The generic enum-type /// The . - private static T GetAttribute(this TEnum source) + private static T? GetAttribute(this System.Enum source) where T : Attribute - where TEnum : struct { - FieldInfo fi = source.GetType().GetField(source.ToString()); + FieldInfo? fi = source.GetType().GetField(source.ToString()); + if (fi == null) return null; T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); return attributes.Length > 0 ? attributes[0] : null; } diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs index dc9fa15..0ce7e41 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs @@ -15,8 +15,8 @@ namespace RGB.NET.Devices.Wooting.Keyboard #region Wooting One - private static readonly Dictionary WootingOne_US = new Dictionary - { + private static readonly Dictionary WootingOne_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, { LedId.Keyboard_F2, (0,3) }, @@ -111,8 +111,8 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_ArrowRight, (5,16) } }; - private static readonly Dictionary WootingOne_UK = new Dictionary - { + private static readonly Dictionary WootingOne_UK = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, { LedId.Keyboard_F2, (0,3) }, @@ -213,8 +213,8 @@ namespace RGB.NET.Devices.Wooting.Keyboard #region Wooting Two - private static readonly Dictionary WootingTwo_US = new Dictionary - { + private static readonly Dictionary WootingTwo_US = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, { LedId.Keyboard_F2, (0,3) }, @@ -330,8 +330,8 @@ namespace RGB.NET.Devices.Wooting.Keyboard { LedId.Keyboard_NumPeriodAndDelete, (5,19) } }; - private static readonly Dictionary WootingTwo_UK = new Dictionary - { + private static readonly Dictionary WootingTwo_UK = new() + { { LedId.Keyboard_Escape, (0,0) }, { LedId.Keyboard_F1, (0,2) }, { LedId.Keyboard_F2, (0,3) }, @@ -455,7 +455,7 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// Contains all the hardware-id mappings for Wooting devices. /// public static readonly Dictionary>> Mapping = - new Dictionary>> + new() { { WootingDevicesIndexes.WootingOne, new Dictionary> { diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs index 3ccc35a..a3e8e0c 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs @@ -29,24 +29,17 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// protected override void InitializeLayout() { - Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout]; foreach (KeyValuePair led in mapping) - { - InitializeLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19,19)); - } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Wooting\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - DeviceInfo.LogicalLayout.ToString()); + AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19)); } /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; /// - protected override object CreateLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue?.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); #endregion } diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs index b2bcc70..7d53a92 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; @@ -18,11 +17,6 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// public WootingPhysicalKeyboardLayout PhysicalLayout { get; } - /// - /// Gets the of the . - /// - public WootingLogicalKeyboardLayout LogicalLayout { get; private set; } - #endregion #region Constructors @@ -33,29 +27,10 @@ namespace RGB.NET.Devices.Wooting.Keyboard /// /// The index of the . /// The of the . - /// The of the layout this keyboard is using - internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex, WootingPhysicalKeyboardLayout physicalKeyboardLayout, - CultureInfo culture) + internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex, WootingPhysicalKeyboardLayout physicalKeyboardLayout) : base(RGBDeviceType.Keyboard, deviceIndex) { this.PhysicalLayout = physicalKeyboardLayout; - - DetermineLogicalLayout(culture.KeyboardLayoutId); - } - - private void DetermineLogicalLayout(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - // TODO SpoinkyNL 15-12-2019: There doesn't seem to be an accurate way to determine this, perhaps it should be a configurable thing.. - // I'm using US International and it's reporting nl-NL's 1043. Also you can after all just swap your keycaps - default: - if (PhysicalLayout == WootingPhysicalKeyboardLayout.US) - LogicalLayout = WootingLogicalKeyboardLayout.US; - else - LogicalLayout = WootingLogicalKeyboardLayout.UK; - break; - } } #endregion diff --git a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs index 1bb7dd9..e6baf08 100644 --- a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs +++ b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs @@ -17,11 +17,6 @@ namespace RGB.NET.Devices.Wooting.Native private static IntPtr _dllHandle = IntPtr.Zero; - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - /// /// Reloads the SDK. /// @@ -37,10 +32,10 @@ namespace RGB.NET.Devices.Wooting.Native // HACK: Load library at runtime to support both, x86 and x64 with one managed dll List possiblePathList = Environment.Is64BitProcess ? WootingDeviceProvider.PossibleX64NativePaths : WootingDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); if (dllPath == null) throw new RGBDeviceException($"Can't find the Wooting-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); + SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))!); _dllHandle = LoadLibrary(dllPath); @@ -79,12 +74,12 @@ namespace RGB.NET.Devices.Wooting.Native #region Pointers - private static GetDeviceInfoPointer _getDeviceInfoPointer; - private static KeyboardConnectedPointer _keyboardConnectedPointer; - private static ResetPointer _resetPointer; - private static ClosePointer _closePointer; - private static ArrayUpdateKeyboardPointer _arrayUpdateKeyboardPointer; - private static ArraySetSinglePointer _arraySetSinglePointer; + private static GetDeviceInfoPointer? _getDeviceInfoPointer; + private static KeyboardConnectedPointer? _keyboardConnectedPointer; + private static ResetPointer? _resetPointer; + private static ClosePointer? _closePointer; + private static ArrayUpdateKeyboardPointer? _arrayUpdateKeyboardPointer; + private static ArraySetSinglePointer? _arraySetSinglePointer; #endregion @@ -110,12 +105,12 @@ namespace RGB.NET.Devices.Wooting.Native #endregion - internal static IntPtr GetDeviceInfo() => _getDeviceInfoPointer(); - internal static bool KeyboardConnected() => _keyboardConnectedPointer(); - internal static bool Reset() => _resetPointer(); - internal static bool Close() => _closePointer(); - internal static bool ArrayUpdateKeyboard() => _arrayUpdateKeyboardPointer(); - internal static bool ArraySetSingle(byte row, byte column, byte red, byte green, byte blue) => _arraySetSinglePointer(row, column, red, green, blue); + internal static IntPtr GetDeviceInfo() => (_getDeviceInfoPointer ?? throw new RGBDeviceException("The Wooting-SDK is not initialized.")).Invoke(); + internal static bool KeyboardConnected() => (_keyboardConnectedPointer ?? throw new RGBDeviceException("The Wooting-SDK is not initialized.")).Invoke(); + internal static bool Reset() => (_resetPointer ?? throw new RGBDeviceException("The Wooting-SDK is not initialized.")).Invoke(); + internal static bool Close() => (_closePointer ?? throw new RGBDeviceException("The Wooting-SDK is not initialized.")).Invoke(); + internal static bool ArrayUpdateKeyboard() => (_arrayUpdateKeyboardPointer ?? throw new RGBDeviceException("The Wooting-SDK is not initialized.")).Invoke(); + internal static bool ArraySetSingle(byte row, byte column, byte red, byte green, byte blue) => (_arraySetSinglePointer ?? throw new RGBDeviceException("The Wooting-SDK is not initialized.")).Invoke(row, column, red, green, blue); #endregion } diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index 9b83452..9f779c2 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -1,6 +1,7 @@ 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; @@ -18,7 +19,7 @@ namespace RGB.NET.Devices.Wooting { #region Properties & Fields - private static WootingDeviceProvider _instance; + private static WootingDeviceProvider? _instance; /// /// Gets the singleton instance. /// @@ -28,13 +29,13 @@ namespace RGB.NET.Devices.Wooting /// 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 List { "x86/wooting-rgb-sdk.dll" }; + public static List PossibleX86NativePaths { get; } = new() { "x86/wooting-rgb-sdk.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 List { "x64/wooting-rgb-sdk64.dll" }; + public static List PossibleX64NativePaths { get; } = new() { "x64/wooting-rgb-sdk64.dll" }; /// /// @@ -42,24 +43,13 @@ namespace RGB.NET.Devices.Wooting /// public bool IsInitialized { get; private set; } - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _WootingSDK.LoadedArchitecture; - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { 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; private set; } + public DeviceUpdateTrigger UpdateTrigger { get; } #endregion @@ -84,45 +74,33 @@ namespace RGB.NET.Devices.Wooting /// /// Thrown if the SDK failed to initialize - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, - bool throwExceptions = false) + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) { IsInitialized = false; try { - UpdateTrigger?.Stop(); + UpdateTrigger.Stop(); _WootingSDK.Reload(); IList devices = new List(); if (_WootingSDK.KeyboardConnected()) { - _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo)); - IWootingRGBDevice device; - // TODO: Find an accurate way to determine physical and logical layouts - if (nativeDeviceInfo.Model == "Wooting two") + _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!; + IWootingRGBDevice device = nativeDeviceInfo.Model switch { - device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo, - WootingPhysicalKeyboardLayout.US, - CultureHelper.GetCurrentCulture())); - } - else if (nativeDeviceInfo.Model == "Wooting one") - { - device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne, - WootingPhysicalKeyboardLayout.US, - CultureHelper.GetCurrentCulture())); - } - else - { - throw new RGBDeviceException("No supported Wooting keyboard connected"); - } + // TODO: Find an accurate way to determine physical and logical layouts + "Wooting two" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo, WootingPhysicalKeyboardLayout.US)), + "Wooting one" => new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne, WootingPhysicalKeyboardLayout.US)), + _ => throw new RGBDeviceException("No supported Wooting keyboard connected") + }; device.Initialize(UpdateTrigger); devices.Add(device); } - UpdateTrigger?.Start(); + UpdateTrigger.Start(); Devices = new ReadOnlyCollection(devices); IsInitialized = true; @@ -135,17 +113,18 @@ namespace RGB.NET.Devices.Wooting return true; } - - /// - public void ResetDevices() - { } - + /// public void Dispose() { - try { UpdateTrigger?.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(); + try { _WootingSDK.Close(); } catch { /* Unlucky.. */ } diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs b/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs deleted file mode 100644 index 5daf314..0000000 --- a/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Wooting -{ - /// - /// Represents a device provider loaded used to dynamically load Wooting devices into an application. - /// - public class WootingDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => WootingDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Groups/Extensions/LedGroupExtension.cs b/RGB.NET.Groups/Extensions/LedGroupExtension.cs index cd09393..4391131 100644 --- a/RGB.NET.Groups/Extensions/LedGroupExtension.cs +++ b/RGB.NET.Groups/Extensions/LedGroupExtension.cs @@ -20,12 +20,13 @@ namespace RGB.NET.Groups // ReSharper disable once InvertIf if (!(ledGroup is ListLedGroup listLedGroup)) { - bool wasAttached = ledGroup.Detach(); - listLedGroup = new ListLedGroup(wasAttached, ledGroup.GetLeds()) { Brush = ledGroup.Brush }; + if (ledGroup.Surface != null) + ledGroup.Detach(ledGroup.Surface); + listLedGroup = new ListLedGroup(ledGroup.Surface, ledGroup.GetLeds()) { Brush = ledGroup.Brush }; } return listLedGroup; } - + /// /// Returns a new which contains all from the given excluding the specified ones. /// @@ -46,13 +47,13 @@ namespace RGB.NET.Groups /// /// The to attach. /// true if the could be attached; otherwise, false. - public static bool Attach(this ILedGroup ledGroup) => RGBSurface.Instance.AttachLedGroup(ledGroup); + public static bool Attach(this ILedGroup ledGroup, RGBSurface surface) => surface.AttachLedGroup(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.Instance.DetachLedGroup(ledGroup); + public static bool Detach(this ILedGroup ledGroup, RGBSurface surface) => surface.DetachLedGroup(ledGroup); } } diff --git a/RGB.NET.Groups/Groups/ListLedGroup.cs b/RGB.NET.Groups/Groups/ListLedGroup.cs index eb833d8..06d15b8 100644 --- a/RGB.NET.Groups/Groups/ListLedGroup.cs +++ b/RGB.NET.Groups/Groups/ListLedGroup.cs @@ -28,26 +28,8 @@ namespace RGB.NET.Groups /// Initializes a new instance of the class. /// /// Specifies whether this should be automatically attached or not. - public ListLedGroup(bool autoAttach = true) - : base(autoAttach) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The initial of this . - public ListLedGroup(params Led[] leds) - : this(true, leds) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The initial of this . - public ListLedGroup(IEnumerable leds) - : this(true, leds) + public ListLedGroup(RGBSurface? surface) + : base(surface) { } /// @@ -56,8 +38,8 @@ namespace RGB.NET.Groups /// /// Specifies whether this should be automatically attached or not. /// The initial of this . - public ListLedGroup(bool autoAttach, IEnumerable leds) - : base(autoAttach) + public ListLedGroup(RGBSurface? surface, IEnumerable leds) + : base(surface) { AddLeds(leds); } @@ -68,8 +50,8 @@ namespace RGB.NET.Groups /// /// Specifies whether this should be automatically attached or not. /// The initial of this . - public ListLedGroup(bool autoAttach, params Led[] leds) - : base(autoAttach) + public ListLedGroup(RGBSurface? surface, params Led[] leds) + : base(surface) { AddLeds(leds); } @@ -90,8 +72,6 @@ namespace RGB.NET.Groups /// The to add. public void AddLeds(IEnumerable leds) { - if (leds == null) return; - lock (GroupLeds) foreach (Led led in leds) if ((led != null) && !ContainsLed(led)) @@ -110,8 +90,6 @@ namespace RGB.NET.Groups /// The to remove. public void RemoveLeds(IEnumerable leds) { - if (leds == null) return; - lock (GroupLeds) foreach (Led led in leds) if (led != null) @@ -126,7 +104,7 @@ namespace RGB.NET.Groups public bool ContainsLed(Led led) { lock (GroupLeds) - return (led != null) && GroupLeds.Contains(led); + return GroupLeds.Contains(led); } /// diff --git a/RGB.NET.Groups/Groups/RectangleLedGroup.cs b/RGB.NET.Groups/Groups/RectangleLedGroup.cs index 90bb88c..fadce4d 100644 --- a/RGB.NET.Groups/Groups/RectangleLedGroup.cs +++ b/RGB.NET.Groups/Groups/RectangleLedGroup.cs @@ -16,7 +16,7 @@ namespace RGB.NET.Groups { #region Properties & Fields - private IList _ledCache; + private IList? _ledCache; private Rectangle _rectangle; /// @@ -58,8 +58,8 @@ namespace RGB.NET.Groups /// They second to calculate the of this from. /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) /// (optional) Specifies whether this should be automatically attached or not. (default: true) - public RectangleLedGroup(Led fromLed, Led toLed, double minOverlayPercentage = 0.5, bool autoAttach = true) - : this(new Rectangle(fromLed.LedRectangle, toLed.LedRectangle), minOverlayPercentage, autoAttach) + public RectangleLedGroup(RGBSurface? surface, Led fromLed, Led toLed, double minOverlayPercentage = 0.5) + : this(surface, new Rectangle(fromLed.LedRectangle, toLed.LedRectangle), minOverlayPercentage) { } /// @@ -70,8 +70,8 @@ namespace RGB.NET.Groups /// They second point to calculate the of this from. /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) /// (optional) Specifies whether this should be automatically attached or not. (default: true) - public RectangleLedGroup(Point fromPoint, Point toPoint, double minOverlayPercentage = 0.5, bool autoAttach = true) - : this(new Rectangle(fromPoint, toPoint), minOverlayPercentage, autoAttach) + public RectangleLedGroup(RGBSurface? surface, Point fromPoint, Point toPoint, double minOverlayPercentage = 0.5) + : this(surface, new Rectangle(fromPoint, toPoint), minOverlayPercentage) { } /// @@ -81,8 +81,8 @@ namespace RGB.NET.Groups /// The of this . /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) /// (optional) Specifies whether this should be automatically attached or not. (default: true) - public RectangleLedGroup(Rectangle rectangle, double minOverlayPercentage = 0.5, bool autoAttach = true) - : base(autoAttach) + public RectangleLedGroup(RGBSurface? surface, Rectangle rectangle, double minOverlayPercentage = 0.5) + : base(surface) { this.Rectangle = rectangle; this.MinOverlayPercentage = minOverlayPercentage; @@ -93,10 +93,22 @@ namespace RGB.NET.Groups #region Methods /// - public override void OnAttach() => RGBSurface.Instance.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; + public override void OnAttach(RGBSurface surface) + { + base.OnAttach(surface); + + if (Surface != null) + Surface.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; + } /// - public override void OnDetach() => RGBSurface.Instance.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; + public override void OnDetach(RGBSurface surface) + { + if (Surface != null) + Surface.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; + + base.OnDetach(surface); + } private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache(); @@ -105,7 +117,7 @@ namespace RGB.NET.Groups /// Gets a list containing all of this . /// /// The list containing all of this . - public override IList GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList(); + public override IList GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List()); private void InvalidateCache() => _ledCache = null; diff --git a/RGB.NET.Core/Devices/Layout/DeviceLayout.cs b/RGB.NET.Layout/DeviceLayout.cs similarity index 59% rename from RGB.NET.Core/Devices/Layout/DeviceLayout.cs rename to RGB.NET.Layout/DeviceLayout.cs index 267c7d0..2f34028 100644 --- a/RGB.NET.Core/Devices/Layout/DeviceLayout.cs +++ b/RGB.NET.Layout/DeviceLayout.cs @@ -2,16 +2,19 @@ using System.Collections.Generic; using System.ComponentModel; using System.IO; +using System.Linq; +using System.Xml; using System.Xml.Serialization; +using RGB.NET.Core; -namespace RGB.NET.Core.Layout +namespace RGB.NET.Layout { /// /// Represents the serializable layout of a . /// [Serializable] [XmlRoot("Device")] - public class DeviceLayout + public class DeviceLayout : IDeviceLayout { #region Properties & Fields @@ -19,13 +22,13 @@ namespace RGB.NET.Core.Layout /// Gets or sets the name of the . /// [XmlElement("Name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the description of the . /// [XmlElement("Description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Gets or sets the of the . @@ -33,23 +36,17 @@ namespace RGB.NET.Core.Layout [XmlElement("Type")] public RGBDeviceType Type { get; set; } - /// - /// Gets or sets the of the . - /// - [XmlElement("Lighting")] - public RGBDeviceLighting Lighting { get; set; } - /// /// Gets or sets the vendor of the . /// [XmlElement("Vendor")] - public string Vendor { get; set; } + public string? Vendor { get; set; } /// /// Gets or sets the model of the . /// [XmlElement("Model")] - public string Model { get; set; } + public string? Model { get; set; } /// /// Gets or sets the of the . @@ -84,29 +81,20 @@ namespace RGB.NET.Core.Layout [DefaultValue(19.0)] public double LedUnitHeight { get; set; } = 19.0; - /// - /// The path images for this device are collected in. - /// - [XmlElement("ImageBasePath")] - public string ImageBasePath { get; set; } - - /// - /// The image file for this device. - /// - [XmlElement("DeviceImage")] - public string DeviceImage { get; set; } + [XmlArray("Leds")] + public List InternalLeds { get; set; } = new(); /// /// Gets or sets a list of representing all the of the . /// - [XmlArray("Leds")] - public List Leds { get; set; } = new List(); + [XmlIgnore] + public IEnumerable Leds => InternalLeds; - /// - /// Gets or sets a list of representing the layouts for the images of all the of the . - /// - [XmlArray("LedImageLayouts")] - public List LedImageLayouts { get; set; } = new List(); + [XmlElement("CustomData")] + public object? InternalCustomData { get; set; } + + [XmlIgnore] + public object? CustomData { get; set; } #endregion @@ -117,28 +105,32 @@ namespace RGB.NET.Core.Layout /// /// The path to the xml file. /// The deserialized . - public static DeviceLayout Load(string path) + public static DeviceLayout? Load(string path, Type? customDeviceDataType = null, Type? customLedDataType = null) { if (!File.Exists(path)) return null; try { - XmlSerializer serializer = new XmlSerializer(typeof(DeviceLayout)); - using (StreamReader reader = new StreamReader(path)) - { - DeviceLayout layout = serializer.Deserialize(reader) as DeviceLayout; - if (layout?.Leds != null) - { - LedLayout lastLed = null; - foreach (LedLayout led in layout.Leds) - { - led.CalculateValues(layout, lastLed); - lastLed = led; - } - } + XmlSerializer serializer = new(typeof(DeviceLayout)); + using StreamReader reader = new(path); - return layout; + DeviceLayout? layout = serializer.Deserialize(reader) as DeviceLayout; + if (layout != null) + layout.CustomData = layout.GetCustomData(layout.InternalCustomData, customDeviceDataType); + + if (layout?.InternalLeds != null) + { + LedLayout? lastLed = null; + foreach (LedLayout led in layout.InternalLeds) + { + led.CalculateValues(layout, lastLed); + lastLed = led; + + led.CustomData = layout.GetCustomData(led.InternalCustomData, customLedDataType); + } } + + return layout; } catch { @@ -146,6 +138,23 @@ namespace RGB.NET.Core.Layout } } + protected virtual object? GetCustomData(object? customData, Type? type) + { + XmlNode? node = (customData as XmlNode) ?? (customData as IEnumerable)?.FirstOrDefault()?.ParentNode; //HACK DarthAffe 16.01.2021: This gives us the CustomData-Node + if ((node == null) || (type == null)) return null; + + if (type == null) return null; + + using MemoryStream ms = new(); + using StreamWriter writer = new(ms); + + writer.Write(node.OuterXml); + writer.Flush(); + ms.Seek(0, SeekOrigin.Begin); + + return new XmlSerializer(type).Deserialize(ms); + } + #endregion } } diff --git a/RGB.NET.Layout/IDeviceLayout.cs b/RGB.NET.Layout/IDeviceLayout.cs new file mode 100644 index 0000000..c06d9d9 --- /dev/null +++ b/RGB.NET.Layout/IDeviceLayout.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using RGB.NET.Core; + +namespace RGB.NET.Layout +{ + public interface IDeviceLayout + { + /// + /// Gets or sets the name of the . + /// + string? Name { get; } + + /// + /// Gets or sets the description of the . + /// + string? Description { get; } + + /// + /// Gets or sets the of the . + /// + RGBDeviceType Type { get; } + + /// + /// Gets or sets the vendor of the . + /// + string? Vendor { get; } + + /// + /// Gets or sets the model of the . + /// + string? Model { get; } + + /// + /// Gets or sets the of the . + /// + Shape Shape { get; } + + /// + /// Gets or sets the width of the . + /// + double Width { get; } + + /// + /// Gets or sets the height of the . + /// + double Height { get; } + + /// + /// Gets or sets a list of representing all the of the . + /// + IEnumerable Leds { get; } + + object? CustomData { get; } + } +} diff --git a/RGB.NET.Layout/ILedLayout.cs b/RGB.NET.Layout/ILedLayout.cs new file mode 100644 index 0000000..3747a97 --- /dev/null +++ b/RGB.NET.Layout/ILedLayout.cs @@ -0,0 +1,44 @@ +using RGB.NET.Core; + +namespace RGB.NET.Layout +{ + public interface ILedLayout + { + /// + /// Gets or sets the Id of the . + /// + string? Id { get; } + + /// + /// Gets or sets the of the . + /// + Shape Shape { get; } + + /// + /// Gets or sets the vecor-data representing a custom-shape of the . + /// + string? ShapeData { get; } + + /// + /// Gets the x-position of the . + /// + double X { get; } + + /// + /// Gets the y-position of the . + /// + double Y { get; } + + /// + /// Gets the width of the . + /// + double Width { get; } + + /// + /// Gets the height of the . + /// + double Height { get; } + + object? CustomData { get; } + } +} diff --git a/RGB.NET.Layout/LayoutExtension.cs b/RGB.NET.Layout/LayoutExtension.cs new file mode 100644 index 0000000..ec88f27 --- /dev/null +++ b/RGB.NET.Layout/LayoutExtension.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RGB.NET.Core; + +namespace RGB.NET.Layout +{ + public static class LayoutExtension + { + public static void ApplyTo(this IDeviceLayout layout, IRGBDevice device, bool createMissingLeds = false, bool removeExcessiveLeds = false) + { + device.Size = new Size(layout.Width, layout.Height); + device.DeviceInfo.LayoutMetadata = layout.CustomData; + + HashSet ledIds = new(); + foreach (ILedLayout layoutLed in layout.Leds) + { + if (Enum.TryParse(layoutLed.Id, true, out LedId ledId)) + { + ledIds.Add(ledId); + + Led? led = device[ledId]; + if ((led == null) && createMissingLeds) + led = device.AddLed(ledId, new Point(), new Size()); + + if (led != null) + { + led.Location = new Point(layoutLed.X, layoutLed.Y); + led.Size = new Size(layoutLed.Width, layoutLed.Height); + led.Shape = layoutLed.Shape; + led.ShapeData = layoutLed.ShapeData; + led.LayoutMetadata = layoutLed.CustomData; + } + } + } + + if (removeExcessiveLeds) + { + List ledsToRemove = device.Select(led => led.Id).Where(id => !ledIds.Contains(id)).ToList(); + foreach (LedId led in ledsToRemove) + device.RemoveLed(led); + } + } + } +} diff --git a/RGB.NET.Core/Devices/Layout/LedLayout.cs b/RGB.NET.Layout/LedLayout.cs similarity index 83% rename from RGB.NET.Core/Devices/Layout/LedLayout.cs rename to RGB.NET.Layout/LedLayout.cs index c382520..3bab36c 100644 --- a/RGB.NET.Core/Devices/Layout/LedLayout.cs +++ b/RGB.NET.Layout/LedLayout.cs @@ -2,15 +2,16 @@ using System.ComponentModel; using System.Globalization; using System.Xml.Serialization; +using RGB.NET.Core; -namespace RGB.NET.Core.Layout +namespace RGB.NET.Layout { /// /// Represents the serializable layout of a . /// [Serializable] [XmlType("Led")] - public class LedLayout + public class LedLayout : ILedLayout { #region Properties & Fields @@ -18,7 +19,7 @@ namespace RGB.NET.Core.Layout /// Gets or sets the Id of the . /// [XmlAttribute("Id")] - public string Id { get; set; } + public string? Id { get; set; } /// /// Gets or sets the descriptive of the . @@ -60,6 +61,12 @@ namespace RGB.NET.Core.Layout [DefaultValue("1.0")] public string DescriptiveHeight { get; set; } = "1.0"; + [XmlElement("CustomData")] + public object? InternalCustomData { get; set; } + + [XmlIgnore] + public object? CustomData { get; set; } + /// /// Gets or sets the of the . /// @@ -70,28 +77,28 @@ namespace RGB.NET.Core.Layout /// Gets or sets the vecor-data representing a custom-shape of the . /// [XmlIgnore] - public string ShapeData { get; set; } + public string? ShapeData { get; set; } /// - /// Gets or sets the x-position of the . + /// Gets the x-position of the . /// [XmlIgnore] public double X { get; private set; } /// - /// Gets or sets the y-position of the . + /// Gets the y-position of the . /// [XmlIgnore] public double Y { get; private set; } /// - /// Gets or sets the width of the . + /// Gets the width of the . /// [XmlIgnore] public double Width { get; private set; } /// - /// Gets or sets the height of the . + /// Gets the height of the . /// [XmlIgnore] public double Height { get; private set; } @@ -105,7 +112,7 @@ namespace RGB.NET.Core.Layout /// /// The this belongs to. /// The previously calculated. - public void CalculateValues(DeviceLayout device, LedLayout lastLed) + public virtual void CalculateValues(DeviceLayout device, LedLayout? lastLed) { if (!Enum.TryParse(DescriptiveShape, true, out Shape shape)) { @@ -121,7 +128,7 @@ namespace RGB.NET.Core.Layout Y = GetLocationValue(DescriptiveY, lastLed?.Y ?? 0, Height, lastLed?.Height ?? 0); } - private double GetLocationValue(string value, double lastValue, double currentSize, double lastSize) + protected virtual double GetLocationValue(string value, double lastValue, double currentSize, double lastSize) { try { @@ -136,19 +143,19 @@ namespace RGB.NET.Core.Layout return lastValue + lastSize; if (value.StartsWith("+", StringComparison.Ordinal)) - return lastValue + lastSize + double.Parse(value.Substring(1), CultureInfo.InvariantCulture); + return lastValue + lastSize + double.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.Substring(1), CultureInfo.InvariantCulture); + return lastValue - currentSize - double.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.Substring(1), CultureInfo.InvariantCulture); + return (lastValue + lastSize) - currentSize - double.Parse(value[1..], CultureInfo.InvariantCulture); return double.Parse(value, CultureInfo.InvariantCulture); } @@ -158,7 +165,7 @@ namespace RGB.NET.Core.Layout } } - private double GetSizeValue(string value, double unitSize) + protected virtual double GetSizeValue(string value, double unitSize) { try { @@ -167,7 +174,7 @@ namespace RGB.NET.Core.Layout value = value.Replace(" ", string.Empty); if (value.EndsWith("mm", StringComparison.OrdinalIgnoreCase)) - return double.Parse(value.Substring(0, value.Length - 2), CultureInfo.InvariantCulture); + return double.Parse(value[..^2], CultureInfo.InvariantCulture); return unitSize * double.Parse(value, CultureInfo.InvariantCulture); } diff --git a/RGB.NET.Layout/RGB.NET.Layout.csproj b/RGB.NET.Layout/RGB.NET.Layout.csproj new file mode 100644 index 0000000..118af56 --- /dev/null +++ b/RGB.NET.Layout/RGB.NET.Layout.csproj @@ -0,0 +1,56 @@ + + + net5.0 + latest + enable + + Darth Affe + Wyrez + en-US + en-US + RGB.NET.Layout + RGB.NET.Layout + RGB.NET.Layout + RGB.NET.Layout + RGB.NET.Layout + Layout-Module of RGB.NET + Layout-Module of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Darth Affe 2021 + Copyright © Darth Affe 2021 + 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.sln b/RGB.NET.sln index 9e742b4..7a1fb70 100644 --- a/RGB.NET.sln +++ b/RGB.NET.sln @@ -25,8 +25,6 @@ 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.Devices.Roccat", "RGB.NET.Devices.Roccat\RGB.NET.Devices.Roccat.csproj", "{9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}" -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}" @@ -45,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Asus", "RGB EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Wooting", "RGB.NET.Devices.Wooting\RGB.NET.Devices.Wooting.csproj", "{DD46DB2D-85BE-4962-86AE-E38C9053A548}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Layout", "RGB.NET.Layout\RGB.NET.Layout.csproj", "{8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -87,10 +87,6 @@ Global {2E162CB7-2C6C-4069-8356-06162F7BE0AA}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E162CB7-2C6C-4069-8356-06162F7BE0AA}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E162CB7-2C6C-4069-8356-06162F7BE0AA}.Release|Any CPU.Build.0 = Release|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Release|Any CPU.Build.0 = Release|Any CPU {B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {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 @@ -123,6 +119,10 @@ Global {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Release|Any CPU.Build.0 = Release|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -136,7 +136,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} - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E} = {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} diff --git a/RGB.NET.sln.DotSettings b/RGB.NET.sln.DotSettings index 563aafd..de2906a 100644 --- a/RGB.NET.sln.DotSettings +++ b/RGB.NET.sln.DotSettings @@ -259,19 +259,23 @@ False False AFBG + API ARGB BWZ + CID CM CMSDK CUESDK DB DG DMX + DRAM EK FM GEZ HID HS + HSV IBAN ID IO @@ -281,6 +285,7 @@ PLZ RGB SAP + SDK SQL UI USB diff --git a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs index 20b17a1..bd0fda1 100644 --- a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs @@ -21,7 +21,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void ToStringTest() { - Core.Color color = new Core.Color(255, 120, 13, 1); + Core.Color color = new(255, 120, 13, 1); Assert.AreEqual("[A: 255, R: 120, G: 13, B: 1]", color.ToString()); } @@ -31,8 +31,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void GetHashCodeTestEqual() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 255); Assert.AreEqual(color1.GetHashCode(), color2.GetHashCode()); } @@ -40,8 +40,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void GetHashCodeTestNotEqualA() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(99, 68, 32, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(99, 68, 32, 255); Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); } @@ -49,8 +49,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void GetHashCodeTestNotEqualR() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 69, 32, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 69, 32, 255); Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); } @@ -58,8 +58,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void GetHashCodeTestNotEqualG() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 200, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 200, 255); Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); } @@ -67,8 +67,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void GetHashCodeTestNotEqualB() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 0); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 0); Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); } @@ -80,8 +80,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void EqualityTestEqual() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 255); Assert.IsTrue(color1.Equals(color2), $"Equals returns false on equal colors {color1} and {color2}"); Assert.IsTrue(color1 == color2, $"Equal-operator returns false on equal colors {color1} and {color2}"); @@ -91,8 +91,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void EqualityTestNotEqualA() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(99, 68, 32, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(99, 68, 32, 255); Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); @@ -102,8 +102,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void EqualityTestNotEqualR() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 69, 32, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 69, 32, 255); Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); @@ -113,8 +113,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void EqualityTestNotEqualG() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 200, 255); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 200, 255); Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); @@ -124,8 +124,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void EqualityTestNotEqualB() { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 0); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 0); Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); @@ -141,7 +141,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void RGBByteConstructorTest() { - Core.Color color = new Core.Color((byte)10, (byte)120, (byte)255); + Core.Color color = new((byte)10, (byte)120, (byte)255); Assert.AreEqual(255, color.GetA(), "A is not 255"); Assert.AreEqual(10, color.GetR(), "R is not 10"); @@ -152,7 +152,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void ARGBByteConstructorTest() { - Core.Color color = new Core.Color((byte)200, (byte)10, (byte)120, (byte)255); + Core.Color color = new((byte)200, (byte)10, (byte)120, (byte)255); Assert.AreEqual(200, color.GetA(), "A is not 200"); Assert.AreEqual(10, color.GetR(), "R is not 10"); @@ -163,7 +163,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void RGBIntConstructorTest() { - Core.Color color = new Core.Color(10, 120, 255); + Core.Color color = new(10, 120, 255); Assert.AreEqual(255, color.GetA(), "A is not 255"); Assert.AreEqual(10, color.GetR(), "R is not 10"); @@ -174,7 +174,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void ARGBIntConstructorTest() { - Core.Color color = new Core.Color(200, 10, 120, 255); + Core.Color color = new(200, 10, 120, 255); Assert.AreEqual(200, color.GetA(), "A is not 200"); Assert.AreEqual(10, color.GetR(), "R is not 10"); @@ -185,14 +185,14 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void RGBIntConstructorClampTest() { - Core.Color color1 = new Core.Color(256, 256, 256); + Core.Color color1 = new(256, 256, 256); Assert.AreEqual(255, color1.GetA(), "A is not 255"); Assert.AreEqual(255, color1.GetR(), "R is not 255"); Assert.AreEqual(255, color1.GetG(), "G is not 255"); Assert.AreEqual(255, color1.GetB(), "B is not 255"); - Core.Color color2 = new Core.Color(-1, -1, -1); + Core.Color color2 = new(-1, -1, -1); Assert.AreEqual(255, color2.GetA(), "A is not 255"); Assert.AreEqual(0, color2.GetR(), "R is not 0"); @@ -203,14 +203,14 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void ARGBIntConstructorClampTest() { - Core.Color color = new Core.Color(256, 256, 256, 256); + Core.Color color = new(256, 256, 256, 256); Assert.AreEqual(255, color.GetA(), "A is not 255"); Assert.AreEqual(255, color.GetR(), "R is not 255"); Assert.AreEqual(255, color.GetG(), "G is not 255"); Assert.AreEqual(255, color.GetB(), "B is not 255"); - Core.Color color2 = new Core.Color(-1, -1, -1, -1); + Core.Color color2 = new(-1, -1, -1, -1); Assert.AreEqual(0, color2.GetA(), "A is not 0"); Assert.AreEqual(0, color2.GetR(), "R is not 0"); @@ -221,7 +221,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void RGBPercentConstructorTest() { - Core.Color color = new Core.Color(0.25341, 0.55367, 1); + Core.Color color = new(0.25341, 0.55367, 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"); @@ -232,7 +232,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void ARGBPercentConstructorTest() { - Core.Color color = new Core.Color(0.3315, 0.25341, 0.55367, 1); + Core.Color color = new(0.3315, 0.25341, 0.55367, 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"); @@ -243,14 +243,14 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void RGBPercentConstructorClampTest() { - Core.Color color1 = new Core.Color(1.1, 1.1, 1.1); + Core.Color color1 = new(1.1, 1.1, 1.1); 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 Core.Color(-1.0, -1.0, -1.0); + Core.Color color2 = new(-1.0, -1.0, -1.0); 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 Core.Color(1.1, 1.1, 1.1, 1.1); + Core.Color color1 = new(1.1, 1.1, 1.1, 1.1); 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 Core.Color(-1.0, -1.0, -1.0, -1.0); + Core.Color color2 = new(-1.0, -1.0, -1.0, -1.0); Assert.AreEqual(0, color2.A, "A is not 0"); Assert.AreEqual(0, color2.R, "R is not 0"); @@ -279,8 +279,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void CloneConstructorTest() { - Core.Color referennceColor = new Core.Color(200, 10, 120, 255); - Core.Color color = new Core.Color(referennceColor); + Core.Color referennceColor = new(200, 10, 120, 255); + Core.Color color = new(referennceColor); Assert.AreEqual(200, color.GetA(), "A is not 200"); Assert.AreEqual(10, color.GetR(), "R is not 10"); @@ -317,76 +317,76 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AToPercentTest() { - Core.Color color1 = new Core.Color(0, 0, 0, 0); + Core.Color color1 = new(0, 0, 0, 0); Assert.AreEqual(0, color1.A); - Core.Color color2 = new Core.Color(255, 0, 0, 0); + Core.Color color2 = new(255, 0, 0, 0); Assert.AreEqual(1, color2.A); - Core.Color color3 = new Core.Color(128, 0, 0, 0); + Core.Color color3 = new(128, 0, 0, 0); Assert.AreEqual(128 / 255.0, color3.A); - Core.Color color4 = new Core.Color(30, 0, 0, 0); + Core.Color color4 = new(30, 0, 0, 0); Assert.AreEqual(30 / 255.0, color4.A); - Core.Color color5 = new Core.Color(201, 0, 0, 0); + Core.Color color5 = new(201, 0, 0, 0); Assert.AreEqual(201 / 255.0, color5.A); } [TestMethod] public void RToPercentTest() { - Core.Color color1 = new Core.Color(0, 0, 0, 0); + Core.Color color1 = new(0, 0, 0, 0); Assert.AreEqual(0, color1.R); - Core.Color color2 = new Core.Color(0, 255, 0, 0); + Core.Color color2 = new(0, 255, 0, 0); Assert.AreEqual(1, color2.R); - Core.Color color3 = new Core.Color(0, 128, 0, 0); + Core.Color color3 = new(0, 128, 0, 0); Assert.AreEqual(128 / 255.0, color3.R); - Core.Color color4 = new Core.Color(0, 30, 0, 0); + Core.Color color4 = new(0, 30, 0, 0); Assert.AreEqual(30 / 255.0, color4.R); - Core.Color color5 = new Core.Color(0, 201, 0, 0); + Core.Color color5 = new(0, 201, 0, 0); Assert.AreEqual(201 / 255.0, color5.R); } [TestMethod] public void GToPercentTest() { - Core.Color color1 = new Core.Color(0, 0, 0, 0); + Core.Color color1 = new(0, 0, 0, 0); Assert.AreEqual(0, color1.G); - Core.Color color2 = new Core.Color(0, 0, 255, 0); + Core.Color color2 = new(0, 0, 255, 0); Assert.AreEqual(1, color2.G); - Core.Color color3 = new Core.Color(0, 0, 128, 0); + Core.Color color3 = new(0, 0, 128, 0); Assert.AreEqual(128 / 255.0, color3.G); - Core.Color color4 = new Core.Color(0, 0, 30, 0); + Core.Color color4 = new(0, 0, 30, 0); Assert.AreEqual(30 / 255.0, color4.G); - Core.Color color5 = new Core.Color(0, 0, 201, 0); + Core.Color color5 = new(0, 0, 201, 0); Assert.AreEqual(201 / 255.0, color5.G); } [TestMethod] public void BToPercentTest() { - Core.Color color1 = new Core.Color(0, 0, 0, 0); + Core.Color color1 = new(0, 0, 0, 0); Assert.AreEqual(0, color1.B); - Core.Color color2 = new Core.Color(0, 0, 0, 255); + Core.Color color2 = new(0, 0, 0, 255); Assert.AreEqual(1, color2.B); - Core.Color color3 = new Core.Color(0, 0, 0, 128); + Core.Color color3 = new(0, 0, 0, 128); Assert.AreEqual(128 / 255.0, color3.B); - Core.Color color4 = new Core.Color(0, 0, 0, 30); + Core.Color color4 = new(0, 0, 0, 30); Assert.AreEqual(30 / 255.0, color4.B); - Core.Color color5 = new Core.Color(0, 0, 0, 201); + Core.Color color5 = new(0, 0, 0, 201); Assert.AreEqual(201 / 255.0, color5.B); } diff --git a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs index 2624444..7a9abc9 100644 --- a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs @@ -12,8 +12,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void BlendOpaqueTest() { - Core.Color baseColor = new Core.Color(255, 0, 0); - Core.Color blendColor = new Core.Color(0, 255, 0); + Core.Color baseColor = new(255, 0, 0); + Core.Color blendColor = new(0, 255, 0); Assert.AreEqual(blendColor, baseColor.Blend(blendColor)); } @@ -21,8 +21,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void BlendTransparentTest() { - Core.Color baseColor = new Core.Color(255, 0, 0); - Core.Color blendColor = new Core.Color(0, 0, 255, 0); + Core.Color baseColor = new(255, 0, 0); + Core.Color blendColor = new(0, 0, 255, 0); Assert.AreEqual(baseColor, baseColor.Blend(blendColor)); } @@ -30,8 +30,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void BlendUpTest() { - Core.Color baseColor = new Core.Color(0.0, 0.0, 0.0); - Core.Color blendColor = new Core.Color(0.5, 1.0, 1.0, 1.0); + Core.Color baseColor = new(0.0, 0.0, 0.0); + Core.Color blendColor = new(0.5, 1.0, 1.0, 1.0); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); } @@ -39,8 +39,8 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void BlendDownTest() { - Core.Color baseColor = new Core.Color(1.0, 1.0, 1.0); - Core.Color blendColor = new Core.Color(0.5, 0.0, 0.0, 0.0); + Core.Color baseColor = new(1.0, 1.0, 1.0); + Core.Color blendColor = new(0.5, 0.0, 0.0, 0.0); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); } @@ -52,7 +52,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddRGBTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.AddRGB(11, 12, 13); Assert.AreEqual(new Core.Color(128, 139, 140, 141), result); @@ -61,7 +61,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddRGBPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.AddRGB(0.2, 0.3, 0.4); Assert.AreEqual(new Core.Color(0.5, 0.7, 0.8, 0.9), result); @@ -70,7 +70,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddATest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.AddA(10); Assert.AreEqual(new Core.Color(138, 128, 128, 128), result); @@ -79,7 +79,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddAPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.AddA(0.1); Assert.AreEqual(new Core.Color(0.6, 0.5, 0.5, 0.5), result); @@ -88,7 +88,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddRTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.AddRGB(r: 10); Assert.AreEqual(new Core.Color(128, 138, 128, 128), result); @@ -97,7 +97,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddRPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.AddRGB(r: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.6, 0.5, 0.5), result); @@ -106,7 +106,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddGTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.AddRGB(g: 10); Assert.AreEqual(new Core.Color(128, 128, 138, 128), result); @@ -115,7 +115,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddGPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.AddRGB(g: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.6, 0.5), result); @@ -124,7 +124,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddBTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.AddRGB(b: 10); Assert.AreEqual(new Core.Color(128, 128, 128, 138), result); @@ -133,7 +133,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void AddBPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.AddRGB(b: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.6), result); @@ -146,7 +146,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractRGBTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SubtractRGB(11, 12, 13); Assert.AreEqual(new Core.Color(128, 117, 116, 115), result); @@ -155,7 +155,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractRGBPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SubtractRGB(0.2, 0.3, 0.4); Assert.AreEqual(new Core.Color(0.5, 0.3, 0.2, 0.1), result); @@ -164,7 +164,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractATest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SubtractA(10); Assert.AreEqual(new Core.Color(118, 128, 128, 128), result); @@ -173,7 +173,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractAPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SubtractA(0.1); Assert.AreEqual(new Core.Color(0.4, 0.5, 0.5, 0.5), result); @@ -182,7 +182,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractRTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SubtractRGB(r: 10); Assert.AreEqual(new Core.Color(128, 118, 128, 128), result); @@ -191,7 +191,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractRPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SubtractRGB(r: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.4, 0.5, 0.5), result); @@ -200,7 +200,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractGTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SubtractRGB(g: 10); Assert.AreEqual(new Core.Color(128, 128, 118, 128), result); @@ -209,7 +209,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractGPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SubtractRGB(g: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.4, 0.5), result); @@ -218,7 +218,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractBTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SubtractRGB(b: 10); Assert.AreEqual(new Core.Color(128, 128, 128, 118), result); @@ -227,7 +227,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SubtractBPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SubtractRGB(b: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.4), result); @@ -240,7 +240,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void MultiplyRGBPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2); Core.Color result = baseColor.MultiplyRGB(3, 4, 5); Assert.AreEqual(new Core.Color(0.2, 0.6, 0.8, 1.0), result); @@ -249,7 +249,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void MultiplyAPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2); Core.Color result = baseColor.MultiplyA(3); Assert.AreEqual(new Core.Color(0.6, 0.2, 0.2, 0.2), result); @@ -258,7 +258,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void MultiplyRPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2); Core.Color result = baseColor.MultiplyRGB(r: 3); Assert.AreEqual(new Core.Color(0.2, 0.6, 0.2, 0.2), result); @@ -267,7 +267,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void MultiplyGPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2); Core.Color result = baseColor.MultiplyRGB(g: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.6, 0.2), result); @@ -276,7 +276,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void MultiplyBPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); + Core.Color baseColor = new(0.2, 0.2, 0.2, 0.2); Core.Color result = baseColor.MultiplyRGB(b: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.6), result); @@ -289,7 +289,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void DivideRGBPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.6, 0.8, 1.0); + Core.Color baseColor = new(0.2, 0.6, 0.8, 1.0); Core.Color result = baseColor.DivideRGB(3, 4, 5); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); @@ -298,7 +298,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void DivideAPercentTest() { - Core.Color baseColor = new Core.Color(0.6, 0.2, 0.2, 0.2); + Core.Color baseColor = new(0.6, 0.2, 0.2, 0.2); Core.Color result = baseColor.DivideA(3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); @@ -307,7 +307,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void DivideRPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.6, 0.2, 0.2); + Core.Color baseColor = new(0.2, 0.6, 0.2, 0.2); Core.Color result = baseColor.DivideRGB(r: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); @@ -316,7 +316,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void DivideGPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.6, 0.2); + Core.Color baseColor = new(0.2, 0.2, 0.6, 0.2); Core.Color result = baseColor.DivideRGB(g: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); @@ -325,7 +325,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void DivideBPercentTest() { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.6); + Core.Color baseColor = new(0.2, 0.2, 0.2, 0.6); Core.Color result = baseColor.DivideRGB(b: 3); Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); @@ -338,7 +338,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetRGBTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SetRGB(11, 12, 13); Assert.AreEqual(new Core.Color(128, 11, 12, 13), result); @@ -347,7 +347,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetRGBPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SetRGB(0.2, 0.3, 0.4); Assert.AreEqual(new Core.Color(0.5, 0.2, 0.3, 0.4), result); @@ -356,7 +356,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetATest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SetA(10); Assert.AreEqual(new Core.Color(10, 128, 128, 128), result); @@ -365,7 +365,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetAPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SetA(0.1); Assert.AreEqual(new Core.Color(0.1, 0.5, 0.5, 0.5), result); @@ -374,7 +374,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetRTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SetRGB(r: 10); Assert.AreEqual(new Core.Color(128, 10, 128, 128), result); @@ -383,7 +383,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetRPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SetRGB(r: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.1, 0.5, 0.5), result); @@ -392,7 +392,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetGTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SetRGB(g: 10); Assert.AreEqual(new Core.Color(128, 128, 10, 128), result); @@ -401,7 +401,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetGPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SetRGB(g: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.1, 0.5), result); @@ -410,7 +410,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetBTest() { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); + Core.Color baseColor = new(128, 128, 128, 128); Core.Color result = baseColor.SetRGB(b: 10); Assert.AreEqual(new Core.Color(128, 128, 128, 10), result); @@ -419,7 +419,7 @@ namespace RGB.NET.Core.Tests.Color [TestMethod] public void SetBPercentTest() { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); + Core.Color baseColor = new(0.5, 0.5, 0.5, 0.5); Core.Color result = baseColor.SetRGB(b: 0.1); Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.1), result);