mirror of
https://github.com/DarthAffe/RGB.NET.git
synced 2025-12-31 09:44:21 +00:00
Compare commits
4 Commits
764fcd1b1d
...
260a820b80
| Author | SHA1 | Date | |
|---|---|---|---|
| 260a820b80 | |||
| 4ee55c6725 | |||
| 70ccc4d575 | |||
| 0cf4f39ccf |
@ -7,6 +7,7 @@ using System.Buffers;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace RGB.NET.Core;
|
namespace RGB.NET.Core;
|
||||||
|
|
||||||
@ -120,6 +121,7 @@ public abstract class AbstractRGBDevice<TDeviceInfo> : Placeable, IRGBDevice<TDe
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="leds">The enumerable of leds to convert.</param>
|
/// <param name="leds">The enumerable of leds to convert.</param>
|
||||||
/// <returns>The enumerable of custom data and color tuples for the specified leds.</returns>
|
/// <returns>The enumerable of custom data and color tuples for the specified leds.</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
protected (object key, Color color) GetUpdateData(Led led)
|
protected (object key, Color color) GetUpdateData(Led led)
|
||||||
{
|
{
|
||||||
Color color = led.Color;
|
Color color = led.Color;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using System.Collections;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
@ -61,5 +62,14 @@ public abstract class AbstractLedGroup : AbstractDecoratable<ILedGroupDecorator>
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IEnumerator<Led> GetEnumerator() => GetLeds().GetEnumerator();
|
public IEnumerator<Led> GetEnumerator() => GetLeds().GetEnumerator();
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
IDisposable? ILedGroup.ToListUnsafe(out IList<Led> leds) => ToListUnsafe(out leds);
|
||||||
|
|
||||||
|
protected virtual IDisposable? ToListUnsafe(out IList<Led> leds)
|
||||||
|
{
|
||||||
|
leds = ToList();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
// ReSharper disable UnusedMemberInSuper.Global
|
// ReSharper disable UnusedMemberInSuper.Global
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace RGB.NET.Core;
|
namespace RGB.NET.Core;
|
||||||
@ -45,4 +46,6 @@ public interface ILedGroup : IDecoratable<ILedGroupDecorator>, IEnumerable<Led>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A list containing all <see cref="Led"/> in this group.</returns>
|
/// <returns>A list containing all <see cref="Led"/> in this group.</returns>
|
||||||
IList<Led> ToList();
|
IList<Led> ToList();
|
||||||
|
|
||||||
|
internal IDisposable? ToListUnsafe(out IList<Led> leds);
|
||||||
}
|
}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
// ReSharper disable MemberCanBePrivate.Global
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace RGB.NET.Core;
|
namespace RGB.NET.Core;
|
||||||
|
|
||||||
@ -13,6 +15,8 @@ public class ListLedGroup : AbstractLedGroup
|
|||||||
{
|
{
|
||||||
#region Properties & Fields
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly ActionDisposable _unlockDisposable;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the list containing the <see cref="Led"/> of this <see cref="ListLedGroup"/>.
|
/// Gets the list containing the <see cref="Led"/> of this <see cref="ListLedGroup"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -29,7 +33,9 @@ public class ListLedGroup : AbstractLedGroup
|
|||||||
/// <param name="surface">Specifies the surface to attach this group to or <c>null</c> if the group should not be attached on creation.</param>
|
/// <param name="surface">Specifies the surface to attach this group to or <c>null</c> if the group should not be attached on creation.</param>
|
||||||
public ListLedGroup(RGBSurface? surface)
|
public ListLedGroup(RGBSurface? surface)
|
||||||
: base(surface)
|
: base(surface)
|
||||||
{ }
|
{
|
||||||
|
_unlockDisposable = new ActionDisposable(Unlock);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -40,6 +46,8 @@ public class ListLedGroup : AbstractLedGroup
|
|||||||
public ListLedGroup(RGBSurface? surface, IEnumerable<Led> leds)
|
public ListLedGroup(RGBSurface? surface, IEnumerable<Led> leds)
|
||||||
: base(surface)
|
: base(surface)
|
||||||
{
|
{
|
||||||
|
_unlockDisposable = new ActionDisposable(Unlock);
|
||||||
|
|
||||||
AddLeds(leds);
|
AddLeds(leds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +60,8 @@ public class ListLedGroup : AbstractLedGroup
|
|||||||
public ListLedGroup(RGBSurface? surface, params Led[] leds)
|
public ListLedGroup(RGBSurface? surface, params Led[] leds)
|
||||||
: base(surface)
|
: base(surface)
|
||||||
{
|
{
|
||||||
|
_unlockDisposable = new ActionDisposable(Unlock);
|
||||||
|
|
||||||
AddLeds(leds);
|
AddLeds(leds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,5 +145,14 @@ public class ListLedGroup : AbstractLedGroup
|
|||||||
return new List<Led>(GroupLeds);
|
return new List<Led>(GroupLeds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IDisposable ToListUnsafe(out IList<Led> leds)
|
||||||
|
{
|
||||||
|
Monitor.Enter(GroupLeds);
|
||||||
|
leds = GroupLeds;
|
||||||
|
return _unlockDisposable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Unlock() => Monitor.Exit(GroupLeds);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
27
RGB.NET.Core/Misc/ActionDisposable.cs
Normal file
27
RGB.NET.Core/Misc/ActionDisposable.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace RGB.NET.Core;
|
||||||
|
|
||||||
|
public sealed class ActionDisposable : IDisposable
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly Action _onDispose;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ActionDisposable(Action onDispose)
|
||||||
|
{
|
||||||
|
this._onDispose = onDispose;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public void Dispose() => _onDispose();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
@ -208,26 +208,27 @@ public sealed class RGBSurface : AbstractBindable, IDisposable
|
|||||||
|
|
||||||
if ((brush == null) || !brush.IsEnabled) return;
|
if ((brush == null) || !brush.IsEnabled) return;
|
||||||
|
|
||||||
IList<Led> leds = ledGroup.ToList();
|
using (ledGroup.ToListUnsafe(out IList<Led> leds))
|
||||||
|
|
||||||
IEnumerable<(RenderTarget renderTarget, Color color)> render;
|
|
||||||
switch (brush.CalculationMode)
|
|
||||||
{
|
{
|
||||||
case RenderMode.Relative:
|
IEnumerable<(RenderTarget renderTarget, Color color)> render;
|
||||||
Rectangle brushRectangle = new(leds);
|
switch (brush.CalculationMode)
|
||||||
Point offset = new(-brushRectangle.Location.X, -brushRectangle.Location.Y);
|
{
|
||||||
brushRectangle = brushRectangle.SetLocation(new Point(0, 0));
|
case RenderMode.Relative:
|
||||||
render = brush.Render(brushRectangle, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary.Translate(offset))));
|
Rectangle brushRectangle = new(leds);
|
||||||
break;
|
Point offset = new(-brushRectangle.Location.X, -brushRectangle.Location.Y);
|
||||||
case RenderMode.Absolute:
|
brushRectangle = brushRectangle.SetLocation(new Point(0, 0));
|
||||||
render = brush.Render(Boundary, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary)));
|
render = brush.Render(brushRectangle, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary.Translate(offset))));
|
||||||
break;
|
break;
|
||||||
default:
|
case RenderMode.Absolute:
|
||||||
throw new ArgumentException($"The CalculationMode '{brush.CalculationMode}' is not valid.");
|
render = brush.Render(Boundary, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary)));
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentException($"The CalculationMode '{brush.CalculationMode}' is not valid.");
|
||||||
|
}
|
||||||
|
|
||||||
foreach ((RenderTarget renderTarget, Color c) in render)
|
foreach ((RenderTarget renderTarget, Color c) in render)
|
||||||
renderTarget.Led.Color = c;
|
renderTarget.Led.Color = c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -76,6 +76,7 @@ public abstract class PixelTexture<T> : ITexture
|
|||||||
/// <param name="width">The with of the region.</param>
|
/// <param name="width">The with of the region.</param>
|
||||||
/// <param name="height">The height of the region.</param>
|
/// <param name="height">The height of the region.</param>
|
||||||
/// <returns>The sampled color.</returns>
|
/// <returns>The sampled color.</returns>
|
||||||
|
[SkipLocalsInit]
|
||||||
public virtual Color this[int x, int y, int width, int height]
|
public virtual Color this[int x, int y, int width, int height]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|||||||
@ -157,11 +157,13 @@ public class DeviceUpdateTrigger : AbstractUpdateTrigger, IDeviceUpdateTrigger
|
|||||||
using (TimerHelper.RequestHighResolutionTimer())
|
using (TimerHelper.RequestHighResolutionTimer())
|
||||||
while (!UpdateToken.IsCancellationRequested)
|
while (!UpdateToken.IsCancellationRequested)
|
||||||
if (HasDataEvent.WaitOne(Timeout))
|
if (HasDataEvent.WaitOne(Timeout))
|
||||||
LastUpdateTime = TimerHelper.Execute(() => OnUpdate(), UpdateFrequency * 1000);
|
LastUpdateTime = TimerHelper.Execute(TimerExecute, UpdateFrequency * 1000);
|
||||||
else if ((HeartbeatTimer > 0) && (LastUpdateTimestamp > 0) && (TimerHelper.GetElapsedTime(LastUpdateTimestamp) > HeartbeatTimer))
|
else if ((HeartbeatTimer > 0) && (LastUpdateTimestamp > 0) && (TimerHelper.GetElapsedTime(LastUpdateTimestamp) > HeartbeatTimer))
|
||||||
OnUpdate(new CustomUpdateData().Heartbeat());
|
OnUpdate(new CustomUpdateData().Heartbeat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TimerExecute() => OnUpdate();
|
||||||
|
|
||||||
protected override void OnUpdate(CustomUpdateData? updateData = null)
|
protected override void OnUpdate(CustomUpdateData? updateData = null)
|
||||||
{
|
{
|
||||||
base.OnUpdate(updateData);
|
base.OnUpdate(updateData);
|
||||||
|
|||||||
@ -83,12 +83,12 @@ public sealed class ManualUpdateTrigger : AbstractUpdateTrigger
|
|||||||
OnStartup();
|
OnStartup();
|
||||||
|
|
||||||
while (!UpdateToken.IsCancellationRequested)
|
while (!UpdateToken.IsCancellationRequested)
|
||||||
{
|
|
||||||
if (_mutex.WaitOne(100))
|
if (_mutex.WaitOne(100))
|
||||||
LastUpdateTime = TimerHelper.Execute(() => OnUpdate(_customUpdateData));
|
LastUpdateTime = TimerHelper.Execute(TimerExecute);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TimerExecute() => OnUpdate(_customUpdateData);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Dispose() => Stop();
|
public override void Dispose() => Stop();
|
||||||
|
|
||||||
|
|||||||
@ -131,10 +131,11 @@ public class TimerUpdateTrigger : AbstractUpdateTrigger
|
|||||||
|
|
||||||
using (TimerHelper.RequestHighResolutionTimer())
|
using (TimerHelper.RequestHighResolutionTimer())
|
||||||
while (!UpdateToken.IsCancellationRequested)
|
while (!UpdateToken.IsCancellationRequested)
|
||||||
LastUpdateTime = TimerHelper.Execute(() => OnUpdate(_customUpdateData), UpdateFrequency * 1000);
|
LastUpdateTime = TimerHelper.Execute(TimerExecute, UpdateFrequency * 1000);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TimerExecute() => OnUpdate(_customUpdateData);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
|
||||||
// ReSharper disable UnusedMember.Global
|
// ReSharper disable UnusedMember.Global
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
@ -121,7 +122,7 @@ public class RectangleLedGroup : AbstractLedGroup
|
|||||||
/// Gets a list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Presets.Groups.RectangleLedGroup" />.
|
/// Gets a list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Presets.Groups.RectangleLedGroup" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Presets.Groups.RectangleLedGroup" />.</returns>
|
/// <returns>The list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Presets.Groups.RectangleLedGroup" />.</returns>
|
||||||
public override IList<Led> ToList() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List<Led>());
|
public override IList<Led> ToList() => _ledCache ??= ((IList<Led>?)Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? Array.Empty<Led>());
|
||||||
|
|
||||||
private void InvalidateCache() => _ledCache = null;
|
private void InvalidateCache() => _ledCache = null;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ public class AverageByteSampler : ISampler<byte>
|
|||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[SkipLocalsInit]
|
||||||
public unsafe void Sample(in SamplerInfo<byte> info, in Span<byte> pixelData)
|
public unsafe void Sample(in SamplerInfo<byte> info, in Span<byte> pixelData)
|
||||||
{
|
{
|
||||||
int count = info.Width * info.Height;
|
int count = info.Width * info.Height;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ public class AverageFloatSampler : ISampler<float>
|
|||||||
#region Methods
|
#region Methods
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
[SkipLocalsInit]
|
||||||
public unsafe void Sample(in SamplerInfo<float> info, in Span<float> pixelData)
|
public unsafe void Sample(in SamplerInfo<float> info, in Span<float> pixelData)
|
||||||
{
|
{
|
||||||
int count = info.Width * info.Height;
|
int count = info.Width * info.Height;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user