using OpenRGB.NET;
using OpenRGB.NET.Models;
using RGB.NET.Core;
using RGB.NET.Devices.OpenRGB.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
namespace RGB.NET.Devices.OpenRGB;
///
///
/// Represents a device provider responsible for OpenRGB devices.
///
public class OpenRGBDeviceProvider : AbstractRGBDeviceProvider
{
#region Properties & Fields
private readonly List _clients = new List();
private static OpenRGBDeviceProvider? _instance;
///
/// Gets the singleton instance.
///
public static OpenRGBDeviceProvider Instance => _instance ?? new OpenRGBDeviceProvider();
///
/// Gets a list of all defined device-definitions.
///
public List DeviceDefinitions { get; } = new List();
///
/// Indicates whether all devices will be added, or just the ones with a 'Direct' mode. Defaults to false.
///
public bool ForceAddAllDevices { get; set; } = false;
///
/// Defines which device types will be separated by zones. Defaults to | .
///
public RGBDeviceType PerZoneDeviceFlag { get; } = RGBDeviceType.LedStripe | RGBDeviceType.Mainboard;
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
/// Thrown if this constructor is called even if there is already an instance of this class.
public OpenRGBDeviceProvider()
{
if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(OpenRGBDeviceProvider)}");
_instance = this;
}
#endregion
#region Methods
///
protected override void InitializeSDK()
{
foreach (OpenRGBServerDefinition? deviceDefinition in DeviceDefinitions)
{
try
{
OpenRGBClient? openRgb = new OpenRGBClient(ip: deviceDefinition.Ip, port: deviceDefinition.Port, name: deviceDefinition.ClientName, autoconnect: true);
_clients.Add(openRgb);
deviceDefinition.Connected = true;
}
catch (Exception e)
{
deviceDefinition.Connected = false;
deviceDefinition.LastError = e.Message;
Throw(e, false);
}
}
}
///
protected override IEnumerable LoadDevices()
{
foreach (OpenRGBClient? openRgb in _clients)
{
int deviceCount = openRgb.GetControllerCount();
for (int i = 0; i < deviceCount; i++)
{
Device? device = openRgb.GetControllerData(i);
int directModeIndex = Array.FindIndex(device.Modes, device => device.Name == "Direct");
if (directModeIndex != -1)
{
//set the device to direct mode if it has it
openRgb.SetMode(i, directModeIndex);
}
else if (!ForceAddAllDevices)
{
//if direct mode does not exist
//and if we're not forcing, continue to the next device.
continue;
}
OpenRGBUpdateQueue? updateQueue = new OpenRGBUpdateQueue(GetUpdateTrigger(), i, openRgb, device);
if (PerZoneDeviceFlag.HasFlag(Helper.GetRgbNetDeviceType(device.Type)))
{
int totalLedCount = 0;
for (int zoneIndex = 0; zoneIndex < device.Zones.Length; zoneIndex++)
{
Zone zone = device.Zones[zoneIndex];
if (zone.LedCount == 0)
continue;
yield return new OpenRGBZoneDevice(new OpenRGBDeviceInfo(device), totalLedCount, zone, updateQueue);
totalLedCount += (int)zone.LedCount;
}
}
else
{
yield return new OpenRGBGenericDevice(new OpenRGBDeviceInfo(device), updateQueue);
}
}
}
}
///
public override void Dispose()
{
base.Dispose();
foreach (OpenRGBClient? client in _clients)
{
try { client?.Dispose(); }
catch { /* at least we tried */ }
}
_clients.Clear();
DeviceDefinitions.Clear();
Devices = Enumerable.Empty();
}
#endregion
}