Loading optimization (no GUI changes)

This commit is contained in:
Dmitry K
2024-09-26 22:20:48 +00:00
committed by Adam Honse
parent 7e96e0efa5
commit 2c952a54d2
7 changed files with 277 additions and 182 deletions

View File

@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <string>
#include <hidapi.h>
#include "cli.h"
#include "ResourceManager.h"
#include "ProfileManager.h"
#include "LogManager.h"
@@ -82,6 +83,7 @@ ResourceManager::ResourceManager()
detection_percent = 100;
detection_string = "";
detection_is_required = false;
InitThread = nullptr;
DetectDevicesThread = nullptr;
dynamic_detectors_processed = false;
@@ -168,6 +170,13 @@ ResourceManager::ResourceManager()
ResourceManager::~ResourceManager()
{
Cleanup();
if(InitThread)
{
DetectDevicesThread->join();
delete DetectDevicesThread;
DetectDevicesThread = nullptr;
}
}
void ResourceManager::RegisterI2CBus(i2c_smbus_interface *bus)
@@ -642,6 +651,76 @@ void ResourceManager::UnregisterNetworkClient(NetworkClient* network_client)
UpdateDeviceList();
}
/******************************************************************************************\
* *
* AttemptLocalConnection *
* *
* Attempts an SDK connection to the local server. Returns true if success *
* *
\******************************************************************************************/
bool ResourceManager::AttemptLocalConnection()
{
detection_percent = 0;
detection_string = "Attempting local server connection...";
DetectionProgressChanged();
LOG_DEBUG("[ResourceManager] Attempting server connection...");
bool success = false;
NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers());
std::string titleString = "OpenRGB ";
titleString.append(VERSION_STRING);
client->SetName(titleString.c_str());
client->StartClient();
for(int timeout = 0; timeout < 10; timeout++)
{
if(client->GetConnected())
{
break;
}
std::this_thread::sleep_for(5ms);
}
if(!client->GetConnected())
{
LOG_TRACE("[main] Client failed to connect");
client->StopClient();
LOG_TRACE("[main] Client stopped");
delete client;
client = NULL;
}
else
{
ResourceManager::get()->RegisterNetworkClient(client);
LOG_TRACE("[main] Registered network client");
success = true;
/*-----------------------------------------------------*\
| Wait up to 5 seconds for the client connection to |
| retrieve all controllers |
\*-----------------------------------------------------*/
for(int timeout = 0; timeout < 1000; timeout++)
{
if(client->GetOnline())
{
break;
}
std::this_thread::sleep_for(5ms);
}
}
return success;
}
std::vector<NetworkClient*>& ResourceManager::GetClients()
{
return(clients);
@@ -744,7 +823,12 @@ void ResourceManager::ProcessDynamicDetectors()
dynamic_detectors_processed = true;
}
void ResourceManager::DetectDevices()
/*-----------------------------------------------------*\
| Handle ALL pre-detection routines |
| The system should be ready to start a detection thread|
| (returns false if detection can not proceed) |
\*-----------------------------------------------------*/
bool ResourceManager::ProcessPreDetection()
{
/*-----------------------------------------------------*\
| Process pre-detection hooks |
@@ -773,7 +857,6 @@ void ResourceManager::DetectDevices()
| Update the detector settings |
\*-----------------------------------------------------*/
UpdateDetectorSettings();
if(detection_enabled)
{
/*-------------------------------------------------*\
@@ -781,7 +864,7 @@ void ResourceManager::DetectDevices()
\*-------------------------------------------------*/
if(detection_is_required.load())
{
return;
return false;
}
/*-------------------------------------------------*\
@@ -808,6 +891,16 @@ void ResourceManager::DetectDevices()
| Start the device detection thread |
\*-------------------------------------------------*/
detection_is_required = true;
return true;
}
return false;
}
void ResourceManager::DetectDevices()
{
if(ProcessPreDetection())
{
DetectDevicesThread = new std::thread(&ResourceManager::DetectDevicesThreadFunction, this);
/*-------------------------------------------------*\
@@ -816,24 +909,37 @@ void ResourceManager::DetectDevices()
\*-------------------------------------------------*/
std::this_thread::sleep_for(1ms);
}
else
{
/*-------------------------------------------------*\
| Signal that detection is complete |
\*-------------------------------------------------*/
detection_percent = 100;
DetectionProgressChanged();
/*-----------------------------------------------------*\
| Call detection end callbacks |
\*-----------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < DetectionEndCallbacks.size(); callback_idx++)
{
DetectionEndCallbacks[callback_idx](DetectionEndCallbackArgs[callback_idx]);
}
if(!detection_enabled)
{
ProcessPostDetection();
}
}
void ResourceManager::ProcessPostDetection()
{
/*-------------------------------------------------*\
| Signal that detection is complete |
\*-------------------------------------------------*/
detection_percent = 100;
DetectionProgressChanged();
LOG_INFO("[ResourceManager] Calling Post-detection callbacks");
/*-----------------------------------------------------*\
| Call detection end callbacks |
\*-----------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < DetectionEndCallbacks.size(); callback_idx++)
{
DetectionEndCallbacks[callback_idx](DetectionEndCallbackArgs[callback_idx]);
}
detection_is_required = false;
LOG_INFO("------------------------------------------------------");
LOG_INFO("| Detection completed |");
LOG_INFO("------------------------------------------------------");
}
void ResourceManager::DisableDetection()
{
detection_enabled = false;
@@ -1379,26 +1485,10 @@ void ResourceManager::DetectDevicesThreadFunction()
| Make sure that when the detection is done, |
| progress bar is set to 100% |
\*-------------------------------------------------*/
detection_is_required = false;
detection_percent = 100;
detection_string = "";
DetectionProgressChanged();
ProcessPostDetection();
DetectDeviceMutex.unlock();
/*-----------------------------------------------------*\
| Call detection end callbacks |
\*-----------------------------------------------------*/
for(unsigned int callback_idx = 0; callback_idx < DetectionEndCallbacks.size(); callback_idx++)
{
DetectionEndCallbacks[callback_idx](DetectionEndCallbackArgs[callback_idx]);
}
LOG_INFO("------------------------------------------------------");
LOG_INFO("| Detection completed |");
LOG_INFO("------------------------------------------------------");
#ifdef __linux__
/*-------------------------------------------------*\
| If the udev rules file is not installed, show a |
@@ -1471,6 +1561,79 @@ void ResourceManager::StopDeviceDetection()
detection_string = "Stopping";
}
void ResourceManager::Initialize(bool tryConnect, bool detectDevices, bool startServer, bool applyPostOptions)
{
// Cache the parameters
// TODO: Possibly cache them in the CLI file somewhere
tryAutoConnect = tryConnect;
detection_enabled = detectDevices;
start_server = startServer;
apply_post_options = applyPostOptions;
InitThread = new std::thread(&ResourceManager::InitThreadFunction, this);
}
void ResourceManager::InitThreadFunction()
{
if(tryAutoConnect)
{
detection_percent = 0;
detection_string = "Attempting server connection...";
DetectionProgressChanged();
// Disable detection if a local server was found
if(AttemptLocalConnection())
{
DisableDetection();
}
else
{
LOG_DEBUG("[ResourceManager] Local OpenRGB server connected, running in client mode");
}
tryAutoConnect = false;
}
/*---------------------------------------------------------*\
| Perform actual detection |
| Done in the same thread (InitThread), as we need to wait |
| for completion anyway |
\*---------------------------------------------------------*/
if(detection_enabled)
{
LOG_DEBUG("[ResourceManager] Running standalone");
if(ProcessPreDetection())
{
DetectDevicesThreadFunction();
}
}
else
{
ProcessPostDetection();
}
if(start_server)
{
detection_percent = 100;
detection_string = "Starting server";
DetectionProgressChanged();
GetServer()->StartServer();
if(!GetServer()->GetOnline())
{
LOG_DEBUG("[ResourceManager] Server failed to start");
}
}
/*---------------------------------------------------------*\
| Process command line arguments after detection only if the|
| pre-detection parsing indicated it should be run |
\*---------------------------------------------------------*/
if(apply_post_options)
{
cli_post_detection();
}
}
void ResourceManager::UpdateDetectorSettings()
{
json detector_settings;

View File

@@ -191,13 +191,15 @@ public:
void SetConfigurationDirectory(const filesystem::path &directory);
void ProcessPreDetectionHooks();
void ProcessDynamicDetectors();
void ProcessPreDetectionHooks(); // Consider making private
void ProcessDynamicDetectors(); // Consider making private
void UpdateDeviceList();
void DeviceListChanged();
void DetectionProgressChanged();
void I2CBusListChanged();
void Initialize(bool tryConnect, bool detectDevices, bool startServer, bool applyPostOptions);
void Cleanup();
void DetectDevices();
@@ -212,17 +214,36 @@ private:
void DetectDevicesThreadFunction();
void UpdateDetectorSettings();
void SetupConfigurationDirectory();
bool AttemptLocalConnection();
void InitThreadFunction();
bool ProcessPreDetection();
void ProcessPostDetection();
/*-------------------------------------------------------------------------------------*\
| Static pointer to shared instance of ResourceManager |
\*-------------------------------------------------------------------------------------*/
static ResourceManager* instance;
/*-------------------------------------------------------------------------------------*\
| Auto connection permitting flag |
\*-------------------------------------------------------------------------------------*/
bool tryAutoConnect;
/*-------------------------------------------------------------------------------------*\
| Detection enabled flag |
\*-------------------------------------------------------------------------------------*/
bool detection_enabled;
/*-------------------------------------------------------------------------------------*\
| Auto connection permitting flag |
\*-------------------------------------------------------------------------------------*/
bool start_server;
/*-------------------------------------------------------------------------------------*\
| Auto connection permitting flag |
\*-------------------------------------------------------------------------------------*/
bool apply_post_options;
/*-------------------------------------------------------------------------------------*\
| Profile Manager |
\*-------------------------------------------------------------------------------------*/
@@ -275,7 +296,8 @@ private:
/*-------------------------------------------------------------------------------------*\
| Detection Thread and Detection State |
\*-------------------------------------------------------------------------------------*/
std::thread * DetectDevicesThread;
std::thread * DetectDevicesThread; // Used for rescan
std::thread * InitThread; // Used for initial scan, initial network scan, server startup
std::mutex DetectDeviceMutex;
std::atomic<bool> detection_is_required;

20
cli.cpp
View File

@@ -38,6 +38,9 @@ static std::string profile_save_filename = "";
const unsigned int brightness_percentage = 100;
const unsigned int speed_percentage = 100;
static int preserve_argc = 0;
static char** preserve_argv = nullptr;
enum
{
RET_FLAG_PRINT_HELP = 1,
@@ -889,7 +892,7 @@ bool OptionSaveProfile(std::string argument)
return(true);
}
int ProcessOptions(int argc, char* argv[], Options* options, std::vector<RGBController *>& rgb_controllers)
int ProcessOptions(Options* options, std::vector<RGBController *>& rgb_controllers)
{
unsigned int ret_flags = 0;
int arg_index = 1;
@@ -903,18 +906,18 @@ int ProcessOptions(int argc, char* argv[], Options* options, std::vector<RGBCont
wchar_t** argvw = CommandLineToArgvW(GetCommandLineW(), &fake_argc);
#endif
while(arg_index < argc)
while(arg_index < preserve_argc)
{
std::string option = argv[arg_index];
std::string option = preserve_argv[arg_index];
std::string argument = "";
filesystem::path arg_path;
/*---------------------------------------------------------*\
| Handle options that take an argument |
\*---------------------------------------------------------*/
if(arg_index + 1 < argc)
if(arg_index + 1 < preserve_argc)
{
argument = argv[arg_index + 1];
argument = preserve_argv[arg_index + 1];
#ifdef _WIN32
arg_path = argvw[arg_index + 1];
#else
@@ -1266,6 +1269,9 @@ unsigned int cli_pre_detection(int argc, char* argv[])
bool server_start = false;
bool print_help = false;
preserve_argc = argc;
preserve_argv = argv;
#ifdef _WIN32
int fake_argc;
wchar_t** argvw = CommandLineToArgvW(GetCommandLineW(), &fake_argc);
@@ -1697,7 +1703,7 @@ unsigned int cli_pre_detection(int argc, char* argv[])
return(ret_flags);
}
unsigned int cli_post_detection(int argc, char *argv[])
unsigned int cli_post_detection()
{
/*---------------------------------------------------------*\
| Wait for device detection |
@@ -1713,7 +1719,7 @@ unsigned int cli_post_detection(int argc, char *argv[])
| Process the argument options |
\*---------------------------------------------------------*/
Options options;
unsigned int ret_flags = ProcessOptions(argc, argv, &options, rgb_controllers);
unsigned int ret_flags = ProcessOptions(&options, rgb_controllers);
/*---------------------------------------------------------*\
| If the return flags are set, exit CLI mode without |

19
cli.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef CLI_H
#define CLI_H
unsigned int cli_pre_detection(int argc, char* argv[]);
unsigned int cli_post_detection();
enum
{
RET_FLAG_PRINT_HELP = 1,
RET_FLAG_START_GUI = 2,
RET_FLAG_I2C_TOOLS = 4,
RET_FLAG_START_MINIMIZED = 8,
RET_FLAG_NO_DETECT = 16,
RET_FLAG_CLI_POST_DETECTION = 32,
RET_FLAG_START_SERVER = 64,
RET_FLAG_NO_AUTO_CONNECT = 128,
};
#endif

143
main.cpp
View File

@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include "cli.h"
#include "ResourceManager.h"
#include "NetworkClient.h"
#include "NetworkServer.h"
@@ -32,24 +33,6 @@ io_connect_t macUSPCIO_driver_connection;
using namespace std::chrono_literals;
/*-------------------------------------------------------------*\
| Command line functionality and return flags |
\*-------------------------------------------------------------*/
extern unsigned int cli_pre_detection(int argc, char *argv[]);
extern unsigned int cli_post_detection(int argc, char *argv[]);
enum
{
RET_FLAG_PRINT_HELP = 1,
RET_FLAG_START_GUI = 2,
RET_FLAG_I2C_TOOLS = 4,
RET_FLAG_START_MINIMIZED = 8,
RET_FLAG_NO_DETECT = 16,
RET_FLAG_CLI_POST_DETECTION = 32,
RET_FLAG_START_SERVER = 64,
RET_FLAG_NO_AUTO_CONNECT = 128,
};
/******************************************************************************************\
* *
* InitializeTimerResolution (Win32) *
@@ -95,66 +78,6 @@ void WaitWhileServerOnline(NetworkServer* srv)
};
}
/******************************************************************************************\
* *
* AttemptLocalConnection *
* *
* Attempts an SDK connection to the local server. Returns true if success *
* *
\******************************************************************************************/
bool AttemptLocalConnection()
{
bool success = false;
NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers());
std::string titleString = "OpenRGB ";
titleString.append(VERSION_STRING);
client->SetName(titleString.c_str());
client->StartClient();
for(int timeout = 0; timeout < 10; timeout++)
{
if(client->GetConnected())
{
break;
}
std::this_thread::sleep_for(5ms);
}
if(!client->GetConnected())
{
client->StopClient();
delete client;
client = NULL;
}
else
{
ResourceManager::get()->RegisterNetworkClient(client);
success = true;
/*-----------------------------------------------------*\
| Wait up to 5 seconds for the client connection to |
| retrieve all controllers |
\*-----------------------------------------------------*/
for(int timeout = 0; timeout < 1000; timeout++)
{
if(client->GetOnline())
{
break;
}
std::this_thread::sleep_for(5ms);
}
}
return success;
}
/******************************************************************************************\
* *
* Install SMBus Driver WinRing0, If not already installed (Win32) *
@@ -279,61 +202,11 @@ int main(int argc, char* argv[])
\*---------------------------------------------------------*/
unsigned int ret_flags = cli_pre_detection(argc, argv);
/*---------------------------------------------------------*\
| Perform local connection and/or hardware detection if not |
| disabled from CLI |
\*---------------------------------------------------------*/
if(!(ret_flags & RET_FLAG_NO_AUTO_CONNECT))
{
printf("Attempting to connect to local OpenRGB server.\r\n");
if(!AttemptLocalConnection())
{
printf("Local OpenRGB server unavailable.\r\n");
}
else
{
printf("Local OpenRGB server connected, running in client mode\r\n");
ResourceManager::get()->DisableDetection();
}
}
/*---------------------------------------------------------*\
| Perform hardware detection if not disabled from CLI |
\*---------------------------------------------------------*/
if(!(ret_flags & RET_FLAG_NO_DETECT))
{
if(ResourceManager::get()->GetDetectionEnabled())
{
printf("Running standalone.\r\n");
}
ResourceManager::get()->DetectDevices();
}
/*---------------------------------------------------------*\
| Start the server if requested from CLI (this must be done |
| after attempting local connection!) |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_START_SERVER)
{
ResourceManager::get()->GetServer()->StartServer();
if(!ResourceManager::get()->GetServer()->GetOnline())
{
printf("Server failed to start\r\n");
}
}
/*---------------------------------------------------------*\
| Process command line arguments after detection only if the|
| pre-detection parsing indicated it should be run |
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_CLI_POST_DETECTION)
{
ret_flags |= cli_post_detection(argc, argv);
}
ResourceManager::get()->Initialize(
!(ret_flags & RET_FLAG_NO_AUTO_CONNECT),
!(ret_flags & RET_FLAG_NO_DETECT),
ret_flags & RET_FLAG_START_SERVER,
ret_flags & RET_FLAG_CLI_POST_DETECTION);
/*---------------------------------------------------------*\
| If the command line parser indicates that the GUI should |
@@ -342,14 +215,17 @@ int main(int argc, char* argv[])
\*---------------------------------------------------------*/
if(ret_flags & RET_FLAG_START_GUI)
{
LOG_TRACE("[main] initializing GUI");
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
QGuiApplication::setDesktopFileName("org.openrgb.OpenRGB");
LOG_TRACE("[main] QApplication created");
/*---------------------------------------------------------*\
| Main UI widget |
\*---------------------------------------------------------*/
Ui::OpenRGBDialog2 dlg;
LOG_TRACE("[main] Dialog created");
if(ret_flags & RET_FLAG_I2C_TOOLS)
{
@@ -370,6 +246,7 @@ int main(int argc, char* argv[])
dlg.show();
}
LOG_TRACE("[main] Ready to exec() the dialog");
return a.exec();
}
else

View File

@@ -433,7 +433,6 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
plugin_manager = new PluginManager();
plugin_manager->RegisterAddPluginCallback(&CreatePluginCallback, this);
plugin_manager->RegisterRemovePluginCallback(&DeletePluginCallback, this);
plugin_manager->ScanAndLoadPlugins();
/*-----------------------------------------------------*\
| Add the Plugins page |
@@ -1448,10 +1447,19 @@ void OpenRGBDialog2::onDetectionProgressUpdated()
void OpenRGBDialog2::onDetectionEnded()
{
/*-----------------------------------------------------*\
| Detect unconfigured zones and prompt for resizing |
\*-----------------------------------------------------*/
/*-------------------------------------------------------*\
| Detect unconfigured zones and prompt for resizing |
\*-------------------------------------------------------*/
OpenRGBZonesBulkResizer::RunChecks(this);
/*-------------------------------------------------------*\
| Load plugins after the first detection (ONLY the first) |
\*-------------------------------------------------------*/
if(!plugins_loaded)
{
plugin_manager->ScanAndLoadPlugins();
plugins_loaded = true;
}
}
void OpenRGBDialog2::on_SetAllDevices(unsigned char red, unsigned char green, unsigned char blue)

View File

@@ -108,6 +108,7 @@ private:
OpenRGBNanoleafSettingsPage *NanoleafSettingsPage;
bool ShowI2CTools = false;
bool plugins_loaded = false;
/*-------------------------------------*\
| System tray icon and menu |
@@ -188,5 +189,4 @@ private slots:
void on_InformationTabBar_currentChanged(int);
void on_DevicesTabBar_currentChanged(int);
void on_SettingsTabBar_currentChanged(int);
};