Split out detection system from ResourceManager into DetectionManager

* Split detection system out into its own class, DetectionManager
    * Clean up ResourceManger's many callbacks into just two, one for detection and one general purpose
This commit is contained in:
Adam Honse
2026-01-08 23:35:50 -06:00
parent 58582202cf
commit ad364871c6
224 changed files with 3161 additions and 2788 deletions

View File

@@ -20,7 +20,7 @@
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
#include "SPDWrapper.h"
#include "DetectionManager.h"
#include "hidapi_wrapper.h"
#include "i2c_smbus.h"
#include "ResourceManagerInterface.h"
@@ -28,11 +28,6 @@
using json = nlohmann::json;
#define HID_INTERFACE_ANY -1
#define HID_USAGE_ANY -1
#define HID_USAGE_PAGE_ANY -1
struct hid_device_info;
class NetworkClient;
class NetworkServer;
class PluginManagerInterface;
@@ -40,187 +35,75 @@ class ProfileManager;
class RGBController;
class SettingsManager;
typedef std::function<bool()> I2CBusDetectorFunction;
typedef std::function<void()> DeviceDetectorFunction;
typedef std::function<void(std::vector<i2c_smbus_interface*>&)> I2CDeviceDetectorFunction;
typedef std::function<void(i2c_smbus_interface*, std::vector<SPDWrapper*>&, const std::string&)> I2CDIMMDeviceDetectorFunction;
typedef std::function<void(i2c_smbus_interface*, uint8_t, const std::string&)> I2CPCIDeviceDetectorFunction;
typedef std::function<void(hid_device_info*, const std::string&)> HIDDeviceDetectorFunction;
typedef std::function<void(hidapi_wrapper wrapper, hid_device_info*, const std::string&)> HIDWrappedDeviceDetectorFunction;
typedef std::function<void()> DynamicDetectorFunction;
typedef std::function<void()> PreDetectionHookFunction;
class BasicHIDBlock
{
public:
std::string name;
uint16_t vid;
uint16_t pid;
int interface;
int usage_page;
int usage;
bool compare(hid_device_info* info);
};
class HIDDeviceDetectorBlock : public BasicHIDBlock
{
public:
HIDDeviceDetectorFunction function;
};
class HIDWrappedDeviceDetectorBlock : public BasicHIDBlock
{
public:
HIDWrappedDeviceDetectorFunction function;
};
typedef struct
{
std::string name;
I2CPCIDeviceDetectorFunction function;
uint16_t ven_id;
uint16_t dev_id;
uint16_t subven_id;
uint16_t subdev_id;
uint8_t i2c_addr;
} I2CPCIDeviceDetectorBlock;
typedef struct
{
std::string name;
I2CDIMMDeviceDetectorFunction function;
uint16_t jedec_id;
uint8_t dimm_type;
} I2CDIMMDeviceDetectorBlock;
/*---------------------------------------------------------*\
| Define a macro for QT lupdate to parse |
\*---------------------------------------------------------*/
#define QT_TRANSLATE_NOOP(scope, x) x
extern const char* I2C_ERR_WIN;
extern const char* I2C_ERR_LINUX;
extern const char* UDEV_MISSING;
extern const char* UDEV_MULTI;
class ResourceManager: public ResourceManagerInterface
{
public:
static ResourceManager *get();
ResourceManager();
~ResourceManager();
void RegisterI2CBus(i2c_smbus_interface *);
std::vector<i2c_smbus_interface*> & GetI2CBusses();
void RegisterRGBController(RGBController *rgb_controller);
void UnregisterRGBController(RGBController *rgb_controller);
std::vector<RGBController*> & GetRGBControllers();
void RegisterI2CBusDetector (I2CBusDetectorFunction detector);
void RegisterDeviceDetector (std::string name, DeviceDetectorFunction detector);
void RegisterI2CDeviceDetector (std::string name, I2CDeviceDetectorFunction detector);
void RegisterI2CDIMMDeviceDetector (std::string name, I2CDIMMDeviceDetectorFunction detector, uint16_t jedec_id, uint8_t dimm_type);
void RegisterI2CPCIDeviceDetector (std::string name, I2CPCIDeviceDetectorFunction detector, uint16_t ven_id, uint16_t dev_id, uint16_t subven_id, uint16_t subdev_id, uint8_t i2c_addr);
void RegisterHIDDeviceDetector (std::string name,
HIDDeviceDetectorFunction detector,
uint16_t vid,
uint16_t pid,
int interface = HID_INTERFACE_ANY,
int usage_page = HID_USAGE_PAGE_ANY,
int usage = HID_USAGE_ANY);
void RegisterHIDWrappedDeviceDetector (std::string name,
HIDWrappedDeviceDetectorFunction detector,
uint16_t vid,
uint16_t pid,
int interface = HID_INTERFACE_ANY,
int usage_page = HID_USAGE_PAGE_ANY,
int usage = HID_USAGE_ANY);
void RegisterDynamicDetector (std::string name, DynamicDetectorFunction detector);
void RegisterPreDetectionHook (PreDetectionHookFunction hook);
void RegisterClientInfoChangeCallback(ClientInfoChangeCallback new_callback, void * new_callback_arg);
void RegisterDeviceListChangeCallback(DeviceListChangeCallback new_callback, void * new_callback_arg);
void RegisterDetectionProgressCallback(DetectionProgressCallback new_callback, void * new_callback_arg);
void RegisterDetectionStartCallback(DetectionStartCallback new_callback, void * new_callback_arg);
void RegisterDetectionEndCallback(DetectionEndCallback new_callback, void * new_callback_arg);
void RegisterI2CBusListChangeCallback(I2CBusListChangeCallback new_callback, void * new_callback_arg);
void UnregisterClientInfoChangeCallback(ClientInfoChangeCallback new_callback, void * new_callback_arg);
void UnregisterDeviceListChangeCallback(DeviceListChangeCallback callback, void * callback_arg);
void UnregisterDetectionProgressCallback(DetectionProgressCallback callback, void *callback_arg);
void UnregisterDetectionStartCallback(DetectionStartCallback callback, void *callback_arg);
void UnregisterDetectionEndCallback(DetectionEndCallback callback, void *callback_arg);
void UnregisterI2CBusListChangeCallback(I2CBusListChangeCallback callback, void * callback_arg);
bool GetDetectionEnabled();
unsigned int GetDetectionPercent();
const char* GetDetectionString();
filesystem::path GetConfigurationDirectory();
void RegisterNetworkClient(NetworkClient* new_client);
void UnregisterNetworkClient(NetworkClient* network_client);
std::vector<NetworkClient*>& GetClients();
NetworkServer* GetServer();
PluginManagerInterface* GetPluginManager();
ProfileManager* GetProfileManager();
SettingsManager* GetSettingsManager();
void SetConfigurationDirectory(const filesystem::path &directory);
void ProcessPreDetectionHooks(); // Consider making private
void ProcessDynamicDetectors(); // Consider making private
void UpdateDeviceList();
void ClientInfoChanged();
void DeviceListChanged();
void DetectionProgressChanged();
void I2CBusListChanged();
void Initialize(bool tryConnect, bool detectDevices, bool startServer, bool applyPostOptions);
void Cleanup();
void DetectDevices();
void DisableDetection();
void RescanDevices();
void SetPluginManager(PluginManagerInterface* plugin_manager_ptr);
void StopDeviceDetection();
void WaitForInitialization();
void WaitForDeviceDetection();
bool IsLocalClient();
NetworkClient* GetLocalClient();
unsigned int GetLocalClientProtocolVersion();
private:
void UpdateDetectorSettings();
void SetupConfigurationDirectory();
bool AttemptLocalConnection();
bool ProcessPreDetection();
void ProcessPostDetection();
bool IsAnyDimmDetectorEnabled(json &detector_settings);
void RunInBackgroundThread(std::function<void()>);
void BackgroundThreadFunction();
/*-----------------------------------------------------*\
| ResourceManager Global Instance Accessor |
\*-----------------------------------------------------*/
static ResourceManager* get();
/*-----------------------------------------------------*\
| Functions that must be run in the background thread |
| These are not related to STL coroutines, yet this |
| name is the most convenient |
| Resource Accessors |
\*-----------------------------------------------------*/
void InitCoroutine();
void DetectDevicesCoroutine();
void HidExitCoroutine();
std::vector<NetworkClient*>& GetClients();
filesystem::path GetConfigurationDirectory();
std::vector<i2c_smbus_interface*>& GetI2CBusses();
PluginManagerInterface* GetPluginManager();
ProfileManager* GetProfileManager();
std::vector<RGBController*>& GetRGBControllers();
NetworkServer* GetServer();
SettingsManager* GetSettingsManager();
void SetConfigurationDirectory(const filesystem::path &directory);
void SetPluginManager(PluginManagerInterface* plugin_manager_ptr);
/*-----------------------------------------------------*\
| Network Client Registration |
\*-----------------------------------------------------*/
void RegisterNetworkClient(NetworkClient* new_client);
void UnregisterNetworkClient(NetworkClient* network_client);
/*-----------------------------------------------------*\
| Local Client Accessors |
\*-----------------------------------------------------*/
NetworkClient* GetLocalClient();
unsigned int GetLocalClientProtocolVersion();
bool IsLocalClient();
/*-----------------------------------------------------*\
| Callback Registration Functions |
\*-----------------------------------------------------*/
void RegisterResourceManagerCallback(ResourceManagerCallback new_callback, void * new_callback_arg);
void UnregisterResourceManagerCallback(ResourceManagerCallback new_callback, void * new_callback_arg);
/*-----------------------------------------------------*\
| Functions to manage detection |
\*-----------------------------------------------------*/
bool GetDetectionEnabled();
unsigned int GetDetectionPercent();
std::string GetDetectionString();
void StopDeviceDetection();
void RescanDevices();
void ClearLocalDevices();
void UpdateDeviceList();
void WaitForDetection();
/*-----------------------------------------------------*\
| Functions to signal update callbacks |
\*-----------------------------------------------------*/
void SignalResourceManagerUpdate(unsigned int update_reason);
void Initialize(bool tryConnect, bool detectDevices, bool startServer, bool applyPostOptions);
void WaitForInitialization();
private:
bool AttemptLocalConnection();
void SetupConfigurationDirectory();
/*-----------------------------------------------------*\
| Static pointer to shared instance of ResourceManager |
@@ -262,11 +145,6 @@ private:
\*-----------------------------------------------------*/
std::atomic<bool> init_finished;
/*-----------------------------------------------------*\
| Initial detection flag |
\*-----------------------------------------------------*/
bool initial_detection;
/*-----------------------------------------------------*\
| Plugin Manager |
\*-----------------------------------------------------*/
@@ -282,16 +160,9 @@ private:
\*-----------------------------------------------------*/
SettingsManager* settings_manager;
/*-----------------------------------------------------*\
| I2C/SMBus Interfaces |
\*-----------------------------------------------------*/
std::vector<i2c_smbus_interface*> busses;
/*-----------------------------------------------------*\
| RGBControllers |
\*-----------------------------------------------------*/
std::vector<RGBController*> rgb_controllers_sizes;
std::vector<RGBController*> rgb_controllers_hw;
std::vector<RGBController*> rgb_controllers;
/*-----------------------------------------------------*\
@@ -305,75 +176,16 @@ private:
std::vector<NetworkClient*> clients;
/*-----------------------------------------------------*\
| Detectors |
\*-----------------------------------------------------*/
std::vector<DeviceDetectorFunction> device_detectors;
std::vector<std::string> device_detector_strings;
std::vector<I2CBusDetectorFunction> i2c_bus_detectors;
std::vector<I2CDeviceDetectorFunction> i2c_device_detectors;
std::vector<std::string> i2c_device_detector_strings;
std::vector<I2CDIMMDeviceDetectorBlock> i2c_dimm_device_detectors;
std::vector<I2CPCIDeviceDetectorBlock> i2c_pci_device_detectors;
std::vector<HIDDeviceDetectorBlock> hid_device_detectors;
std::vector<HIDWrappedDeviceDetectorBlock> hid_wrapped_device_detectors;
std::vector<DynamicDetectorFunction> dynamic_detectors;
std::vector<std::string> dynamic_detector_strings;
std::vector<PreDetectionHookFunction> pre_detection_hooks;
bool dynamic_detectors_processed;
/*-----------------------------------------------------*\
| Detection Thread and Detection State |
\*-----------------------------------------------------*/
std::thread * DetectDevicesThread;
std::mutex DetectDeviceMutex;
std::function<void()> ScheduledBackgroundFunction;
std::mutex BackgroundThreadStateMutex;
/*-----------------------------------------------------*\
| NOTE: wakes up the background detection thread |
\*-----------------------------------------------------*/
std::condition_variable BackgroundFunctionStartTrigger;
std::atomic<bool> background_thread_running;
std::atomic<bool> detection_is_required;
std::atomic<unsigned int> detection_percent;
std::atomic<unsigned int> detection_prev_size;
std::vector<bool> detection_size_entry_used;
const char* detection_string;
/*-----------------------------------------------------*\
| Client Info Changed Callback |
\*-----------------------------------------------------*/
std::vector<ClientInfoChangeCallback> ClientInfoChangeCallbacks;
std::vector<void *> ClientInfoChangeCallbackArgs;
/*-----------------------------------------------------*\
| Device List Changed Callback |
| Device List Mutex |
\*-----------------------------------------------------*/
std::mutex DeviceListChangeMutex;
std::vector<DeviceListChangeCallback> DeviceListChangeCallbacks;
std::vector<void *> DeviceListChangeCallbackArgs;
/*-----------------------------------------------------*\
| Detection Progress, Start, and End Callbacks |
| ResourceManager Callbacks |
\*-----------------------------------------------------*/
std::mutex DetectionProgressMutex;
std::vector<DetectionProgressCallback> DetectionProgressCallbacks;
std::vector<void *> DetectionProgressCallbackArgs;
std::vector<DetectionStartCallback> DetectionStartCallbacks;
std::vector<void *> DetectionStartCallbackArgs;
std::vector<DetectionEndCallback> DetectionEndCallbacks;
std::vector<void *> DetectionEndCallbackArgs;
/*-----------------------------------------------------*\
| I2C/SMBus Adapter List Changed Callback |
\*-----------------------------------------------------*/
std::mutex I2CBusListChangeMutex;
std::vector<I2CBusListChangeCallback> I2CBusListChangeCallbacks;
std::vector<void *> I2CBusListChangeCallbackArgs;
std::vector<ResourceManagerCallback> ResourceManagerCallbacks;
std::vector<void *> ResourceManagerCallbackArgs;
std::mutex ResourceManagerCallbackMutex;
/*-----------------------------------------------------*\
| OpenRGB configuration directory path |