From ddfcd1caf9c06333f3793c5f0ae5c6e46301fb14 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Tue, 1 Dec 2020 23:50:29 -0600 Subject: [PATCH] Split CLI processing into pre- and post-detection functions and add --localconfig and --nodetect options --- ProfileManager.cpp | 6 + ProfileManager.h | 2 + ResourceManager.cpp | 6 + ResourceManager.h | 2 + SettingsManager.cpp | 7 +- cli.cpp | 419 +++++++++++++++++++++-------------- main.cpp | 57 +++-- qt/OpenRGBClientInfoPage.cpp | 2 +- qt/OpenRGBClientInfoPage.h | 2 +- qt/OpenRGBDialog2.cpp | 8 +- qt/OpenRGBDialog2.h | 6 +- 11 files changed, 330 insertions(+), 187 deletions(-) diff --git a/ProfileManager.cpp b/ProfileManager.cpp index 326eca18..64c6e413 100644 --- a/ProfileManager.cpp +++ b/ProfileManager.cpp @@ -72,6 +72,12 @@ bool ProfileManager::SaveProfile(std::string profile_name) } } +void ProfileManager::SetConfigurationDirectory(std::string directory) +{ + configuration_directory = directory; + UpdateProfileList(); +} + bool ProfileManager::LoadProfile(std::string profile_name) { return(LoadProfileWithOptions(profile_name, false, true)); diff --git a/ProfileManager.h b/ProfileManager.h index 3c00c316..e1dcea5c 100644 --- a/ProfileManager.h +++ b/ProfileManager.h @@ -29,6 +29,8 @@ public: std::string profile_name ); + void SetConfigurationDirectory(std::string directory); + protected: std::vector& controllers; diff --git a/ResourceManager.cpp b/ResourceManager.cpp index 69246218..e7648d76 100644 --- a/ResourceManager.cpp +++ b/ResourceManager.cpp @@ -284,6 +284,12 @@ const char *ResourceManager::GetDetectionString() return (detection_string); } +void ResourceManager::SetConfigurationDirectory(std::string directory) +{ + settings_manager->LoadSettings(directory + "OpenRGB.json"); + profile_manager->SetConfigurationDirectory(directory); +} + void ResourceManager::Cleanup() { ResourceManager::get()->WaitForDeviceDetection(); diff --git a/ResourceManager.h b/ResourceManager.h index f5d9da0c..b474535a 100644 --- a/ResourceManager.h +++ b/ResourceManager.h @@ -89,6 +89,8 @@ public: ProfileManager* GetProfileManager(); SettingsManager* GetSettingsManager(); + void SetConfigurationDirectory(std::string directory); + void DeviceListChanged(); void DetectionProgressChanged(); diff --git a/SettingsManager.cpp b/SettingsManager.cpp index 73791a4b..67f44e6b 100644 --- a/SettingsManager.cpp +++ b/SettingsManager.cpp @@ -51,6 +51,11 @@ void SettingsManager::SetSettings(std::string settings_key, json new_settings) void SettingsManager::LoadSettings(std::string filename) { + /*---------------------------------------------------------*\ + | Clear any stored settings before loading | + \*---------------------------------------------------------*/ + settings_data.clear(); + /*---------------------------------------------------------*\ | Store settings filename, so we can save to it later | \*---------------------------------------------------------*/ @@ -101,4 +106,4 @@ void SettingsManager::SaveSettings() settings_file.close(); } -} \ No newline at end of file +} diff --git a/cli.cpp b/cli.cpp index e357517c..c7d28bac 100644 --- a/cli.cpp +++ b/cli.cpp @@ -30,6 +30,9 @@ enum 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, }; struct DeviceOptions @@ -371,6 +374,8 @@ void OptionHelp() help_text += "--i2c-tools Shows the I2C/SMBus Tools page in the GUI. Implies --gui, even if not specified.\n"; help_text += " USE I2C TOOLS AT YOUR OWN RISK! Don't use this option if you don't know what you're doing!\n"; help_text += " There is a risk of bricking your motherboard, RGB controller, and RAM if you send invalid SMBus/I2C transactions.\n"; + help_text += "--localconfig Use the current working directory instead of the global configuration directory.\n"; + help_text += "--nodetect Do not try to detect hardware or autoconnect to a local server at startup.\n"; std::cout << help_text << std::endl; } @@ -688,139 +693,10 @@ int ProcessOptions(int argc, char *argv[], Options *options, std::vectorSetIP(ip.c_str()); - client->SetName(titleString.c_str()); - client->SetPort(port_val); - - client->StartClient(); - - for(int timeout = 0; timeout < 100; timeout++) - { - if(client->GetConnected()) - { - break; - } - std::this_thread::sleep_for(10ms); - } - - ResourceManager::get()->GetClients().push_back(client); - - arg_index++; - } - - /*---------------------------------------------------------*\ - | --server (no arguments) | - \*---------------------------------------------------------*/ - else if(option == "--server") - { - options->servOpts.start = true; - } - - /*---------------------------------------------------------*\ - | --server-port | - \*---------------------------------------------------------*/ - else if(option == "--server-port") - { - if (argument != "") - { - try - { - int port = std::stoi(argument); - if (port >= 1024 && port <= 65535) - { - options->servOpts.port = port; - } - else - { - std::cout << "Error: Port out of range: " << port << " (1024-65535)" << std::endl; - return RET_FLAG_PRINT_HELP; - } - } - catch(std::invalid_argument& e) - { - std::cout << "Error: Invalid data in --server-port argument (expected a number in range 1024-65535)" << std::endl; - return RET_FLAG_PRINT_HELP; - } - } - else - { - std::cout << "Error: Missing argument for --server-port" << std::endl; - return RET_FLAG_PRINT_HELP; - } - - arg_index++; - } - - /*---------------------------------------------------------*\ - | --gui (no arguments) | - \*---------------------------------------------------------*/ - else if(option == "--gui") - { - ret_flags |= RET_FLAG_START_GUI; - } - - /*---------------------------------------------------------*\ - | --i2c-tools / --yolo (no arguments) | - \*---------------------------------------------------------*/ - else if(option == "--i2c-tools" || option == "--yolo") - { - ret_flags |= RET_FLAG_START_GUI | RET_FLAG_I2C_TOOLS; - } - - /*---------------------------------------------------------*\ - | --startminimized | - \*---------------------------------------------------------*/ - else if(option == "--startminimized") - { - ret_flags |= RET_FLAG_START_GUI | RET_FLAG_START_MINIMIZED; - } - - /*---------------------------------------------------------*\ - | -h / --help (no arguments) | - \*---------------------------------------------------------*/ - else if(option == "--help" || option == "-h") - { - OptionHelp(); - exit(0); - } - - /*---------------------------------------------------------*\ - | -v / --version (no arguments) | - \*---------------------------------------------------------*/ - else if(option == "--version" || option == "-v") - { - OptionVersion(); - exit(0); - } - /*---------------------------------------------------------*\ | -l / --list-devices (no arguments) | \*---------------------------------------------------------*/ - else if(option == "--list-devices" || option == "-l") + if(option == "--list-devices" || option == "-l") { OptionListDevices(rgb_controllers); exit(0); @@ -916,8 +792,38 @@ int ProcessOptions(int argc, char *argv[], Options *options, std::vector &rgb_controllers, ProfileManager* profile_manager_in) +unsigned int cli_pre_detection(int argc, char *argv[]) { - profile_manager = profile_manager_in; + /*---------------------------------------------------------*\ + | Process only the arguments that should be performed prior | + | to detecting devices and/or starting clients | + \*---------------------------------------------------------*/ + int arg_index = 1; + unsigned int ret_flags = 0; + unsigned short server_port = OPENRGB_SDK_PORT; + bool server_start = false; + bool print_help = false; + + while(arg_index < argc) + { + std::string option = argv[arg_index]; + std::string argument = ""; + + /*---------------------------------------------------------*\ + | Handle options that take an argument | + \*---------------------------------------------------------*/ + if(arg_index + 1 < argc) + { + argument = argv[arg_index + 1]; + } + + /*---------------------------------------------------------*\ + | --localconfig | + \*---------------------------------------------------------*/ + if(option == "--localconfig") + { + ResourceManager::get()->SetConfigurationDirectory("./"); + } + + /*---------------------------------------------------------*\ + | --nodetect | + \*---------------------------------------------------------*/ + else if(option == "--nodetect") + { + ret_flags |= RET_FLAG_NO_DETECT; + } + + /*---------------------------------------------------------*\ + | --client | + \*---------------------------------------------------------*/ + else if(option == "--client") + { + NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers()); + + std::size_t pos = argument.find(":"); + std::string ip = argument.substr(0, pos); + unsigned short port_val; + + if(pos == argument.npos) + { + port_val = OPENRGB_SDK_PORT; + } + else + { + std::string port = argument.substr(argument.find(":") + 1); + port_val = std::stoi(port); + } + + std::string titleString = "OpenRGB "; + titleString.append(VERSION_STRING); + + client->SetIP(ip.c_str()); + client->SetName(titleString.c_str()); + client->SetPort(port_val); + + client->StartClient(); + + for(int timeout = 0; timeout < 100; timeout++) + { + if(client->GetConnected()) + { + break; + } + std::this_thread::sleep_for(10ms); + } + + ResourceManager::get()->GetClients().push_back(client); + + arg_index++; + } + + /*---------------------------------------------------------*\ + | --server (no arguments) | + \*---------------------------------------------------------*/ + else if(option == "--server") + { + server_start = true; + } + + /*---------------------------------------------------------*\ + | --server-port | + \*---------------------------------------------------------*/ + else if(option == "--server-port") + { + if (argument != "") + { + try + { + int port = std::stoi(argument); + if (port >= 1024 && port <= 65535) + { + server_port = port; + server_start = true; + } + else + { + std::cout << "Error: Port out of range: " << port << " (1024-65535)" << std::endl; + print_help = true; + break; + } + } + catch(std::invalid_argument& e) + { + std::cout << "Error: Invalid data in --server-port argument (expected a number in range 1024-65535)" << std::endl; + print_help = true; + break; + } + } + else + { + std::cout << "Error: Missing argument for --server-port" << std::endl; + print_help = true; + break; + } + + arg_index++; + } + + /*---------------------------------------------------------*\ + | --gui (no arguments) | + \*---------------------------------------------------------*/ + else if(option == "--gui") + { + ret_flags |= RET_FLAG_START_GUI; + } + + /*---------------------------------------------------------*\ + | --i2c-tools / --yolo (no arguments) | + \*---------------------------------------------------------*/ + else if(option == "--i2c-tools" || option == "--yolo") + { + ret_flags |= RET_FLAG_START_GUI | RET_FLAG_I2C_TOOLS; + } + + /*---------------------------------------------------------*\ + | --startminimized | + \*---------------------------------------------------------*/ + else if(option == "--startminimized") + { + ret_flags |= RET_FLAG_START_GUI | RET_FLAG_START_MINIMIZED; + } + + /*---------------------------------------------------------*\ + | -h / --help (no arguments) | + \*---------------------------------------------------------*/ + else if(option == "--help" || option == "-h") + { + print_help = true; + break; + } + + /*---------------------------------------------------------*\ + | -v / --version (no arguments) | + \*---------------------------------------------------------*/ + else if(option == "--version" || option == "-v") + { + OptionVersion(); + exit(0); + } + + /*---------------------------------------------------------*\ + | Any unrecognized arguments trigger the post-detection CLI | + \*---------------------------------------------------------*/ + else + { + ret_flags |= RET_FLAG_CLI_POST_DETECTION; + } + + arg_index++; + } + + if(print_help) + { + OptionHelp(); + exit(0); + } + + if(server_start) + { + ResourceManager::get()->GetServer()->SetPort(server_port); + ret_flags |= RET_FLAG_START_SERVER; + } + + return(ret_flags); +} + +unsigned int cli_post_detection(int argc, char *argv[]) +{ + /*---------------------------------------------------------*\ + | Wait for device detection | + \*---------------------------------------------------------*/ + ResourceManager::get()->WaitForDeviceDetection(); + + /*---------------------------------------------------------*\ + | Get controller list from resource manager | + \*---------------------------------------------------------*/ + std::vector rgb_controllers = ResourceManager::get()->GetRGBControllers(); /*---------------------------------------------------------*\ | Process the argument options | @@ -1039,33 +1153,6 @@ unsigned int cli_main(int argc, char *argv[], std::vector &rgb_ Options options; unsigned int ret_flags = ProcessOptions(argc, argv, &options, rgb_controllers); - /*---------------------------------------------------------*\ - | If the server was told to start, start it before returning| - \*---------------------------------------------------------*/ - if(options.servOpts.start) - { - ResourceManager::get()->GetServer()->SetPort(options.servOpts.port); - ResourceManager::get()->GetServer()->StartServer(); - - if(ResourceManager::get()->GetServer()->GetOnline()) - { - /*---------------------------------------------------------*\ - | If the GUI has been started, return from cli_main. | - | Otherwise, we are in daemon mode and cli_main should wait | - | to keep the program alive as long as the server is online | - \*---------------------------------------------------------*/ - if((ret_flags & RET_FLAG_START_GUI) == 0) - { - WaitWhileServerOnline(ResourceManager::get()->GetServer()); - } - } - else - { - std::cout << "Server failed to start" << std::endl; - exit(1); - } - } - /*---------------------------------------------------------*\ | If the return flags are set, exit CLI mode without | | processing device updates from CLI input. | @@ -1085,8 +1172,6 @@ unsigned int cli_main(int argc, char *argv[], std::vector &rgb_ break; } - ResourceManager::get()->WaitForDeviceDetection(); - /*---------------------------------------------------------*\ | If the options has one or more specific devices, loop | | through all of the specific devices and apply settings. | @@ -1123,6 +1208,14 @@ unsigned int cli_main(int argc, char *argv[], std::vector &rgb_ } } + /*---------------------------------------------------------*\ + | If the server is online, keep running while it is online | + \*---------------------------------------------------------*/ + if(ResourceManager::get()->GetServer()->GetOnline()) + { + WaitWhileServerOnline(ResourceManager::get()->GetServer()); + } + exit(0); return 0; diff --git a/main.cpp b/main.cpp index cba87e3b..5b8daff1 100644 --- a/main.cpp +++ b/main.cpp @@ -25,7 +25,8 @@ using namespace std::chrono_literals; /*-------------------------------------------------------------*\ | Command line functionality and return flags | \*-------------------------------------------------------------*/ -extern unsigned int cli_main(int argc, char *argv[], std::vector &rgb_controllers, ProfileManager* profile_manager_in); +extern unsigned int cli_pre_detection(int argc, char *argv[]); +extern unsigned int cli_post_detection(int argc, char *argv[]); enum { @@ -33,6 +34,9 @@ enum 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, }; /******************************************************************************************\ @@ -80,11 +84,11 @@ void InitializeTimerResolutionThreadFunction() * * \******************************************************************************************/ -bool AttemptLocalConnection(std::vector &rgb_controllers) +bool AttemptLocalConnection() { bool success = false; - NetworkClient * client = new NetworkClient(rgb_controllers); + NetworkClient * client = new NetworkClient(ResourceManager::get()->GetRGBControllers()); std::string titleString = "OpenRGB "; titleString.append(VERSION_STRING); @@ -144,26 +148,53 @@ int main(int argc, char* argv[]) freopen("CONOUT$", "w", stderr); } + /*---------------------------------------------------------*\ + | Windows only - Start timer resolution correction thread | + \*---------------------------------------------------------*/ std::thread * InitializeTimerResolutionThread; InitializeTimerResolutionThread = new std::thread(InitializeTimerResolutionThreadFunction); InitializeTimerResolutionThread->detach(); #endif - std::vector &busses = ResourceManager::get()->GetI2CBusses(); - std::vector &rgb_controllers = ResourceManager::get()->GetRGBControllers(); - - if(!AttemptLocalConnection(rgb_controllers)) + /*---------------------------------------------------------*\ + | Process command line arguments before detection | + \*---------------------------------------------------------*/ + unsigned int ret_flags = RET_FLAG_START_GUI; + 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_DETECT)) { - ResourceManager::get()->DetectDevices(); + if(!AttemptLocalConnection()) + { + ResourceManager::get()->DetectDevices(); + } } /*---------------------------------------------------------*\ - | Process command line arguments | + | Start the server if requested from CLI (this must be done | + | after attempting local connection!) | \*---------------------------------------------------------*/ - unsigned int ret_flags = RET_FLAG_START_GUI; - if(argc > 1) + if(ret_flags & RET_FLAG_START_SERVER) { - ret_flags = cli_main(argc, argv, rgb_controllers, ResourceManager::get()->GetProfileManager()); + 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); } /*---------------------------------------------------------*\ @@ -176,7 +207,7 @@ int main(int argc, char* argv[]) QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication a(argc, argv); - Ui::OpenRGBDialog2 dlg(busses, rgb_controllers); + Ui::OpenRGBDialog2 dlg; if(ret_flags & RET_FLAG_I2C_TOOLS) { diff --git a/qt/OpenRGBClientInfoPage.cpp b/qt/OpenRGBClientInfoPage.cpp index e3c6c06e..491ab62d 100644 --- a/qt/OpenRGBClientInfoPage.cpp +++ b/qt/OpenRGBClientInfoPage.cpp @@ -17,7 +17,7 @@ public: NetworkClient * net_client; }; -OpenRGBClientInfoPage::OpenRGBClientInfoPage(std::vector& control, QWidget *parent) : +OpenRGBClientInfoPage::OpenRGBClientInfoPage(QWidget *parent) : QFrame(parent), ui(new Ui::OpenRGBClientInfoPageUi) { diff --git a/qt/OpenRGBClientInfoPage.h b/qt/OpenRGBClientInfoPage.h index d133237f..f084998b 100644 --- a/qt/OpenRGBClientInfoPage.h +++ b/qt/OpenRGBClientInfoPage.h @@ -15,7 +15,7 @@ class Ui::OpenRGBClientInfoPage : public QFrame Q_OBJECT public: - explicit OpenRGBClientInfoPage(std::vector& control, QWidget *parent = nullptr); + explicit OpenRGBClientInfoPage(QWidget *parent = nullptr); ~OpenRGBClientInfoPage(); void AddClient(NetworkClient* new_client); diff --git a/qt/OpenRGBDialog2.cpp b/qt/OpenRGBDialog2.cpp index 2fdd54d0..8435bf7f 100644 --- a/qt/OpenRGBDialog2.cpp +++ b/qt/OpenRGBDialog2.cpp @@ -141,7 +141,7 @@ bool OpenRGBDialog2::IsDarkTheme() return false; } -OpenRGBDialog2::OpenRGBDialog2(std::vector& bus, std::vector& control, QWidget *parent) : QMainWindow(parent), busses(bus), controllers(control), ui(new OpenRGBDialog2Ui) +OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new OpenRGBDialog2Ui) { ui->setupUi(this); @@ -331,7 +331,7 @@ void OpenRGBDialog2::AddI2CToolsPage() /*-----------------------------------------------------*\ | Create the I2C Tools page if it doesn't exist yet | \*-----------------------------------------------------*/ - SMBusToolsPage = new OpenRGBSystemInfoPage(busses); + SMBusToolsPage = new OpenRGBSystemInfoPage(ResourceManager::get()->GetI2CBusses()); /*-----------------------------------------------------*\ | Create the I2C Tools tab in the Information bar | @@ -364,7 +364,7 @@ void OpenRGBDialog2::AddClientTab() \*-----------------------------------------------------*/ if(ClientInfoPage == NULL) { - ClientInfoPage = new OpenRGBClientInfoPage(controllers); + ClientInfoPage = new OpenRGBClientInfoPage(); ui->MainTabBar->addTab(ClientInfoPage, "SDK Client"); /*-----------------------------------------------------*\ @@ -414,6 +414,8 @@ void OpenRGBDialog2::ClearDevicesList() void OpenRGBDialog2::UpdateDevicesList() { + std::vector controllers = ResourceManager::get()->GetRGBControllers(); + /*-----------------------------------------------------*\ | Loop through each controller in the list. | \*-----------------------------------------------------*/ diff --git a/qt/OpenRGBDialog2.h b/qt/OpenRGBDialog2.h index 03be402f..650e7ff9 100644 --- a/qt/OpenRGBDialog2.h +++ b/qt/OpenRGBDialog2.h @@ -29,7 +29,7 @@ class Ui::OpenRGBDialog2 : public QMainWindow Q_OBJECT public: - explicit OpenRGBDialog2(std::vector& bus, std::vector& control, QWidget *parent = 0); + explicit OpenRGBDialog2(QWidget *parent = 0); ~OpenRGBDialog2(); void AddClient(NetworkClient* new_client); @@ -41,10 +41,6 @@ public: static bool IsDarkTheme(); -protected: - std::vector& busses; - std::vector& controllers; - private: /*-------------------------------------*\ | Page pointers |