Utils: Use std::function instead of signal SynchronousProcess callback

Simpler interface and use.

Change-Id: I8db448b7ccd12927b8f8fd347b0a92c3f76f7114
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
hjk
2021-05-06 08:56:42 +02:00
parent 3229903e8a
commit d825805c39
6 changed files with 31 additions and 85 deletions

View File

@@ -1862,12 +1862,8 @@ QString QtcProcess::locateBinary(const QString &binary)
event loop that blocks only user input events. Thus, it allows for the GUI to
repaint and append output to log windows.
The stdOut(), stdErr() signals are emitted unbuffered as the process
writes them.
The stdOutBuffered(), stdErrBuffered() signals are emitted with complete
lines based on the '\\n' marker if they are enabled using
stdOutBufferedSignalsEnabled()/setStdErrBufferedSignalsEnabled().
The callbacks set with setStdOutCallBack(), setStdErrCallback() are called
with complete lines based on the '\\n' marker.
They would typically be used for log windows.
There is a timeout handling that takes effect after the last data have been
@@ -1974,8 +1970,6 @@ SynchronousProcessResponse::Result defaultExitCodeInterpreter(int code)
// Data for one channel buffer (stderr/stdout)
class ChannelBuffer : public QObject
{
Q_OBJECT
public:
void clearForRun();
@@ -1987,16 +1981,11 @@ public:
QTextCodec *codec = nullptr; // Not owner
std::unique_ptr<QTextCodec::ConverterState> codecState;
int rawDataPos = 0;
bool bufferedSignalsEnabled = false;
bool firstBuffer = true;
signals:
void outputBuffered(const QString &text, bool firstTime);
std::function<void(const QString &lines)> outputCallback;
};
void ChannelBuffer::clearForRun()
{
firstBuffer = true;
rawDataPos = 0;
rawData.clear();
codecState.reset(new QTextCodec::ConverterState);
@@ -2035,12 +2024,10 @@ void ChannelBuffer::append(const QByteArray &text, bool emitSignals)
return;
// Buffered. Emit complete lines?
if (bufferedSignalsEnabled) {
if (outputCallback) {
const QString lines = linesRead();
if (!lines.isEmpty()) {
emit outputBuffered(lines, firstBuffer);
firstBuffer = false;
}
if (!lines.isEmpty())
outputCallback(lines);
}
}
@@ -2098,8 +2085,6 @@ SynchronousProcess::SynchronousProcess() :
d->m_hangTimerCount = 0;
processStdErr(true);
});
connect(&d->m_stdOut, &ChannelBuffer::outputBuffered, this, &SynchronousProcess::stdOutBuffered);
connect(&d->m_stdErr, &ChannelBuffer::outputBuffered, this, &SynchronousProcess::stdErrBuffered);
}
SynchronousProcess::~SynchronousProcess()
@@ -2133,26 +2118,6 @@ QTextCodec *SynchronousProcess::codec() const
return d->m_codec;
}
bool SynchronousProcess::stdOutBufferedSignalsEnabled() const
{
return d->m_stdOut.bufferedSignalsEnabled;
}
void SynchronousProcess::setStdOutBufferedSignalsEnabled(bool v)
{
d->m_stdOut.bufferedSignalsEnabled = v;
}
bool SynchronousProcess::stdErrBufferedSignalsEnabled() const
{
return d->m_stdErr.bufferedSignalsEnabled;
}
void SynchronousProcess::setStdErrBufferedSignalsEnabled(bool v)
{
d->m_stdErr.bufferedSignalsEnabled = v;
}
Environment SynchronousProcess::environment() const
{
return d->m_process.environment();
@@ -2352,6 +2317,16 @@ SynchronousProcessResponse SynchronousProcess::runBlocking(const CommandLine &cm
return d->m_result;
}
void SynchronousProcess::setStdOutCallback(const std::function<void (const QString &)> &callback)
{
d->m_stdOut.outputCallback = callback;
}
void SynchronousProcess::setStdErrCallback(const std::function<void (const QString &)> &callback)
{
d->m_stdErr.outputCallback = callback;
}
bool SynchronousProcess::terminate()
{
return d->m_process.stopProcess();
@@ -2423,6 +2398,3 @@ void SynchronousProcess::processStdErr(bool emitSignals)
}
} // namespace Utils
#include "qtcprocess.moc"

View File

@@ -248,12 +248,6 @@ public:
QProcess::ProcessChannelMode processChannelMode () const;
void setProcessChannelMode(QProcess::ProcessChannelMode m);
bool stdOutBufferedSignalsEnabled() const;
void setStdOutBufferedSignalsEnabled(bool);
bool stdErrBufferedSignalsEnabled() const;
void setStdErrBufferedSignalsEnabled(bool);
bool timeOutMessageBoxEnabled() const;
void setTimeOutMessageBoxEnabled(bool);
@@ -274,9 +268,8 @@ public:
// Starts the command blocking the UI fully
SynchronousProcessResponse runBlocking(const CommandLine &cmd);
signals:
void stdOutBuffered(const QString &lines, bool firstTime);
void stdErrBuffered(const QString &lines, bool firstTime);
void setStdOutCallback(const std::function<void(const QString &)> &callback);
void setStdErrCallback(const std::function<void(const QString &)> &callback);
public slots:
bool terminate();

View File

@@ -407,9 +407,7 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const CommandLine &cmd,
if (d->m_flags & MergeOutputChannels) {
process.setProcessChannelMode(QProcess::MergedChannels);
} else if (d->m_progressiveOutput || !(d->m_flags & SuppressStdErr)) {
process.setStdErrBufferedSignalsEnabled(true);
connect(&process, &SynchronousProcess::stdErrBuffered,
this, [this, proxy](const QString &text) {
process.setStdErrCallback([this, proxy](const QString &text) {
if (d->m_progressParser)
d->m_progressParser->parseProgress(text);
if (!(d->m_flags & SuppressStdErr))
@@ -421,9 +419,7 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const CommandLine &cmd,
// connect stdout to the output window if desired
if (d->m_progressParser || d->m_progressiveOutput || (d->m_flags & ShowStdOut)) {
process.setStdOutBufferedSignalsEnabled(true);
connect(&process, &SynchronousProcess::stdOutBuffered,
this, [this, proxy](const QString &text) {
process.setStdOutCallback([this, proxy](const QString &text) {
if (d->m_progressParser)
d->m_progressParser->parseProgress(text);
if (d->m_flags & ShowStdOut)

View File

@@ -174,18 +174,15 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
SynchronousProcess proc;
proc.setEnvironment(AndroidConfigurations::toolsEnvironment(config));
bool assertionFound = false;
proc.setStdErrBufferedSignalsEnabled(true);
proc.setStdOutBufferedSignalsEnabled(true);
proc.setTimeoutS(timeout);
QObject::connect(&proc, &SynchronousProcess::stdOutBuffered,
[offset, progressQuota, &proc, &assertionFound, &fi](const QString &out) {
proc.setStdOutCallback([offset, progressQuota, &proc, &assertionFound, &fi](const QString &out) {
int progressPercent = parseProgress(out, assertionFound);
if (assertionFound)
proc.terminate();
if (progressPercent != -1)
fi.setProgressValue(offset + qRound((progressPercent / 100.0) * progressQuota));
});
QObject::connect(&proc, &SynchronousProcess::stdErrBuffered, [&output](const QString &err) {
proc.setStdErrCallback([&output](const QString &err) {
output.stdError = err;
});
if (interruptible) {

View File

@@ -1249,7 +1249,6 @@ PerforceResponse PerforcePluginPrivate::synchronousProcess(const QString &workin
{
QTC_ASSERT(stdInput.isEmpty(), return PerforceResponse()); // Not supported here
VcsOutputWindow *outputWindow = VcsOutputWindow::instance();
// Run, connect stderr to the output window
SynchronousProcess process;
const int timeOutS = (flags & LongTimeOut) ? m_settings.longTimeOutS() : m_settings.timeOutS.value();
@@ -1262,26 +1261,15 @@ PerforceResponse PerforcePluginPrivate::synchronousProcess(const QString &workin
process.setWorkingDirectory(workingDir);
// connect stderr to the output window if desired
if (flags & StdErrToWindow) {
process.setStdErrBufferedSignalsEnabled(true);
connect(&process, &SynchronousProcess::stdErrBuffered,
outputWindow, [](const QString &lines) {
VcsOutputWindow::append(lines);
});
}
if (flags & StdErrToWindow)
process.setStdErrCallback([](const QString &lines) { VcsOutputWindow::append(lines); });
// connect stdout to the output window if desired
if (flags & StdOutToWindow) {
process.setStdOutBufferedSignalsEnabled(true);
if (flags & SilentStdOut) {
connect(&process, &SynchronousProcess::stdOutBuffered,
outputWindow, &VcsOutputWindow::appendSilently);
} else {
connect(&process, &SynchronousProcess::stdOutBuffered,
outputWindow, [](const QString &lines) {
VcsOutputWindow::append(lines);
});
}
if (flags & SilentStdOut)
process.setStdOutCallback(&VcsOutputWindow::appendSilently);
else
process.setStdOutCallback([](const QString &lines) { VcsOutputWindow::append(lines); });
}
process.setTimeOutMessageBoxEnabled(true);
const SynchronousProcessResponse sp_resp = process.run({m_settings.p4BinaryPath.value(), args});

View File

@@ -55,8 +55,8 @@ void MainWindow::test()
Utils::SynchronousProcess process;
process.setTimeoutS(2);
qDebug() << "Async: " << cmd << args;
connect(&process, &Utils::SynchronousProcess::stdOutBuffered, this, &MainWindow::append);
connect(&process, &Utils::SynchronousProcess::stdErrBuffered, this, &MainWindow::append);
const Utils::SynchronousProcessResponse resp = process.run({Utils::FilePath::fromString(cmd), args});
process.setStdOutCallback([this](const QString &s) { append(s); });
process.setStdErrCallback([this](const QString &s) { append(s); });
const Utils::SynchronousProcessResponse resp = process.run({cmd, args});
qDebug() << resp;
}