diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs index d61fcbb..e76554e 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs @@ -20,8 +20,13 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider /// public bool ThrowsExceptions { get; protected set; } + /// + /// The list of devices managed by this device-provider. + /// + protected List InternalDevices { get; } = new(); + /// - public virtual IEnumerable Devices { get; protected set; } = Enumerable.Empty(); + public virtual IReadOnlyList Devices => new ReadOnlyCollection(InternalDevices); /// /// Gets the dictionary containing the registered update triggers. @@ -39,6 +44,9 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider /// public event EventHandler? Exception; + /// + public event EventHandler? DevicesChanged; + #endregion #region Constructors @@ -67,7 +75,8 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider InitializeSDK(); - Devices = new ReadOnlyCollection(GetLoadedDevices(loadFilter).ToList()); + foreach (IRGBDevice device in GetLoadedDevices(loadFilter)) + AddDevice(device); foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggerMapping.Values) updateTrigger.Start(); @@ -168,11 +177,43 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider foreach (IRGBDevice device in Devices) device.Dispose(); - Devices = Enumerable.Empty(); + List devices = new(InternalDevices); + foreach (IRGBDevice device in devices) + RemoveDevice(device); + UpdateTriggerMapping.Clear(); IsInitialized = false; } + /// + /// Adds the provided device to the list of managed devices. + /// + /// The device to add. + /// true if the device was added successfully; otherwise false. + protected virtual bool AddDevice(IRGBDevice device) + { + if (InternalDevices.Contains(device)) return false; + + InternalDevices.Add(device); + try { OnDevicesChanged(DevicesChangedEventArgs.CreateDevicesAddedArgs(device)); } catch { /* we don't want to throw due to bad event handlers */ } + + return true; + } + + /// + /// Removes the provided device from the list of managed devices. + /// + /// The device to remove. + /// true if the device was removed successfully; otherwise false. + protected virtual bool RemoveDevice(IRGBDevice device) + { + if (!InternalDevices.Remove(device)) return false; + + try { OnDevicesChanged(DevicesChangedEventArgs.CreateDevicesRemovedArgs(device)); } catch { /* we don't want to throw due to bad event handlers */ } + + return true; + } + /// /// Triggers the -event and throws the specified exception if is true and it is not overriden in the event. /// @@ -188,11 +229,17 @@ public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider } /// - /// Throws the event. + /// Throws the .event. /// /// The parameters passed to the event. protected virtual void OnException(ExceptionEventArgs args) => Exception?.Invoke(this, args); + /// + /// Throws the -event. + /// + /// The parameters passed to the event. + protected virtual void OnDevicesChanged(DevicesChangedEventArgs args) => DevicesChanged?.Invoke(this, args); + /// public virtual void Dispose() { diff --git a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs index 86f41e1..6e22d12 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs @@ -29,7 +29,7 @@ public interface IRGBDeviceProvider : IDisposable /// /// Gets a collection of loaded by this . /// - IEnumerable Devices { get; } + IReadOnlyList Devices { get; } /// /// Gets a collection registered to this device provider. @@ -45,6 +45,11 @@ public interface IRGBDeviceProvider : IDisposable /// event EventHandler? Exception; + /// + /// Occures when the devices provided by this device provider changed. + /// + event EventHandler? DevicesChanged; + #endregion #region Methods diff --git a/RGB.NET.Core/Events/DevicesChangedEventArgs.cs b/RGB.NET.Core/Events/DevicesChangedEventArgs.cs new file mode 100644 index 0000000..5b5012d --- /dev/null +++ b/RGB.NET.Core/Events/DevicesChangedEventArgs.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +namespace RGB.NET.Core; + +public sealed class DevicesChangedEventArgs : EventArgs +{ + #region Properties & Fields + + public IList Added { get; } + public IList Removed { get; } + + #endregion + + #region Constructors + + private DevicesChangedEventArgs(IList added, IList removed) + { + this.Added = added; + this.Removed = removed; + } + + #endregion + + #region Methods + + public static DevicesChangedEventArgs CreateDevicesAddedArgs(params IRGBDevice[] addedDevices) => CreateDevicesAddedArgs((IEnumerable)addedDevices); + public static DevicesChangedEventArgs CreateDevicesAddedArgs(IEnumerable addedDevices) => new(new List(addedDevices), new List()); + + public static DevicesChangedEventArgs CreateDevicesRemovedArgs(params IRGBDevice[] removedDevices) => CreateDevicesRemovedArgs((IEnumerable)removedDevices); + public static DevicesChangedEventArgs CreateDevicesRemovedArgs(IEnumerable removedDevices) => new(new List(), new List(removedDevices)); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs b/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs index 6c83a68..4d19484 100644 --- a/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs +++ b/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs @@ -161,7 +161,7 @@ public sealed class OpenRGBDeviceProvider : AbstractRGBDeviceProvider _clients.Clear(); DeviceDefinitions.Clear(); - Devices = Enumerable.Empty(); } + #endregion }