1
0
mirror of https://github.com/DarthAffe/RGB.NET.git synced 2025-12-12 17:48:31 +00:00

Reduced some allocations mostly due to boxing

This commit is contained in:
Darth Affe 2023-02-05 07:36:50 +01:00
parent b8b2343d6c
commit d60d4833ca
11 changed files with 80 additions and 70 deletions

View File

@ -6,7 +6,7 @@ namespace RGB.NET.Core;
/// <summary>
/// Represents the default-behavior for the work with colors.
/// </summary>
public class DefaultColorBehavior : IColorBehavior
public sealed class DefaultColorBehavior : IColorBehavior
{
#region Methods
@ -14,7 +14,7 @@ public class DefaultColorBehavior : IColorBehavior
/// Converts the individual byte values of this <see cref="Color"/> to a human-readable string.
/// </summary>
/// <returns>A string that contains the individual byte values of this <see cref="Color"/>. For example "[A: 255, R: 255, G: 0, B: 0]".</returns>
public virtual string ToString(in Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]";
public string ToString(in Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]";
/// <summary>
/// Tests whether the specified object is a <see cref="Color" /> and is equivalent to this <see cref="Color" />.
@ -22,28 +22,35 @@ public class DefaultColorBehavior : IColorBehavior
/// <param name="color">The color to test.</param>
/// <param name="obj">The object to test.</param>
/// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Color" /> equivalent to this <see cref="Color" />; otherwise, <c>false</c>.</returns>
public virtual bool Equals(in Color color, object? obj)
public bool Equals(in Color color, object? obj)
{
if (obj is not Color color2) return false;
return color.A.EqualsInTolerance(color2.A)
&& color.R.EqualsInTolerance(color2.R)
&& color.G.EqualsInTolerance(color2.G)
&& color.B.EqualsInTolerance(color2.B);
return Equals(color, color2);
}
/// <summary>
/// Tests whether the specified object is a <see cref="Color" /> and is equivalent to this <see cref="Color" />.
/// </summary>
/// <param name="color">The first color to test.</param>
/// <param name="color2">The second color to test.</param>
/// <returns><c>true</c> if <paramref name="color2" /> equivalent to this <see cref="Color" />; otherwise, <c>false</c>.</returns>
public bool Equals(in Color color, in Color color2) => color.A.EqualsInTolerance(color2.A)
&& color.R.EqualsInTolerance(color2.R)
&& color.G.EqualsInTolerance(color2.G)
&& color.B.EqualsInTolerance(color2.B);
/// <summary>
/// Returns a hash code for this <see cref="Color" />.
/// </summary>
/// <returns>An integer value that specifies the hash code for this <see cref="Color" />.</returns>
public virtual int GetHashCode(in Color color) => HashCode.Combine(color.A, color.R, color.G, color.B);
public int GetHashCode(in Color color) => HashCode.Combine(color.A, color.R, color.G, color.B);
/// <summary>
/// Blends a <see cref="Color"/> over this color.
/// </summary>
/// <param name="baseColor">The <see cref="Color"/> to to blend over.</param>
/// <param name="blendColor">The <see cref="Color"/> to blend.</param>
public virtual Color Blend(in Color baseColor, in Color blendColor)
public Color Blend(in Color baseColor, in Color blendColor)
{
if (blendColor.A.EqualsInTolerance(0)) return baseColor;

View File

@ -20,6 +20,14 @@ public interface IColorBehavior
/// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Color" /> equivalent to this <see cref="Color" />; otherwise, <c>false</c>.</returns>
bool Equals(in Color color, object? obj);
/// <summary>
/// Tests whether the specified object is a <see cref="Color" /> and is equivalent to this <see cref="Color" />.
/// </summary>
/// <param name="color">The first color to test.</param>
/// <param name="color2">The second color to test.</param>
/// <returns><c>true</c> if <paramref name="color2" /> equivalent to this <see cref="Color" />; otherwise, <c>false</c>.</returns>
bool Equals(in Color color, in Color color2);
/// <summary>
/// Returns a hash code for this <see cref="Color" />.
/// </summary>

View File

@ -11,7 +11,7 @@ namespace RGB.NET.Core;
/// Represents an ARGB (alpha, red, green, blue) color.
/// </summary>
[DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")]
public readonly struct Color
public readonly struct Color : IEquatable<Color>
{
#region Constants
@ -196,6 +196,13 @@ public readonly struct Color
/// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Color" /> equivalent to this <see cref="Color" />; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj) => Behavior.Equals(this, obj);
/// <summary>
/// Tests whether the specified <see cref="Color" /> is equivalent to this <see cref="Color" />, as defined by the current <see cref="Behavior"/>.
/// </summary>
/// <param name="other">The color to test.</param>
/// <returns><c>true</c> if <paramref name="other" /> is equivalent to this <see cref="Color" />; otherwise, <c>false</c>.</returns>
public bool Equals(Color other) => Behavior.Equals(this, other);
/// <summary>
/// Returns a hash code for this <see cref="Color" />, as defined by the current <see cref="Behavior"/>.
/// </summary>

View File

@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace RGB.NET.Core;
@ -28,7 +29,7 @@ public abstract class AbstractBindable : IBindable
/// <param name="value">Value to apply.</param>
/// <returns><c>true</c> if the value needs to be updated; otherweise <c>false</c>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected virtual bool RequiresUpdate<T>(ref T storage, T value) => !Equals(storage, value);
protected virtual bool RequiresUpdate<T>(ref T storage, T value) => !EqualityComparer<T>.Default.Equals(storage, value);
/// <summary>
/// Checks if the property already matches the desired value and updates it if not.

View File

@ -211,7 +211,7 @@ public class Placeable : AbstractBindable, IPlaceable
/// </summary>
protected virtual void OnLocationChanged()
{
LocationChanged?.Invoke(this, new EventArgs());
LocationChanged?.Invoke(this, EventArgs.Empty);
UpdateActualPlaceableData();
}
@ -220,7 +220,7 @@ public class Placeable : AbstractBindable, IPlaceable
/// </summary>
protected virtual void OnSizeChanged()
{
SizeChanged?.Invoke(this, new EventArgs());
SizeChanged?.Invoke(this, EventArgs.Empty);
UpdateActualPlaceableData();
}
@ -229,7 +229,7 @@ public class Placeable : AbstractBindable, IPlaceable
/// </summary>
protected virtual void OnScaleChanged()
{
ScaleChanged?.Invoke(this, new EventArgs());
ScaleChanged?.Invoke(this, EventArgs.Empty);
UpdateActualPlaceableData();
}
@ -238,24 +238,24 @@ public class Placeable : AbstractBindable, IPlaceable
/// </summary>
protected virtual void OnRotationChanged()
{
RotationChanged?.Invoke(this, new EventArgs());
RotationChanged?.Invoke(this, EventArgs.Empty);
UpdateActualPlaceableData();
}
/// <summary>
/// Called when the <see cref="ActualLocation"/> property was changed.
/// </summary>
protected virtual void OnActualLocationChanged() => ActualLocationChanged?.Invoke(this, new EventArgs());
protected virtual void OnActualLocationChanged() => ActualLocationChanged?.Invoke(this, EventArgs.Empty);
/// <summary>
/// Called when the <see cref="ActualLocation"/> property was changed.
/// </summary>
protected virtual void OnActualSizeChanged() => ActualSizeChanged?.Invoke(this, new EventArgs());
protected virtual void OnActualSizeChanged() => ActualSizeChanged?.Invoke(this, EventArgs.Empty);
/// <summary>
/// Called when the <see cref="Boundary"/> property was changed.
/// </summary>
protected virtual void OnBoundaryChanged() => BoundaryChanged?.Invoke(this, new EventArgs());
protected virtual void OnBoundaryChanged() => BoundaryChanged?.Invoke(this, EventArgs.Empty);
#endregion
}

View File

@ -10,7 +10,7 @@ namespace RGB.NET.Core;
/// Represents a point consisting of a X- and a Y-position.
/// </summary>
[DebuggerDisplay("[X: {X}, Y: {Y}]")]
public readonly struct Point
public readonly struct Point : IEquatable<Point>
{
#region Constants
@ -59,18 +59,20 @@ public readonly struct Point
/// <returns>A string that contains the <see cref="X"/> and <see cref="Y"/> of this <see cref="Point"/>. For example "[X: 100, Y: 20]".</returns>
public override string ToString() => $"[X: {X}, Y: {Y}]";
/// <summary>
/// Tests whether the specified <see cref="Point" /> is equivalent to this <see cref="Point" />.
/// </summary>
/// <param name="other">The point to test.</param>
/// <returns><c>true</c> if <paramref name="other" /> is equivalent to this <see cref="Point" />; otherwise, <c>false</c>.</returns>
public bool Equals(Point other) => ((float.IsNaN(X) && float.IsNaN(other.X)) || X.EqualsInTolerance(other.X))
&& ((float.IsNaN(Y) && float.IsNaN(other.Y)) || Y.EqualsInTolerance(other.Y));
/// <summary>
/// Tests whether the specified object is a <see cref="Point" /> and is equivalent to this <see cref="Point" />.
/// </summary>
/// <param name="obj">The object to test.</param>
/// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Point" /> equivalent to this <see cref="Point" />; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
if (obj is not Point comparePoint) return false;
return ((float.IsNaN(X) && float.IsNaN(comparePoint.X)) || X.EqualsInTolerance(comparePoint.X))
&& ((float.IsNaN(Y) && float.IsNaN(comparePoint.Y)) || Y.EqualsInTolerance(comparePoint.Y));
}
public override bool Equals(object? obj) => obj is Point other && Equals(other);
/// <summary>
/// Returns a hash code for this <see cref="Point" />.

View File

@ -12,7 +12,7 @@ namespace RGB.NET.Core;
/// Represents a rectangle defined by it's position and it's size.
/// </summary>
[DebuggerDisplay("[Location: {Location}, Size: {Size}]")]
public readonly struct Rectangle
public readonly struct Rectangle : IEquatable<Rectangle>
{
#region Properties & Fields
@ -172,35 +172,25 @@ public readonly struct Rectangle
/// <returns>A string that contains the <see cref="Location"/> and <see cref="Size"/> of this <see cref="Rectangle"/>. For example "[Location: [X: 100, Y: 10], Size: [Width: 20, Height: [40]]".</returns>
public override string ToString() => $"[Location: {Location}, Size: {Size}]";
/// <summary>
/// Tests whether the specified <see cref="Rectangle" /> is equivalent to this <see cref="Rectangle" />.
/// </summary>
/// <param name="other">The rectangle to test.</param>
/// <returns><c>true</c> if <paramref name="other" /> is equivalent to this <see cref="Rectangle" />; otherwise, <c>false</c>.</returns>
public bool Equals(Rectangle other) => (Location == other.Location) && (Size == other.Size);
/// <summary>
/// Tests whether the specified object is a <see cref="Rectangle" /> and is equivalent to this <see cref="Rectangle" />.
/// </summary>
/// <param name="obj">The object to test.</param>
/// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Rectangle" /> equivalent to this <see cref="Rectangle" />; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
if (obj is not Rectangle compareRect)
return false;
if (GetType() != compareRect.GetType())
return false;
return (Location == compareRect.Location) && (Size == compareRect.Size);
}
public override bool Equals(object? obj) => obj is Rectangle other && Equals(other);
/// <summary>
/// Returns a hash code for this <see cref="Rectangle" />.
/// </summary>
/// <returns>An integer value that specifies the hash code for this <see cref="Rectangle" />.</returns>
public override int GetHashCode()
{
unchecked
{
int hashCode = Location.GetHashCode();
hashCode = (hashCode * 397) ^ Size.GetHashCode();
return hashCode;
}
}
public override int GetHashCode() => HashCode.Combine(Location, Size);
#endregion

View File

@ -10,7 +10,7 @@ namespace RGB.NET.Core;
/// Represents an angular rotation.
/// </summary>
[DebuggerDisplay("[{" + nameof(Degrees) + "}°]")]
public readonly struct Rotation
public readonly struct Rotation : IEquatable<Rotation>
{
#region Constants

View File

@ -1,6 +1,7 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Diagnostics;
namespace RGB.NET.Core;
@ -9,7 +10,7 @@ namespace RGB.NET.Core;
/// Represents a scaling.
/// </summary>
[DebuggerDisplay("[Horizontal: {Horizontal}, Vertical: {Vertical}]")]
public readonly struct Scale
public readonly struct Scale : IEquatable<Scale>
{
#region Properties & Fields
@ -67,7 +68,7 @@ public readonly struct Scale
/// Returns a hash code for this <see cref="Scale" />.
/// </summary>
/// <returns>An integer value that specifies the hash code for this <see cref="Scale" />.</returns>
public override int GetHashCode() { unchecked { return (Horizontal.GetHashCode() * 397) ^ Vertical.GetHashCode(); } }
public override int GetHashCode() => HashCode.Combine(Horizontal, Vertical);
/// <summary>
/// Deconstructs the scale into the horizontal and vertical value.

View File

@ -1,6 +1,7 @@
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedMember.Global
using System;
using System.Diagnostics;
namespace RGB.NET.Core;
@ -9,7 +10,7 @@ namespace RGB.NET.Core;
/// Represents a size consisting of a width and a height.
/// </summary>
[DebuggerDisplay("[Width: {Width}, Height: {Height}]")]
public readonly struct Size
public readonly struct Size : IEquatable<Size>
{
#region Constants
@ -67,33 +68,26 @@ public readonly struct Size
/// <returns>A string that contains the <see cref="Width"/> and <see cref="Height"/> of this <see cref="Size"/>. For example "[Width: 100, Height: 20]".</returns>
public override string ToString() => $"[Width: {Width}, Height: {Height}]";
/// <summary>
/// Tests whether the specified <see cref="Size" /> is equivalent to this <see cref="Size" />.
/// </summary>
/// <param name="other">The size to test.</param>
/// <returns><c>true</c> if <paramref name="other" /> is equivalent to this <see cref="Size" />; otherwise, <c>false</c>.</returns>
public bool Equals(Size other) => ((float.IsNaN(Width) && float.IsNaN(other.Width)) || Width.EqualsInTolerance(other.Width))
&& ((float.IsNaN(Height) && float.IsNaN(other.Height)) || Height.EqualsInTolerance(other.Height));
/// <summary>
/// Tests whether the specified object is a <see cref="Size" /> and is equivalent to this <see cref="Size" />.
/// </summary>
/// <param name="obj">The object to test.</param>
/// <returns><c>true</c> if <paramref name="obj" /> is a <see cref="Size" /> equivalent to this <see cref="Size" />; otherwise, <c>false</c>.</returns>
public override bool Equals(object? obj)
{
if (obj is not Size size) return false;
(float width, float height) = size;
return ((float.IsNaN(Width) && float.IsNaN(width)) || Width.EqualsInTolerance(width))
&& ((float.IsNaN(Height) && float.IsNaN(height)) || Height.EqualsInTolerance(height));
}
public override bool Equals(object? obj) => obj is Size other && Equals(other);
/// <summary>
/// Returns a hash code for this <see cref="Size" />.
/// </summary>
/// <returns>An integer value that specifies the hash code for this <see cref="Size" />.</returns>
public override int GetHashCode()
{
unchecked
{
int hashCode = Width.GetHashCode();
hashCode = (hashCode * 397) ^ Height.GetHashCode();
return hashCode;
}
}
public override int GetHashCode() => HashCode.Combine(Width, Height);
/// <summary>
/// Deconstructs the size into the width and height value.

View File

@ -10,7 +10,7 @@ namespace RGB.NET.Core;
/// <remarks>
/// Averages all components (A, R, G, B) of the colors separately which isn't ideal in cases where multiple different colors are combined.
/// </remarks>
public class AverageColorSampler : ISampler<Color>
public sealed class AverageColorSampler : ISampler<Color>
{
#region Constants