Split CLI processing into pre- and post-detection functions and add --localconfig and --nodetect options

This commit is contained in:
Adam Honse 2020-12-01 23:50:29 -06:00
parent 72da8f362c
commit ddfcd1caf9
11 changed files with 330 additions and 187 deletions

View file

@ -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));

View file

@ -29,6 +29,8 @@ public:
std::string profile_name
);
void SetConfigurationDirectory(std::string directory);
protected:
std::vector<RGBController *>& controllers;

View file

@ -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();

View file

@ -89,6 +89,8 @@ public:
ProfileManager* GetProfileManager();
SettingsManager* GetSettingsManager();
void SetConfigurationDirectory(std::string directory);
void DeviceListChanged();
void DetectionProgressChanged();

View file

@ -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 |
\*---------------------------------------------------------*/

419
cli.cpp
View file

@ -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::vector<RGBCont
argument = argv[arg_index + 1];
}
/*---------------------------------------------------------*\
| --server |
\*---------------------------------------------------------*/
if(option == "--client")
{
NetworkClient * client = new NetworkClient(rgb_controllers);
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")
{
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<RGBCont
\*---------------------------------------------------------*/
else
{
std::cout << "Error: Invalid option: " + option << std::endl;
return RET_FLAG_PRINT_HELP;
if((option == "--localconfig")
||(option == "--nodetect")
||(option == "--client")
||(option == "--server")
||(option == "--gui")
||(option == "--i2c-tools" || option == "--yolo")
||(option == "--startminimized")
||(option == "--help" || option == "-h")
||(option == "--version" || option == "-v"))
{
/*-------------------------------------------------*\
| Do nothing, these are pre-detection arguments |
| and this parser should ignore them |
\*-------------------------------------------------*/
}
else if(option == "--server-port")
{
/*-------------------------------------------------*\
| Increment index for pre-detection arguments with |
| parameter |
\*-------------------------------------------------*/
arg_index++;
}
else
{
/*-------------------------------------------------*\
| If the argument is not a pre-detection argument, |
| throw an error and print help |
\*-------------------------------------------------*/
std::cout << "Error: Invalid option: " + option << std::endl;
return RET_FLAG_PRINT_HELP;
}
}
arg_index++;
@ -1029,9 +935,217 @@ void WaitWhileServerOnline(NetworkServer* srv)
};
}
unsigned int cli_main(int argc, char *argv[], std::vector<RGBController *> &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<RGBController *> rgb_controllers = ResourceManager::get()->GetRGBControllers();
/*---------------------------------------------------------*\
| Process the argument options |
@ -1039,33 +1153,6 @@ unsigned int cli_main(int argc, char *argv[], std::vector<RGBController *> &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<RGBController *> &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<RGBController *> &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;

View file

@ -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<RGBController *> &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<RGBController*> &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<i2c_smbus_interface*> &busses = ResourceManager::get()->GetI2CBusses();
std::vector<RGBController*> &rgb_controllers = ResourceManager::get()->GetRGBControllers();
/*---------------------------------------------------------*\
| Process command line arguments before detection |
\*---------------------------------------------------------*/
unsigned int ret_flags = RET_FLAG_START_GUI;
ret_flags |= cli_pre_detection(argc, argv);
if(!AttemptLocalConnection(rgb_controllers))
/*---------------------------------------------------------*\
| 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)
{

View file

@ -17,7 +17,7 @@ public:
NetworkClient * net_client;
};
OpenRGBClientInfoPage::OpenRGBClientInfoPage(std::vector<RGBController *>& control, QWidget *parent) :
OpenRGBClientInfoPage::OpenRGBClientInfoPage(QWidget *parent) :
QFrame(parent),
ui(new Ui::OpenRGBClientInfoPageUi)
{

View file

@ -15,7 +15,7 @@ class Ui::OpenRGBClientInfoPage : public QFrame
Q_OBJECT
public:
explicit OpenRGBClientInfoPage(std::vector<RGBController *>& control, QWidget *parent = nullptr);
explicit OpenRGBClientInfoPage(QWidget *parent = nullptr);
~OpenRGBClientInfoPage();
void AddClient(NetworkClient* new_client);

View file

@ -141,7 +141,7 @@ bool OpenRGBDialog2::IsDarkTheme()
return false;
}
OpenRGBDialog2::OpenRGBDialog2(std::vector<i2c_smbus_interface *>& bus, std::vector<RGBController *>& 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<RGBController *> controllers = ResourceManager::get()->GetRGBControllers();
/*-----------------------------------------------------*\
| Loop through each controller in the list. |
\*-----------------------------------------------------*/

View file

@ -29,7 +29,7 @@ class Ui::OpenRGBDialog2 : public QMainWindow
Q_OBJECT
public:
explicit OpenRGBDialog2(std::vector<i2c_smbus_interface *>& bus, std::vector<RGBController *>& 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<i2c_smbus_interface *>& busses;
std::vector<RGBController *>& controllers;
private:
/*-------------------------------------*\
| Page pointers |