From f14e3c801d9c7649d0f9a5bd51792595c11a962b Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Fri, 5 Mar 2021 21:43:12 +0100 Subject: [PATCH] Moved all methods not directly tied to the surface in an extension and refactored led groups --- RGB.NET.Core/Devices/AbstractRGBDevice.cs | 3 - RGB.NET.Core/Extensions/SurfaceExtensions.cs | 64 +++++++++++++ RGB.NET.Core/Groups/AbstractLedGroup.cs | 21 +++-- RGB.NET.Core/Groups/ILedGroup.cs | 17 ++-- RGB.NET.Core/Groups/LedGroupExtension.cs | 12 +-- RGB.NET.Core/Groups/ListLedGroup.cs | 4 +- RGB.NET.Core/RGBSurface.cs | 94 ++++---------------- RGB.NET.Presets/Groups/RectangleLedGroup.cs | 17 ++-- 8 files changed, 118 insertions(+), 114 deletions(-) create mode 100644 RGB.NET.Core/Extensions/SurfaceExtensions.cs diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs index cf47142..7b28a30 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs @@ -90,9 +90,6 @@ namespace RGB.NET.Core // Send LEDs to SDK List ledsToUpdate = GetLedsToUpdate(flushLeds).ToList(); - foreach (Led ledToUpdate in ledsToUpdate) - ledToUpdate.Update(); - UpdateLeds(ledsToUpdate); } diff --git a/RGB.NET.Core/Extensions/SurfaceExtensions.cs b/RGB.NET.Core/Extensions/SurfaceExtensions.cs new file mode 100644 index 0000000..0a93c69 --- /dev/null +++ b/RGB.NET.Core/Extensions/SurfaceExtensions.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace RGB.NET.Core +{ + public static class SurfaceExtensions + { + #region Methods + + public static void Load(this RGBSurface surface, IRGBDeviceProvider deviceProvider, RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + { + if (!deviceProvider.IsInitialized) + deviceProvider.Initialize(loadFilter, throwExceptions); + + surface.Attach(deviceProvider.Devices); + } + + + public static void Attach(this RGBSurface surface, IEnumerable devices) + { + foreach (IRGBDevice device in devices) + surface.Attach(device); + } + + public static void Detach(this RGBSurface surface, IEnumerable devices) + { + foreach (IRGBDevice device in devices) + surface.Detach(device); + } + + /// + /// Gets all devices of a specific type. + /// + /// The type of devices to get. + /// A collection of devices with the specified type. + public static IEnumerable GetDevices(this RGBSurface surface) + where T : class + => surface.Devices.Where(x => x is T).Cast(); + + /// + /// Gets all devices of the specified . + /// + /// The of the devices to get. + /// A collection of devices matching the specified . + public static IEnumerable GetDevices(this RGBSurface surface, RGBDeviceType deviceType) + => surface.Devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)); + + /// + /// Automatically aligns all devices to prevent overlaps. + /// + public static void AlignDevices(this RGBSurface surface) + { + float posX = 0; + foreach (IRGBDevice device in surface.Devices) + { + device.Location += new Point(posX, 0); + posX += device.ActualSize.Width + 1; + } + } + + #endregion + } +} diff --git a/RGB.NET.Core/Groups/AbstractLedGroup.cs b/RGB.NET.Core/Groups/AbstractLedGroup.cs index 3720302..c035937 100644 --- a/RGB.NET.Core/Groups/AbstractLedGroup.cs +++ b/RGB.NET.Core/Groups/AbstractLedGroup.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; namespace RGB.NET.Core { @@ -11,7 +12,8 @@ namespace RGB.NET.Core { #region Properties & Fields - public RGBSurface? Surface { get; private set; } + RGBSurface? ILedGroup.Surface { get; set; } + public RGBSurface? Surface => ((ILedGroup)this).Surface; /// public IBrush? Brush { get; set; } @@ -28,21 +30,26 @@ namespace RGB.NET.Core /// protected AbstractLedGroup(RGBSurface? attachTo) { - attachTo?.AttachLedGroup(this); + attachTo?.Attach(this); } #endregion #region Methods - /// - public abstract IList GetLeds(); + protected abstract IEnumerable GetLeds(); /// - public virtual void OnAttach(RGBSurface surface) => Surface = surface; + public virtual void OnAttach() { } /// - public virtual void OnDetach(RGBSurface surface) => Surface = null; + public virtual void OnDetach() { } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator GetEnumerator() => GetLeds().GetEnumerator(); #endregion } diff --git a/RGB.NET.Core/Groups/ILedGroup.cs b/RGB.NET.Core/Groups/ILedGroup.cs index 3985f8a..adcf9b7 100644 --- a/RGB.NET.Core/Groups/ILedGroup.cs +++ b/RGB.NET.Core/Groups/ILedGroup.cs @@ -5,13 +5,14 @@ using System.Collections.Generic; namespace RGB.NET.Core { - /// /// /// Represents a generic ledgroup. /// - public interface ILedGroup : IDecoratable + public interface ILedGroup : IDecoratable, IEnumerable { - public RGBSurface? Surface { get; } + RGBSurface? Surface { get; internal set; } + + bool IsAttached => Surface != null; /// /// Gets or sets the which should be drawn over this . @@ -23,20 +24,14 @@ namespace RGB.NET.Core /// int ZIndex { get; set; } - /// - /// Gets a list containing all of this . - /// - /// The list containing all of this . - IList GetLeds(); - /// /// Called when the is attached to the . /// - void OnAttach(RGBSurface surface); + void OnAttach(); /// /// Called when the is detached from the . /// - void OnDetach(RGBSurface surface); + void OnDetach(); } } diff --git a/RGB.NET.Core/Groups/LedGroupExtension.cs b/RGB.NET.Core/Groups/LedGroupExtension.cs index 3a8c9f7..3d29d4c 100644 --- a/RGB.NET.Core/Groups/LedGroupExtension.cs +++ b/RGB.NET.Core/Groups/LedGroupExtension.cs @@ -16,11 +16,11 @@ namespace RGB.NET.Core public static ListLedGroup ToListLedGroup(this ILedGroup ledGroup) { // ReSharper disable once InvertIf - if (!(ledGroup is ListLedGroup listLedGroup)) + if (ledGroup is not ListLedGroup listLedGroup) { - if (ledGroup.Surface != null) - ledGroup.Detach(ledGroup.Surface); - listLedGroup = new ListLedGroup(ledGroup.Surface, ledGroup.GetLeds()) { Brush = ledGroup.Brush }; + if (ledGroup.IsAttached) + ledGroup.Detach(); + listLedGroup = new ListLedGroup(ledGroup.Surface, ledGroup) { Brush = ledGroup.Brush, ZIndex = ledGroup.ZIndex }; } return listLedGroup; } @@ -45,13 +45,13 @@ namespace RGB.NET.Core /// /// The to attach. /// true if the could be attached; otherwise, false. - public static bool Attach(this ILedGroup ledGroup, RGBSurface surface) => surface.AttachLedGroup(ledGroup); + public static bool Attach(this ILedGroup ledGroup, RGBSurface surface) => surface.Attach(ledGroup); /// /// Detaches the given from the . /// /// The to attach. /// true if the could be detached; otherwise, false. - public static bool Detach(this ILedGroup ledGroup, RGBSurface surface) => surface.DetachLedGroup(ledGroup); + public static bool Detach(this ILedGroup ledGroup) => ledGroup.Surface?.Detach(ledGroup) ?? false; } } diff --git a/RGB.NET.Core/Groups/ListLedGroup.cs b/RGB.NET.Core/Groups/ListLedGroup.cs index f4aa007..b6be55b 100644 --- a/RGB.NET.Core/Groups/ListLedGroup.cs +++ b/RGB.NET.Core/Groups/ListLedGroup.cs @@ -113,7 +113,7 @@ namespace RGB.NET.Core public void MergeLeds(ILedGroup groupToMerge) { lock (GroupLeds) - foreach (Led led in groupToMerge.GetLeds()) + foreach (Led led in groupToMerge) if (!GroupLeds.Contains(led)) GroupLeds.Add(led); } @@ -123,7 +123,7 @@ namespace RGB.NET.Core /// Gets a list containing the from this group. /// /// The list containing the . - public override IList GetLeds() + protected override IEnumerable GetLeds() { lock (GroupLeds) return new List(GroupLeds); diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs index 94169b5..5a26b68 100644 --- a/RGB.NET.Core/RGBSurface.cs +++ b/RGB.NET.Core/RGBSurface.cs @@ -14,20 +14,15 @@ namespace RGB.NET.Core /// /// Represents a RGB-surface containing multiple devices. /// - public class RGBSurface : AbstractBindable, IDisposable + public sealed class RGBSurface : AbstractBindable, IDisposable { #region Properties & Fields private Stopwatch _deltaTimeCounter; - private IList _devices = new List(); - private IList _updateTriggers = new List(); - - // ReSharper disable InconsistentNaming - - private readonly LinkedList _ledGroups = new(); - - // ReSharper restore InconsistentNaming + private readonly IList _devices = new List(); + private readonly IList _updateTriggers = new List(); + private readonly List _ledGroups = new List(); /// /// Gets a readonly list containing all loaded . @@ -160,7 +155,7 @@ namespace RGB.NET.Core lock (_ledGroups) { // Render brushes - foreach (ILedGroup ledGroup in _ledGroups.OrderBy(x => x.ZIndex)) + foreach (ILedGroup ledGroup in _ledGroups) try { Render(ledGroup); } catch (Exception ex) { OnException(ex); } } @@ -170,6 +165,9 @@ namespace RGB.NET.Core try { device.Update(flushLeds); } catch (Exception ex) { OnException(ex); } + foreach (Led led in Leds) + led.Update(); + OnUpdated(); } } @@ -204,7 +202,7 @@ namespace RGB.NET.Core /// Thrown if the of the Brush is not valid. private void Render(ILedGroup ledGroup) { - IList leds = ledGroup.GetLeds().ToList(); + IList leds = ledGroup.ToList(); IBrush? brush = ledGroup.Brush; if ((brush == null) || !brush.IsEnabled) return; @@ -234,14 +232,16 @@ namespace RGB.NET.Core /// /// The to attach. /// true if the could be attached; otherwise, false. - public bool AttachLedGroup(ILedGroup ledGroup) + public bool Attach(ILedGroup ledGroup) { lock (_ledGroups) { - if (_ledGroups.Contains(ledGroup)) return false; + if (ledGroup.Surface != null) return false; - _ledGroups.AddLast(ledGroup); - ledGroup.OnAttach(this); + ledGroup.Surface = this; + _ledGroups.Add(ledGroup); + _ledGroups.Sort((group1, group2) => group1.ZIndex.CompareTo(group2.ZIndex)); + ledGroup.OnAttach(); return true; } @@ -252,29 +252,18 @@ namespace RGB.NET.Core /// /// The to detached. /// true if the could be detached; otherwise, false. - public bool DetachLedGroup(ILedGroup ledGroup) + public bool Detach(ILedGroup ledGroup) { lock (_ledGroups) { - LinkedListNode? node = _ledGroups.Find(ledGroup); - if (node == null) return false; - - _ledGroups.Remove(node); - node.Value.OnDetach(this); + if (!_ledGroups.Remove(ledGroup)) return false; + ledGroup.OnDetach(); + ledGroup.Surface = null; return true; } } - public void Attach(IEnumerable devices) - { - lock (_devices) - { - foreach (IRGBDevice device in devices) - Attach(device); - } - } - public void Attach(IRGBDevice device) { lock (_devices) @@ -289,15 +278,6 @@ namespace RGB.NET.Core } } - public void Detach(IEnumerable devices) - { - lock (_devices) - { - foreach (IRGBDevice device in devices) - Detach(device); - } - } - public void Detach(IRGBDevice device) { lock (_devices) @@ -313,19 +293,6 @@ namespace RGB.NET.Core } } - /// - /// Automatically aligns all devices to prevent overlaps. - /// - public void AlignDevices() - { - float posX = 0; - foreach (IRGBDevice device in Devices) - { - device.Location += new Point(posX, 0); - posX += device.ActualSize.Width + 1; - } - } - // ReSharper restore UnusedMember.Global private void DeviceOnBoundaryChanged(object? sender, EventArgs args) @@ -347,29 +314,6 @@ namespace RGB.NET.Core } } - /// - /// Gets all devices of a specific type. - /// - /// The type of devices to get. - /// A list of devices with the specified type. - public IList GetDevices() - where T : class - { - lock (_devices) - return new ReadOnlyCollection(_devices.Where(x => x is T).Cast().ToList()); - } - - /// - /// Gets all devices of the specified . - /// - /// The of the devices to get. - /// a list of devices matching the specified . - public IList GetDevices(RGBDeviceType deviceType) - { - lock (_devices) - return new ReadOnlyCollection(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList()); - } - /// /// Registers the provided . /// diff --git a/RGB.NET.Presets/Groups/RectangleLedGroup.cs b/RGB.NET.Presets/Groups/RectangleLedGroup.cs index b024405..a17ff98 100644 --- a/RGB.NET.Presets/Groups/RectangleLedGroup.cs +++ b/RGB.NET.Presets/Groups/RectangleLedGroup.cs @@ -93,21 +93,18 @@ namespace RGB.NET.Presets.Groups #region Methods /// - public override void OnAttach(RGBSurface surface) + public override void OnAttach() { - base.OnAttach(surface); - - if (Surface != null) - Surface.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; + base.OnAttach(); + Surface!.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; } /// - public override void OnDetach(RGBSurface surface) + public override void OnDetach() { - if (Surface != null) - Surface.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; + Surface!.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; - base.OnDetach(surface); + base.OnDetach(); } private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache(); @@ -117,7 +114,7 @@ namespace RGB.NET.Presets.Groups /// Gets a list containing all of this . /// /// The list containing all of this . - public override IList GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List()); + protected override IEnumerable GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List()); private void InvalidateCache() => _ledCache = null;