mirror of
https://github.com/DarthAffe/RGB.NET.git
synced 2025-12-13 10:08:31 +00:00
Merge pull request #116 from DarthAffe/Fix/ThreadSafety
Fix/thread safety
This commit is contained in:
commit
89810e4b1d
@ -36,7 +36,7 @@ namespace RGB.NET.Core
|
||||
#region Methods
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract IEnumerable<Led> GetLeds();
|
||||
public abstract IList<Led> GetLeds();
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual void OnAttach()
|
||||
|
||||
@ -25,7 +25,7 @@ namespace RGB.NET.Core
|
||||
/// Gets a list containing all <see cref="Led"/> of this <see cref="ILedGroup"/>.
|
||||
/// </summary>
|
||||
/// <returns>The list containing all <see cref="Led"/> of this <see cref="ILedGroup"/>.</returns>
|
||||
IEnumerable<Led> GetLeds();
|
||||
IList<Led> GetLeds();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the <see cref="ILedGroup"/> is attached to the <see cref="RGBSurface"/>.
|
||||
|
||||
@ -38,7 +38,14 @@ namespace RGB.NET.Core
|
||||
/// <summary>
|
||||
/// Gets a readonly list containing all loaded <see cref="IRGBDevice"/>.
|
||||
/// </summary>
|
||||
public IEnumerable<IRGBDevice> Devices => new ReadOnlyCollection<IRGBDevice>(_devices);
|
||||
public IEnumerable<IRGBDevice> Devices
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_devices)
|
||||
return new ReadOnlyCollection<IRGBDevice>(_devices);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a readonly list containing all registered <see cref="IUpdateTrigger"/>.
|
||||
@ -53,7 +60,14 @@ namespace RGB.NET.Core
|
||||
/// <summary>
|
||||
/// Gets a list of all <see cref="Led"/> on this <see cref="RGBSurface"/>.
|
||||
/// </summary>
|
||||
public IEnumerable<Led> Leds => _devices.SelectMany(x => x);
|
||||
public IEnumerable<Led> 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
|
||||
/// <inheritdoc />
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -235,7 +252,10 @@ namespace RGB.NET.Core
|
||||
/// <returns>A list of devices with the specified type.</returns>
|
||||
public IList<T> GetDevices<T>()
|
||||
where T : class
|
||||
=> new ReadOnlyCollection<T>(_devices.Select(x => x as T).Where(x => x != null).ToList());
|
||||
{
|
||||
lock (_devices)
|
||||
return new ReadOnlyCollection<T>(_devices.Select(x => x as T).Where(x => x != null).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all devices of the specified <see cref="RGBDeviceType"/>.
|
||||
@ -243,7 +263,10 @@ namespace RGB.NET.Core
|
||||
/// <param name="deviceType">The <see cref="RGBDeviceType"/> of the devices to get.</param>
|
||||
/// <returns>a list of devices matching the specified <see cref="RGBDeviceType"/>.</returns>
|
||||
public IList<IRGBDevice> GetDevices(RGBDeviceType deviceType)
|
||||
=> new ReadOnlyCollection<IRGBDevice>(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList());
|
||||
{
|
||||
lock (_devices)
|
||||
return new ReadOnlyCollection<IRGBDevice>(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the provided <see cref="IUpdateTrigger"/>.
|
||||
|
||||
@ -29,28 +29,31 @@ namespace RGB.NET.Core
|
||||
/// <param name="throwExceptions">Specifies whether exception during the initialization sequence should be thrown or not.</param>
|
||||
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<IRGBDevice> addedDevices = new List<IRGBDevice>();
|
||||
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<IRGBDevice> addedDevices = new List<IRGBDevice>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -121,7 +123,11 @@ namespace RGB.NET.Groups
|
||||
/// </summary>
|
||||
/// <param name="led">The LED which should be checked.</param>
|
||||
/// <returns><c>true</c> if the LED is contained by this ledgroup; otherwise, <c>false</c>.</returns>
|
||||
public bool ContainsLed(Led led) => (led != null) && GroupLeds.Contains(led);
|
||||
public bool ContainsLed(Led led)
|
||||
{
|
||||
lock (GroupLeds)
|
||||
return (led != null) && GroupLeds.Contains(led);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges the <see cref="Led"/> from the given ledgroup in this ledgroup.
|
||||
@ -129,9 +135,10 @@ namespace RGB.NET.Groups
|
||||
/// <param name="groupToMerge">The ledgroup to merge.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@ -139,7 +146,11 @@ namespace RGB.NET.Groups
|
||||
/// Gets a list containing the <see cref="T:RGB.NET.Core.Led" /> from this group.
|
||||
/// </summary>
|
||||
/// <returns>The list containing the <see cref="T:RGB.NET.Core.Led" />.</returns>
|
||||
public override IEnumerable<Led> GetLeds() => GroupLeds;
|
||||
public override IList<Led> GetLeds()
|
||||
{
|
||||
lock (GroupLeds)
|
||||
return new List<Led>(GroupLeds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ namespace RGB.NET.Groups
|
||||
/// Gets a list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Groups.RectangleLedGroup" />.
|
||||
/// </summary>
|
||||
/// <returns>The list containing all <see cref="T:RGB.NET.Core.Led" /> of this <see cref="T:RGB.NET.Groups.RectangleLedGroup" />.</returns>
|
||||
public override IEnumerable<Led> GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList();
|
||||
public override IList<Led> GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList();
|
||||
|
||||
private void InvalidateCache() => _ledCache = null;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user