mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-20 20:40:15 +00:00
109 lines
2.7 KiB
C++
109 lines
2.7 KiB
C++
#include "launch_manager.hpp"
|
|
#include "debug.hpp"
|
|
|
|
LaunchManager::~LaunchManager(){
|
|
if(currentLaunch){
|
|
auto& p = currentLaunch->process;
|
|
p.blockSignals(true);
|
|
p.terminate();
|
|
p.waitForFinished(500);
|
|
if(p.state() != QProcess::NotRunning){
|
|
p.kill();
|
|
p.waitForFinished(1000);
|
|
}
|
|
}
|
|
queuedLaunch.reset();
|
|
}
|
|
|
|
void LaunchManager::launch(std::unique_ptr<LaunchContext>&& ctx){
|
|
if(getCurrentStatus() == LaunchContext::Type::None){
|
|
doLaunch(std::move(ctx));
|
|
} else {
|
|
if(queuedLaunch && queuedLaunch->type == LaunchContext::Type::Run){
|
|
return;
|
|
}
|
|
queuedLaunch = std::move(ctx);
|
|
currentLaunch->terminate();
|
|
}
|
|
}
|
|
|
|
void LaunchManager::doLaunch(std::unique_ptr<LaunchContext>&& ctx){
|
|
currentLaunch = std::move(ctx);
|
|
|
|
connect(¤tLaunch->process,
|
|
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &LaunchManager::processFinished, Qt::UniqueConnection);
|
|
|
|
currentLaunch->process.start(currentLaunch->executablePath, currentLaunch->args);
|
|
|
|
if(!currentLaunch->process.waitForStarted()){
|
|
//Shouldn't happen as we probe ug executability at startup
|
|
abort_msgBox("Failed to launch process. Did the ug executable disappear?");
|
|
}
|
|
}
|
|
|
|
void LaunchManager::stop(){
|
|
if(!currentLaunch)
|
|
return;
|
|
|
|
currentLaunch->terminate();
|
|
}
|
|
|
|
void LaunchManager::processFinished(){
|
|
currentLaunch.reset();
|
|
|
|
if(queuedLaunch)
|
|
doLaunch(std::move(queuedLaunch));
|
|
}
|
|
|
|
std::unique_ptr<LaunchContext> LaunchManager::extractCurrentCtx(){
|
|
auto ret = std::move(currentLaunch);
|
|
return ret;
|
|
}
|
|
|
|
|
|
void LaunchManager::reLaunch(std::unique_ptr<LaunchContext>&& ctx){
|
|
queuedLaunch = std::move(ctx);
|
|
}
|
|
|
|
LaunchContext::Type LaunchManager::getCurrentStatus() const{
|
|
if(!currentLaunch)
|
|
return LaunchContext::Type::None;
|
|
|
|
return currentLaunch->type;
|
|
}
|
|
|
|
LaunchContext::LaunchContext(){
|
|
connect(&killTimer, &QTimer::timeout, [=](){ process.kill(); });
|
|
killTimer.setSingleShot(true);
|
|
connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
this, &LaunchContext::processTerminationHandler);
|
|
|
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
|
connect(&process, &QProcess::readyReadStandardOutput, this, &LaunchContext::processOutput);
|
|
connect(&process, &QProcess::readyReadStandardError, this, &LaunchContext::processOutput);
|
|
}
|
|
|
|
void LaunchContext::processTerminationHandler(int code, QProcess::ExitStatus es){
|
|
emit processTerminated(code, es, terminationRequested);
|
|
}
|
|
|
|
void LaunchContext::processOutput(){
|
|
QString str = process.isReadable() ? process.readAll() : QByteArray();
|
|
|
|
emit processOutputRead(str);
|
|
|
|
lineBuf.write(str.toStdString());
|
|
|
|
while(lineBuf.hasLine()){
|
|
emit processOutputLine(lineBuf.peek());
|
|
lineBuf.pop();
|
|
}
|
|
}
|
|
|
|
void LaunchContext::terminate(){
|
|
terminationRequested = true;
|
|
process.terminate();
|
|
killTimer.start(terminateTimeoutMs);
|
|
}
|