diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs index 2ed8377..a737f29 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs @@ -157,8 +157,12 @@ namespace RGB.NET.Core /// public virtual void Dispose() { - SpecialDeviceParts.Clear(); - LedMapping.Clear(); + try + { + SpecialDeviceParts.Clear(); + LedMapping.Clear(); + } + catch { /* this really shouldn't happen */ } } /// diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs index 7ba3183..9528f78 100644 --- a/RGB.NET.Core/RGBSurface.cs +++ b/RGB.NET.Core/RGBSurface.cs @@ -139,6 +139,10 @@ namespace RGB.NET.Core try { deviceProvider.Dispose(); } catch { /* We do what we can */ } + foreach (IUpdateTrigger updateTrigger in _updateTriggers) + try { updateTrigger.Dispose(); } + catch { /* We do what we can */ } + _ledGroups.Clear(); _devices = null; _deviceProvider = null; diff --git a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs index 3ac5d46..e311037 100644 --- a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs +++ b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs @@ -5,7 +5,7 @@ namespace RGB.NET.Core /// /// Represents a generic update trigger. /// - public class AbstractUpdateTrigger : AbstractBindable, IUpdateTrigger + public abstract class AbstractUpdateTrigger : AbstractBindable, IUpdateTrigger { #region Events @@ -31,8 +31,7 @@ namespace RGB.NET.Core protected virtual void OnUpdate(CustomUpdateData updateData = null) => Update?.Invoke(this, updateData); /// - public virtual void Dispose() - { } + public abstract void Dispose(); #endregion } diff --git a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs index 04cfb92..8f4beba 100644 --- a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs +++ b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs @@ -144,6 +144,9 @@ namespace RGB.NET.Core UpdateFrequency = UpdateRateHardLimit; } + /// + public override void Dispose() => Stop(); + #endregion } } diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs index 23eaa96..0171ffb 100644 --- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs +++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs @@ -106,6 +106,9 @@ namespace RGB.NET.Core } } + /// + public override void Dispose() => Stop(); + #endregion } } diff --git a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs index f8e3834..cf19d8c 100644 --- a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs +++ b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs @@ -172,7 +172,12 @@ namespace RGB.NET.Devices.Asus /// public void Dispose() { - _sdk?.ReleaseControl(0); + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + try { _sdk?.ReleaseControl(0); } + catch { /* at least we tried */ } + _sdk = null; } diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs index 0241828..42caff9 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs @@ -80,6 +80,15 @@ namespace RGB.NET.Devices.Asus //} } + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs index 4ca979a..6dbae09 100644 --- a/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs +++ b/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs @@ -228,7 +228,7 @@ namespace RGB.NET.Devices.Asus catch { if (throwExceptions) throw; } #endregion - + UpdateTrigger?.Start(); Devices = new ReadOnlyCollection(devices); @@ -267,7 +267,13 @@ namespace RGB.NET.Devices.Asus /// public void Dispose() - { } + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + try { _AsusSDK.UnloadAsusSDK(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs index 083cafd..011383b 100644 --- a/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs @@ -80,6 +80,9 @@ namespace RGB.NET.Devices.Asus /// public override void Dispose() { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + if ((DeviceInfo is AsusRGBDeviceInfo deviceInfo) && (deviceInfo.Handle != IntPtr.Zero)) Marshal.FreeHGlobal(deviceInfo.Handle); diff --git a/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs b/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs index 830dadd..437a3ea 100644 --- a/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs +++ b/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs @@ -75,7 +75,7 @@ namespace RGB.NET.Devices.Asus.Native //_getDramColorPointer = (GetDramColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDramColor"), typeof(GetDramColorPointer)); } - private static void UnloadAsusSDK() + internal static void UnloadAsusSDK() { if (_dllHandle == IntPtr.Zero) return; diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs index f091ed3..0e4b6c0 100644 --- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs +++ b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs @@ -108,7 +108,7 @@ namespace RGB.NET.Devices.CoolerMaster { RGBDeviceType deviceType = index.GetDeviceType(); if (deviceType == RGBDeviceType.None) continue; - + if (_CoolerMasterSDK.IsDevicePlugged(index)) { if (!loadFilter.HasFlag(deviceType)) continue; @@ -175,6 +175,9 @@ namespace RGB.NET.Devices.CoolerMaster /// public void Dispose() { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + if (IsInitialized) foreach (IRGBDevice device in Devices) { @@ -185,6 +188,9 @@ namespace RGB.NET.Devices.CoolerMaster } catch {/* shit happens */} } + + try { _CoolerMasterSDK.UnloadCMSDK(); } + catch { /* at least we tried */ } } #endregion diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs index c35676e..d33351f 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs @@ -74,6 +74,9 @@ namespace RGB.NET.Devices.CoolerMaster /// public override void Dispose() { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + _CoolerMasterSDK.EnableLedControl(false, DeviceInfo.DeviceIndex); base.Dispose(); diff --git a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs index 00e89c8..ac23587 100644 --- a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs +++ b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs @@ -52,7 +52,7 @@ namespace RGB.NET.Devices.CoolerMaster.Native _setAllLedColorPointer = (SetAllLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetAllLedColor"), typeof(SetAllLedColorPointer)); } - private static void UnloadCMSDK() + internal static void UnloadCMSDK() { if (_dllHandle == IntPtr.Zero) return; diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index d048397..166662d 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -292,7 +292,13 @@ namespace RGB.NET.Devices.Corsair /// public void Dispose() - { } + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + try { _CUESDK.UnloadCUESDK(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs index bb0c479..650a61e 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs @@ -122,6 +122,15 @@ namespace RGB.NET.Devices.Corsair Marshal.FreeHGlobal(ptr); } + /// + public override void Dispose() + { + try { DeviceUpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs index 0e319ff..9b217e4 100644 --- a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs +++ b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs @@ -56,7 +56,7 @@ namespace RGB.NET.Devices.Corsair.Native _corsairGetLastErrorPointer = (CorsairGetLastErrorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLastError"), typeof(CorsairGetLastErrorPointer)); } - private static void UnloadCUESDK() + internal static void UnloadCUESDK() { if (_dllHandle == IntPtr.Zero) return; @@ -136,7 +136,7 @@ namespace RGB.NET.Devices.Corsair.Native #endregion // ReSharper disable EventExceptionNotDocumented - + /// /// CUE-SDK: set specified LEDs to some colors. /// This function set LEDs colors in the buffer which is written to the devices via CorsairSetLedsColorsFlushBuffer or CorsairSetLedsColorsFlushBufferAsync. @@ -151,7 +151,7 @@ namespace RGB.NET.Devices.Corsair.Native /// This function executes synchronously, if you are concerned about delays consider using CorsairSetLedsColorsFlushBufferAsync /// internal static bool CorsairSetLedsColorsFlushBuffer() => _corsairSetLedsColorsFlushBufferPointer(); - + /// /// CUE-SDK: get current color for the list of requested LEDs. /// The color should represent the actual state of the hardware LED, which could be a combination of SDK and/or CUE input. @@ -175,7 +175,7 @@ namespace RGB.NET.Devices.Corsair.Native /// CUE-SDK: returns information about device at provided index. /// internal static IntPtr CorsairGetDeviceInfo(int deviceIndex) => _corsairGetDeviceInfoPointer(deviceIndex); - + /// /// CUE-SDK: provides list of keyboard or mousepad LEDs with their physical positions. /// diff --git a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs index 3e7d889..a151778 100644 --- a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs +++ b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs @@ -116,7 +116,10 @@ namespace RGB.NET.Devices.DMX /// public void Dispose() - { } + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.DMX/E131/E131Device.cs b/RGB.NET.Devices.DMX/E131/E131Device.cs index 871466e..1b199dd 100644 --- a/RGB.NET.Devices.DMX/E131/E131Device.cs +++ b/RGB.NET.Devices.DMX/E131/E131Device.cs @@ -59,6 +59,15 @@ namespace RGB.NET.Devices.DMX.E131 /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + public override void Dispose() + { + try { _updateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs index 02a8373..74104fa 100644 --- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs @@ -70,6 +70,15 @@ namespace RGB.NET.Devices.Logitech ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Logitech", $"{layoutPath}.xml"), layout, true); } + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs index 991fc01..5169eb3 100644 --- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs +++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs @@ -182,7 +182,17 @@ namespace RGB.NET.Devices.Logitech public void ResetDevices() => _LogitechGSDK.LogiLedRestoreLighting(); /// - public void Dispose() => _LogitechGSDK.LogiLedRestoreLighting(); + public void Dispose() + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + try { _LogitechGSDK.LogiLedRestoreLighting(); } + catch { /* at least we tried */ } + + try { _LogitechGSDK.UnloadLogitechGSDK(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs index 39d0968..8f1b826 100644 --- a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs +++ b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs @@ -55,7 +55,7 @@ namespace RGB.NET.Devices.Logitech.Native _logiLedSetLightingForTargetZonePointer = (LogiLedSetLightingForTargetZonePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingForTargetZone"), typeof(LogiLedSetLightingForTargetZonePointer)); } - private static void UnloadLogitechGSDK() + internal static void UnloadLogitechGSDK() { if (_dllHandle == IntPtr.Zero) return; diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index e6a5210..258bf84 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -68,6 +68,15 @@ namespace RGB.NET.Devices.Msi protected override void UpdateLeds(IEnumerable ledsToUpdate) => DeviceUpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int))); + /// + public override void Dispose() + { + try { DeviceUpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index 59a3980..dc46a01 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -163,7 +163,13 @@ namespace RGB.NET.Devices.Msi /// public void Dispose() - { } + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + try { _MsiSDK.UnloadMsiSDK(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs index a67aa94..930352f 100644 --- a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs +++ b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs @@ -60,7 +60,7 @@ namespace RGB.NET.Devices.Msi.Native _getErrorMessagePointer = (GetErrorMessagePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetErrorMessage"), typeof(GetErrorMessagePointer)); } - private static void UnloadMsiSDK() + internal static void UnloadMsiSDK() { if (_dllHandle == IntPtr.Zero) return; diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs index c1904eb..8152ebe 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs @@ -78,8 +78,11 @@ namespace RGB.NET.Devices.Novation /// public override void Dispose() { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + Reset(); - UpdateQueue.Dispose(); + base.Dispose(); } diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs index 5ad614f..b7890e8 100644 --- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs +++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs @@ -122,7 +122,10 @@ namespace RGB.NET.Devices.Novation /// public void Dispose() - { } + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs index 525dd58..e537caf 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs @@ -81,6 +81,15 @@ namespace RGB.NET.Devices.Razer /// public void Reset() => UpdateQueue.Reset(); + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Razer/Native/_RazerSDK.cs b/RGB.NET.Devices.Razer/Native/_RazerSDK.cs index 17742b3..4802196 100644 --- a/RGB.NET.Devices.Razer/Native/_RazerSDK.cs +++ b/RGB.NET.Devices.Razer/Native/_RazerSDK.cs @@ -52,7 +52,7 @@ namespace RGB.NET.Devices.Razer.Native _deleteEffectPointer = (DeleteEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "DeleteEffect"), typeof(DeleteEffectPointer)); } - private static void UnloadRazerSDK() + internal static void UnloadRazerSDK() { if (_dllHandle == IntPtr.Zero) return; diff --git a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs index 5c9f88b..0f711bb 100644 --- a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs +++ b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs @@ -222,7 +222,16 @@ namespace RGB.NET.Devices.Razer } /// - public void Dispose() => TryUnInit(); + public void Dispose() + { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + TryUnInit(); + + try { _RazerSDK.UnloadRazerSDK(); } + catch { /* at least we tried */ } + } #endregion } diff --git a/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs b/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs index aa59118..21e1644 100644 --- a/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs +++ b/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs @@ -27,11 +27,11 @@ namespace RGB.NET.Devices.Roccat.Native /// internal static void Reload() { - UnloadCUESDK(); - LoadCUESDK(); + UnloadRoccatSDK(); + LoadRoccatSDK(); } - private static void LoadCUESDK() + private static void LoadRoccatSDK() { if (_dllHandle != IntPtr.Zero) return; @@ -57,7 +57,7 @@ namespace RGB.NET.Devices.Roccat.Native _setAllLedSfxPointer = (SetAllLedSfxPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "Set_all_LEDSFX"), typeof(SetAllLedSfxPointer)); } - private static void UnloadCUESDK() + internal static void UnloadRoccatSDK() { if (_dllHandle == IntPtr.Zero) return; diff --git a/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs b/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs index 391a0da..4ad9a9e 100644 --- a/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs +++ b/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs @@ -114,6 +114,9 @@ namespace RGB.NET.Devices.Roccat try { _RoccatSDK.UnloadSDK(_sdkHandle); } catch { /* We tried our best */} } + + try { _RoccatSDK.UnloadRoccatSDK(); } + catch { /* at least we tried */ } } #endregion diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs index 5a5285e..ca72447 100644 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs +++ b/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs @@ -66,6 +66,9 @@ namespace RGB.NET.Devices.SoIP.Server /// public override void Dispose() { + try { _updateQueue?.Dispose(); } + catch { /* at least we tried */ } + base.Dispose(); _tcpServer.Stop(); diff --git a/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs b/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs index 9152b9a..9755cc2 100644 --- a/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs +++ b/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs @@ -56,7 +56,7 @@ namespace RGB.NET.Devices.SoIP { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SoIPDeviceProvider)}"); _instance = this; - + UpdateTrigger = new DeviceUpdateTrigger(); } @@ -130,8 +130,8 @@ namespace RGB.NET.Devices.SoIP /// public void Dispose() { - foreach (IRGBDevice device in Devices) - device.Dispose(); + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } } #endregion diff --git a/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs b/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs index be7f5ac..8b3d84d 100644 --- a/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs +++ b/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs @@ -85,7 +85,9 @@ namespace RGB.NET.Devices.SteelSeries.API internal static void Dispose() { - ResetLeds(); + if (IsInitialized) + ResetLeds(); + _client.Dispose(); } diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs index f13d918..78a65eb 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs @@ -83,6 +83,15 @@ namespace RGB.NET.Devices.SteelSeries ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\SteelSeries", $"{layoutPath}.xml"), layout, true); } + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs index 9f59d7d..21402dd 100644 --- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs +++ b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs @@ -117,11 +117,11 @@ namespace RGB.NET.Devices.SteelSeries /// public void Dispose() { - try - { - SteelSeriesSDK.Dispose(); - } - catch {/* shit happens */} + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + + try { SteelSeriesSDK.Dispose(); } + catch { /* shit happens */ } } #endregion diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs index 5fa3c85..f8b9d4f 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs @@ -73,6 +73,15 @@ namespace RGB.NET.Devices.WS281X.Arduino /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs index dc28760..0690926 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs @@ -39,7 +39,7 @@ namespace RGB.NET.Devices.WS281X.Arduino /// /// Initializes a new instance of the class. /// - /// The name of the serial-port to connect to. + /// The name of the serial-port to connect to. public ArduinoWS281XDeviceDefinition(string port) { this.Port = port; @@ -50,10 +50,8 @@ namespace RGB.NET.Devices.WS281X.Arduino #region Methods /// - public IEnumerable CreateDevices() + public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) { - DeviceUpdateTrigger updateTrigger = new DeviceUpdateTrigger(); - ArduinoWS2812USBUpdateQueue queue = new ArduinoWS2812USBUpdateQueue(updateTrigger, Port, BaudRate); IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels(); int counter = 0; @@ -64,8 +62,6 @@ namespace RGB.NET.Devices.WS281X.Arduino device.Initialize(ledCount); yield return device; } - - updateTrigger.Start(); } #endregion diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs index 0e4f7a9..74d52ee 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs @@ -63,6 +63,15 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs index d8bc4f3..b769519 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs @@ -43,7 +43,7 @@ namespace RGB.NET.Devices.WS281X.Bitwizard /// /// Initializes a new instance of the class. /// - /// The name of the serial-port to connect to. + /// The name of the serial-port to connect to. public BitwizardWS281XDeviceDefinition(string port) { this.Port = port; @@ -54,17 +54,13 @@ namespace RGB.NET.Devices.WS281X.Bitwizard #region Methods /// - public IEnumerable CreateDevices() + public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) { - DeviceUpdateTrigger updateTrigger = new DeviceUpdateTrigger(); - BitwizardWS2812USBUpdateQueue queue = new BitwizardWS2812USBUpdateQueue(updateTrigger, Port, BaudRate); string name = Name ?? $"Bitwizard WS2812 USB ({Port})"; BitwizardWS2812USBDevice device = new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue); device.Initialize(StripLength); yield return device; - - updateTrigger.Start(); } #endregion diff --git a/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs index 8ff5fa9..a6f375e 100644 --- a/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs @@ -13,6 +13,6 @@ namespace RGB.NET.Devices.WS281X /// Gets the devices defined by this definition. /// /// The initialized devices defined by this definition. - IEnumerable CreateDevices(); + IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger); } } diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs index 127e54b..89ad1cc 100644 --- a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs +++ b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using RGB.NET.Core; namespace RGB.NET.Devices.WS281X @@ -37,6 +38,11 @@ namespace RGB.NET.Devices.WS281X // ReSharper disable once ReturnTypeCanBeEnumerable.Global public List DeviceDefinitions { get; } = new List(); + /// + /// The used to trigger the updates for corsair devices. + /// + public DeviceUpdateTrigger UpdateTrigger { get; } + #endregion #region Constructors @@ -49,6 +55,8 @@ namespace RGB.NET.Devices.WS281X { if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WS281XDeviceProvider)}"); _instance = this; + + UpdateTrigger = new DeviceUpdateTrigger(); } #endregion @@ -69,17 +77,20 @@ namespace RGB.NET.Devices.WS281X try { + UpdateTrigger?.Stop(); + List devices = new List(); foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions) { try { - devices.AddRange(deviceDefinition.CreateDevices()); + devices.AddRange(deviceDefinition.CreateDevices(UpdateTrigger)); } catch { if (throwExceptions) throw; } } - Devices = devices; + UpdateTrigger?.Start(); + Devices = new ReadOnlyCollection(devices); IsInitialized = true; } catch @@ -99,10 +110,10 @@ namespace RGB.NET.Devices.WS281X /// public void Dispose() { - if (IsInitialized) - foreach (IRGBDevice device in Devices) - if (device is IDisposable disposable) - disposable.Dispose(); + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */} + + DeviceDefinitions.Clear(); } #endregion diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs index 7647a3d..b766da8 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs @@ -63,6 +63,15 @@ namespace RGB.NET.Devices.Wooting.Generic /// protected abstract void InitializeLayout(); + /// + public override void Dispose() + { + try { UpdateQueue?.Dispose(); } + catch { /* at least we tried */ } + + base.Dispose(); + } + #endregion } } diff --git a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs index a9017f3..b90e4f7 100644 --- a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs +++ b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs @@ -52,7 +52,7 @@ namespace RGB.NET.Devices.Wooting.Native _arraySetSinglePointer = (ArraySetSinglePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_array_set_single"), typeof(ArraySetSinglePointer)); } - private static void UnloadWootingSDK() + internal static void UnloadWootingSDK() { if (_dllHandle == IntPtr.Zero) return; @@ -91,13 +91,13 @@ namespace RGB.NET.Devices.Wooting.Native [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate IntPtr GetDeviceInfoPointer(); - + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool KeyboardConnectedPointer(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool ResetPointer(); - + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate bool ArrayUpdateKeyboardPointer(); diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index 5a1113c..638949a 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -28,13 +28,13 @@ namespace RGB.NET.Devices.Wooting /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. /// The first match will be used. /// - public static List PossibleX86NativePaths { get; } = new List {"x86/wooting-rgb-sdk.dll"}; + public static List PossibleX86NativePaths { get; } = new List { "x86/wooting-rgb-sdk.dll" }; /// /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. /// The first match will be used. /// - public static List PossibleX64NativePaths { get; } = new List {"x64/wooting-rgb-sdk64.dll"}; + public static List PossibleX64NativePaths { get; } = new List { "x64/wooting-rgb-sdk64.dll" }; /// /// @@ -143,10 +143,14 @@ namespace RGB.NET.Devices.Wooting /// public void Dispose() { + try { UpdateTrigger?.Dispose(); } + catch { /* at least we tried */ } + try { _WootingSDK.Reset(); } - catch - { /* Unlucky.. */ - } + catch { /* Unlucky.. */ } + + try { _WootingSDK.UnloadWootingSDK(); } + catch { /* at least we tried */ } } #endregion