diff --git a/src/utils/process-config.cpp b/src/utils/process-config.cpp index 81551608..809e6d7b 100644 --- a/src/utils/process-config.cpp +++ b/src/utils/process-config.cpp @@ -1,4 +1,5 @@ #include "process-config.hpp" +#include "log-helper.hpp" #include "name-dialog.hpp" #include "utility.hpp" @@ -37,7 +38,7 @@ bool ProcessConfig::Load(obs_data_t *obj) return true; } -QStringList ProcessConfig::Args() +QStringList ProcessConfig::Args() const { QStringList result; for (auto &arg : _args) { @@ -46,6 +47,42 @@ QStringList ProcessConfig::Args() return result; } +bool ProcessConfig::StartProcessDetached() const +{ + return QProcess::startDetached(QString::fromStdString(Path()), Args(), + QString::fromStdString(WorkingDir())); +} + +std::variant +ProcessConfig::StartProcessAndWait(int timeout) const +{ + QProcess process; + process.setWorkingDirectory(QString::fromStdString(WorkingDir())); + process.start(QString::fromStdString(Path()), Args()); + vblog(LOG_INFO, "run \"%s\" with a timeout of %d ms", Path().c_str(), + timeout); + + if (!process.waitForFinished(timeout)) { + if (process.error() == QProcess::FailedToStart) { + vblog(LOG_INFO, "failed to start \"%s\"!", + Path().c_str()); + return ProcStartError::FAILED_TO_START; + } + vblog(LOG_INFO, + "timeout while running \"%s\"\nAttempting to kill process!", + Path().c_str()); + process.kill(); + process.waitForFinished(); + return ProcStartError::TIMEOUT; + } + + if (process.exitStatus() == QProcess::NormalExit) { + return process.exitCode(); + } + vblog(LOG_INFO, "process \"%s\" crashed!", Path().c_str()); + return ProcStartError::CRASH; +} + ProcessConfigEdit::ProcessConfigEdit(QWidget *parent) : QWidget(parent), _filePath(new FileSelection()), @@ -91,7 +128,7 @@ ProcessConfigEdit::ProcessConfigEdit(QWidget *parent) _advancedSettingsLayout->addWidget(_argList); _advancedSettingsLayout->addLayout(workingDirectoryLayout); - auto *mainLayout = new QVBoxLayout; + auto mainLayout = new QVBoxLayout; mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addLayout(entryLayout); mainLayout->addLayout(_advancedSettingsLayout); @@ -143,6 +180,9 @@ void ProcessConfigEdit::ShowAdvancedSettings(bool showAdvancedSettings) _showAdvancedSettings->setVisible(!showAdvancedSettings); adjustSize(); updateGeometry(); + if (showAdvancedSettings) { + emit AdvancedSettingsEnabled(); + } } } // namespace advss diff --git a/src/utils/process-config.hpp b/src/utils/process-config.hpp index 720066f9..f353459e 100644 --- a/src/utils/process-config.hpp +++ b/src/utils/process-config.hpp @@ -3,12 +3,13 @@ #include "string-list.hpp" #include -#include +#include #include #include #include #include +#include namespace advss { @@ -17,10 +18,21 @@ public: bool Save(obs_data_t *obj) const; bool Load(obs_data_t *obj); - std::string Path() { return _path; } + std::string Path() const { return _path; } std::string UnresolvedPath() const { return _path.UnresolvedValue(); } - std::string WorkingDir() { return _workingDirectory; } - QStringList Args(); // Resolves variables + std::string WorkingDir() const { return _workingDirectory; } + QStringList Args() const; // Resolves variables + + enum class ProcStartError { + NONE, + FAILED_TO_START, + TIMEOUT, + CRASH, + }; + + std::variant + StartProcessAndWait(int timeoutInMs) const; + bool StartProcessDetached() const; private: StringVariable _path = obs_module_text("AdvSceneSwitcher.enterPath"); @@ -44,6 +56,7 @@ private slots: void ArgsChanged(const StringList &); signals: void ConfigChanged(const ProcessConfig &); + void AdvancedSettingsEnabled(); private: void ShowAdvancedSettings(bool);