diff --git a/RGB.NET.Core/Groups/AbstractLedGroup.cs b/RGB.NET.Core/Groups/AbstractLedGroup.cs index 7007152..eab6803 100644 --- a/RGB.NET.Core/Groups/AbstractLedGroup.cs +++ b/RGB.NET.Core/Groups/AbstractLedGroup.cs @@ -36,7 +36,7 @@ namespace RGB.NET.Core #region Methods /// - public abstract IEnumerable GetLeds(); + public abstract IList GetLeds(); /// public virtual void OnAttach() diff --git a/RGB.NET.Core/Groups/ILedGroup.cs b/RGB.NET.Core/Groups/ILedGroup.cs index 638f146..5db5e63 100644 --- a/RGB.NET.Core/Groups/ILedGroup.cs +++ b/RGB.NET.Core/Groups/ILedGroup.cs @@ -25,7 +25,7 @@ namespace RGB.NET.Core /// Gets a list containing all of this . /// /// The list containing all of this . - IEnumerable GetLeds(); + IList GetLeds(); /// /// Called when the is attached to the . diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs index 9528f78..74bc882 100644 --- a/RGB.NET.Core/RGBSurface.cs +++ b/RGB.NET.Core/RGBSurface.cs @@ -38,7 +38,14 @@ namespace RGB.NET.Core /// /// Gets a readonly list containing all loaded . /// - public IEnumerable Devices => new ReadOnlyCollection(_devices); + public IEnumerable Devices + { + get + { + lock (_devices) + return new ReadOnlyCollection(_devices); + } + } /// /// Gets a readonly list containing all registered . @@ -53,7 +60,14 @@ namespace RGB.NET.Core /// /// Gets a list of all on this . /// - public IEnumerable Leds => _devices.SelectMany(x => x); + public IEnumerable Leds + { + get + { + lock (_devices) + return _devices.SelectMany(x => x); + } + } #endregion @@ -92,32 +106,33 @@ namespace RGB.NET.Core bool updateDevices = customData["updateDevices"] as bool? ?? true; lock (_updateTriggers) - { - OnUpdating(updateTrigger, customData); + lock (_devices) + { + OnUpdating(updateTrigger, customData); - if (syncBack) - foreach (IRGBDevice device in Devices) - if (device.UpdateMode.HasFlag(DeviceUpdateMode.SyncBack) && device.DeviceInfo.SupportsSyncBack) - try { device.SyncBack(); } - catch (Exception ex) { OnException(ex); } + if (syncBack) + foreach (IRGBDevice device in _devices) + if (device.UpdateMode.HasFlag(DeviceUpdateMode.SyncBack) && device.DeviceInfo.SupportsSyncBack) + try { device.SyncBack(); } + catch (Exception ex) { OnException(ex); } - if (render) - lock (_ledGroups) - { - // Render brushes - foreach (ILedGroup ledGroup in _ledGroups.OrderBy(x => x.ZIndex)) - try { Render(ledGroup); } - catch (Exception ex) { OnException(ex); } - } + if (render) + lock (_ledGroups) + { + // Render brushes + foreach (ILedGroup ledGroup in _ledGroups.OrderBy(x => x.ZIndex)) + try { Render(ledGroup); } + catch (Exception ex) { OnException(ex); } + } - if (updateDevices) - foreach (IRGBDevice device in Devices) - if (!device.UpdateMode.HasFlag(DeviceUpdateMode.NoUpdate)) - try { device.Update(flushLeds); } - catch (Exception ex) { OnException(ex); } + if (updateDevices) + foreach (IRGBDevice device in _devices) + if (!device.UpdateMode.HasFlag(DeviceUpdateMode.NoUpdate)) + try { device.Update(flushLeds); } + catch (Exception ex) { OnException(ex); } - OnUpdated(); - } + OnUpdated(); + } } catch (Exception ex) { @@ -128,20 +143,19 @@ namespace RGB.NET.Core /// public void Dispose() { - //if (_updateTokenSource?.IsCancellationRequested == false) - // _updateTokenSource.Cancel(); + lock (_devices) + foreach (IRGBDevice device in _devices) + try { device.Dispose(); } + catch { /* We do what we can */} - foreach (IRGBDevice device in _devices) - try { device.Dispose(); } - catch { /* We do what we can */ } - - foreach (IRGBDeviceProvider deviceProvider in _deviceProvider) - try { deviceProvider.Dispose(); } - catch { /* We do what we can */ } + lock (_deviceProvider) + foreach (IRGBDeviceProvider deviceProvider in _deviceProvider) + try { deviceProvider.Dispose(); } + catch { /* We do what we can */} foreach (IUpdateTrigger updateTrigger in _updateTriggers) try { updateTrigger.Dispose(); } - catch { /* We do what we can */ } + catch { /* We do what we can */} _ledGroups.Clear(); _devices = null; @@ -224,8 +238,11 @@ namespace RGB.NET.Core private void UpdateSurfaceRectangle() { - Rectangle devicesRectangle = new Rectangle(_devices.Select(d => d.DeviceRectangle)); - SurfaceRectangle = SurfaceRectangle.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height)); + lock (_devices) + { + Rectangle devicesRectangle = new Rectangle(_devices.Select(d => d.DeviceRectangle)); + SurfaceRectangle = SurfaceRectangle.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height)); + } } /// @@ -235,7 +252,10 @@ namespace RGB.NET.Core /// A list of devices with the specified type. public IList GetDevices() where T : class - => new ReadOnlyCollection(_devices.Select(x => x as T).Where(x => x != null).ToList()); + { + lock (_devices) + return new ReadOnlyCollection(_devices.Select(x => x as T).Where(x => x != null).ToList()); + } /// /// Gets all devices of the specified . @@ -243,7 +263,10 @@ namespace RGB.NET.Core /// The of the devices to get. /// a list of devices matching the specified . public IList GetDevices(RGBDeviceType deviceType) - => new ReadOnlyCollection(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList()); + { + lock (_devices) + return new ReadOnlyCollection(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList()); + } /// /// Registers the provided . diff --git a/RGB.NET.Core/RGBSurfaceDeviceLoader.cs b/RGB.NET.Core/RGBSurfaceDeviceLoader.cs index f233282..df760c3 100644 --- a/RGB.NET.Core/RGBSurfaceDeviceLoader.cs +++ b/RGB.NET.Core/RGBSurfaceDeviceLoader.cs @@ -29,28 +29,31 @@ namespace RGB.NET.Core /// 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) { - if (_deviceProvider.Contains(deviceProvider) || _deviceProvider.Any(x => x.GetType() == deviceProvider.GetType())) return; - - List addedDevices = new List(); - if (deviceProvider.IsInitialized || deviceProvider.Initialize(loadFilter, exclusiveAccessIfPossible, throwExceptions)) + lock (_deviceProvider) { - _deviceProvider.Add(deviceProvider); + if (_deviceProvider.Contains(deviceProvider) || _deviceProvider.Any(x => x.GetType() == deviceProvider.GetType())) return; - foreach (IRGBDevice device in deviceProvider.Devices) + List addedDevices = new List(); + if (deviceProvider.IsInitialized || deviceProvider.Initialize(loadFilter, exclusiveAccessIfPossible, throwExceptions)) { - if (_devices.Contains(device)) continue; + _deviceProvider.Add(deviceProvider); + lock (_devices) + foreach (IRGBDevice device in deviceProvider.Devices) + { + if (_devices.Contains(device)) continue; - addedDevices.Add(device); + addedDevices.Add(device); - device.PropertyChanged += DeviceOnPropertyChanged; - _devices.Add(device); + device.PropertyChanged += DeviceOnPropertyChanged; + _devices.Add(device); + } } - } - if (addedDevices.Any()) - { - UpdateSurfaceRectangle(); - SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs(addedDevices, true, false)); + if (addedDevices.Any()) + { + UpdateSurfaceRectangle(); + SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs(addedDevices, true, false)); + } } } diff --git a/RGB.NET.Groups/Groups/ListLedGroup.cs b/RGB.NET.Groups/Groups/ListLedGroup.cs index a5fed36..eb833d8 100644 --- a/RGB.NET.Groups/Groups/ListLedGroup.cs +++ b/RGB.NET.Groups/Groups/ListLedGroup.cs @@ -92,9 +92,10 @@ namespace RGB.NET.Groups { if (leds == null) return; - foreach (Led led in leds) - if ((led != null) && !ContainsLed(led)) - GroupLeds.Add(led); + lock (GroupLeds) + foreach (Led led in leds) + if ((led != null) && !ContainsLed(led)) + GroupLeds.Add(led); } /// @@ -111,9 +112,10 @@ namespace RGB.NET.Groups { if (leds == null) return; - foreach (Led led in leds) - if (led != null) - GroupLeds.Remove(led); + lock (GroupLeds) + foreach (Led led in leds) + if (led != null) + GroupLeds.Remove(led); } /// @@ -121,7 +123,11 @@ namespace RGB.NET.Groups /// /// The LED which should be checked. /// true if the LED is contained by this ledgroup; otherwise, false. - public bool ContainsLed(Led led) => (led != null) && GroupLeds.Contains(led); + public bool ContainsLed(Led led) + { + lock (GroupLeds) + return (led != null) && GroupLeds.Contains(led); + } /// /// Merges the from the given ledgroup in this ledgroup. @@ -129,9 +135,10 @@ namespace RGB.NET.Groups /// The ledgroup to merge. public void MergeLeds(ILedGroup groupToMerge) { - foreach (Led led in groupToMerge.GetLeds()) - if (!GroupLeds.Contains(led)) - GroupLeds.Add(led); + lock (GroupLeds) + foreach (Led led in groupToMerge.GetLeds()) + if (!GroupLeds.Contains(led)) + GroupLeds.Add(led); } /// @@ -139,7 +146,11 @@ namespace RGB.NET.Groups /// Gets a list containing the from this group. /// /// The list containing the . - public override IEnumerable GetLeds() => GroupLeds; + public override IList GetLeds() + { + lock (GroupLeds) + return new List(GroupLeds); + } #endregion } diff --git a/RGB.NET.Groups/Groups/RectangleLedGroup.cs b/RGB.NET.Groups/Groups/RectangleLedGroup.cs index 1b23c26..90bb88c 100644 --- a/RGB.NET.Groups/Groups/RectangleLedGroup.cs +++ b/RGB.NET.Groups/Groups/RectangleLedGroup.cs @@ -105,7 +105,7 @@ namespace RGB.NET.Groups /// Gets a list containing all of this . /// /// The list containing all of this . - public override IEnumerable GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList(); + public override IList GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList(); private void InvalidateCache() => _ledCache = null;