mirror of
https://github.com/DarthAffe/RGB.NET.git
synced 2025-12-13 01:58:30 +00:00
Added caching to the linear gradient for a small performance gain
This commit is contained in:
parent
98331d0241
commit
575461ec5e
@ -1,6 +1,7 @@
|
|||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
|
||||||
@ -12,6 +13,13 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LinearGradient : AbstractGradient
|
public class LinearGradient : AbstractGradient
|
||||||
{
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private bool _isOrderedGradientListDirty = true;
|
||||||
|
private LinkedList<GradientStop> _orderedGradientStops;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -19,7 +27,9 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
/// Initializes a new instance of the <see cref="T:RGB.NET.Brushes.Gradients.LinearGradient" /> class.
|
/// Initializes a new instance of the <see cref="T:RGB.NET.Brushes.Gradients.LinearGradient" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LinearGradient()
|
public LinearGradient()
|
||||||
{ }
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -28,7 +38,9 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||||
public LinearGradient(params GradientStop[] gradientStops)
|
public LinearGradient(params GradientStop[] gradientStops)
|
||||||
: base(gradientStops)
|
: base(gradientStops)
|
||||||
{ }
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -38,12 +50,33 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
/// <param name="gradientStops">The stops with which the gradient should be initialized.</param>
|
||||||
public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops)
|
public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops)
|
||||||
: base(wrapGradient, gradientStops)
|
: base(wrapGradient, gradientStops)
|
||||||
{ }
|
{
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
|
private void Initialize()
|
||||||
|
{
|
||||||
|
void OnGradientStopOnPropertyChanged(object sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true;
|
||||||
|
|
||||||
|
foreach (GradientStop gradientStop in GradientStops)
|
||||||
|
gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged;
|
||||||
|
|
||||||
|
GradientStops.CollectionChanged += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.OldItems != null)
|
||||||
|
foreach (GradientStop gradientStop in args.OldItems)
|
||||||
|
gradientStop.PropertyChanged -= OnGradientStopOnPropertyChanged;
|
||||||
|
|
||||||
|
if (args.NewItems != null)
|
||||||
|
foreach (GradientStop gradientStop in args.NewItems)
|
||||||
|
gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the linear interpolated <see cref="T:RGB.NET.Core.Color" /> at the given offset.
|
/// Gets the linear interpolated <see cref="T:RGB.NET.Core.Color" /> at the given offset.
|
||||||
@ -55,7 +88,10 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
if (GradientStops.Count == 0) return Color.Transparent;
|
if (GradientStops.Count == 0) return Color.Transparent;
|
||||||
if (GradientStops.Count == 1) return GradientStops[0].Color;
|
if (GradientStops.Count == 1) return GradientStops[0].Color;
|
||||||
|
|
||||||
(GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, GradientStops, WrapGradient);
|
if (_isOrderedGradientListDirty)
|
||||||
|
_orderedGradientStops = new LinkedList<GradientStop>(GradientStops.OrderBy(x => x.Offset));
|
||||||
|
|
||||||
|
(GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, _orderedGradientStops, WrapGradient);
|
||||||
|
|
||||||
double blendFactor = 0;
|
double blendFactor = 0;
|
||||||
if (!gsBefore.Offset.Equals(gsAfter.Offset))
|
if (!gsBefore.Offset.Equals(gsAfter.Offset))
|
||||||
@ -73,12 +109,12 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
/// Get the two <see cref="GradientStop"/>s encapsulating the given offset.
|
/// Get the two <see cref="GradientStop"/>s encapsulating the given offset.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">The reference offset.</param>
|
/// <param name="offset">The reference offset.</param>
|
||||||
/// <param name="stops">The <see cref="GradientStop"/> to choose from.</param>
|
/// <param name="orderedStops">The ordered list of <see cref="GradientStop"/> to choose from.</param>
|
||||||
/// <param name="wrap">Bool indicating if the gradient should be wrapped or not.</param>
|
/// <param name="wrap">Bool indicating if the gradient should be wrapped or not.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(double offset, IEnumerable<GradientStop> stops, bool wrap)
|
protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(double offset, LinkedList<GradientStop> orderedStops, bool wrap)
|
||||||
{
|
{
|
||||||
LinkedList<GradientStop> orderedStops = new LinkedList<GradientStop>(stops.OrderBy(x => x.Offset));
|
LinkedList<GradientStop> gradientStops = new LinkedList<GradientStop>(orderedStops);
|
||||||
|
|
||||||
if (wrap)
|
if (wrap)
|
||||||
{
|
{
|
||||||
@ -86,20 +122,20 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
gsBefore = orderedStops.LastOrDefault(n => n.Offset <= offset);
|
gsBefore = gradientStops.LastOrDefault(n => n.Offset <= offset);
|
||||||
if (gsBefore == null)
|
if (gsBefore == null)
|
||||||
{
|
{
|
||||||
GradientStop lastStop = orderedStops.Last.Value;
|
GradientStop lastStop = gradientStops.Last.Value;
|
||||||
orderedStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color));
|
gradientStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color));
|
||||||
orderedStops.RemoveLast();
|
gradientStops.RemoveLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
gsAfter = orderedStops.FirstOrDefault(n => n.Offset >= offset);
|
gsAfter = gradientStops.FirstOrDefault(n => n.Offset >= offset);
|
||||||
if (gsAfter == null)
|
if (gsAfter == null)
|
||||||
{
|
{
|
||||||
GradientStop firstStop = orderedStops.First.Value;
|
GradientStop firstStop = gradientStops.First.Value;
|
||||||
orderedStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color));
|
gradientStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color));
|
||||||
orderedStops.RemoveFirst();
|
gradientStops.RemoveFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
} while ((gsBefore == null) || (gsAfter == null));
|
} while ((gsBefore == null) || (gsAfter == null));
|
||||||
@ -108,7 +144,7 @@ namespace RGB.NET.Brushes.Gradients
|
|||||||
}
|
}
|
||||||
|
|
||||||
offset = ClipOffset(offset);
|
offset = ClipOffset(offset);
|
||||||
return (orderedStops.Last(n => n.Offset <= offset), orderedStops.First(n => n.Offset >= offset));
|
return (gradientStops.Last(n => n.Offset <= offset), gradientStops.First(n => n.Offset >= offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user