forked from qt-creator/qt-creator
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:
@@ -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
|
event loop that blocks only user input events. Thus, it allows for the GUI to
|
||||||
repaint and append output to log windows.
|
repaint and append output to log windows.
|
||||||
|
|
||||||
The stdOut(), stdErr() signals are emitted unbuffered as the process
|
The callbacks set with setStdOutCallBack(), setStdErrCallback() are called
|
||||||
writes them.
|
with complete lines based on the '\\n' marker.
|
||||||
|
|
||||||
The stdOutBuffered(), stdErrBuffered() signals are emitted with complete
|
|
||||||
lines based on the '\\n' marker if they are enabled using
|
|
||||||
stdOutBufferedSignalsEnabled()/setStdErrBufferedSignalsEnabled().
|
|
||||||
They would typically be used for log windows.
|
They would typically be used for log windows.
|
||||||
|
|
||||||
There is a timeout handling that takes effect after the last data have been
|
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)
|
// Data for one channel buffer (stderr/stdout)
|
||||||
class ChannelBuffer : public QObject
|
class ChannelBuffer : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void clearForRun();
|
void clearForRun();
|
||||||
|
|
||||||
@@ -1987,16 +1981,11 @@ public:
|
|||||||
QTextCodec *codec = nullptr; // Not owner
|
QTextCodec *codec = nullptr; // Not owner
|
||||||
std::unique_ptr<QTextCodec::ConverterState> codecState;
|
std::unique_ptr<QTextCodec::ConverterState> codecState;
|
||||||
int rawDataPos = 0;
|
int rawDataPos = 0;
|
||||||
bool bufferedSignalsEnabled = false;
|
std::function<void(const QString &lines)> outputCallback;
|
||||||
bool firstBuffer = true;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void outputBuffered(const QString &text, bool firstTime);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void ChannelBuffer::clearForRun()
|
void ChannelBuffer::clearForRun()
|
||||||
{
|
{
|
||||||
firstBuffer = true;
|
|
||||||
rawDataPos = 0;
|
rawDataPos = 0;
|
||||||
rawData.clear();
|
rawData.clear();
|
||||||
codecState.reset(new QTextCodec::ConverterState);
|
codecState.reset(new QTextCodec::ConverterState);
|
||||||
@@ -2035,12 +2024,10 @@ void ChannelBuffer::append(const QByteArray &text, bool emitSignals)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Buffered. Emit complete lines?
|
// Buffered. Emit complete lines?
|
||||||
if (bufferedSignalsEnabled) {
|
if (outputCallback) {
|
||||||
const QString lines = linesRead();
|
const QString lines = linesRead();
|
||||||
if (!lines.isEmpty()) {
|
if (!lines.isEmpty())
|
||||||
emit outputBuffered(lines, firstBuffer);
|
outputCallback(lines);
|
||||||
firstBuffer = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2098,8 +2085,6 @@ SynchronousProcess::SynchronousProcess() :
|
|||||||
d->m_hangTimerCount = 0;
|
d->m_hangTimerCount = 0;
|
||||||
processStdErr(true);
|
processStdErr(true);
|
||||||
});
|
});
|
||||||
connect(&d->m_stdOut, &ChannelBuffer::outputBuffered, this, &SynchronousProcess::stdOutBuffered);
|
|
||||||
connect(&d->m_stdErr, &ChannelBuffer::outputBuffered, this, &SynchronousProcess::stdErrBuffered);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SynchronousProcess::~SynchronousProcess()
|
SynchronousProcess::~SynchronousProcess()
|
||||||
@@ -2133,26 +2118,6 @@ QTextCodec *SynchronousProcess::codec() const
|
|||||||
return d->m_codec;
|
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
|
Environment SynchronousProcess::environment() const
|
||||||
{
|
{
|
||||||
return d->m_process.environment();
|
return d->m_process.environment();
|
||||||
@@ -2352,6 +2317,16 @@ SynchronousProcessResponse SynchronousProcess::runBlocking(const CommandLine &cm
|
|||||||
return d->m_result;
|
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()
|
bool SynchronousProcess::terminate()
|
||||||
{
|
{
|
||||||
return d->m_process.stopProcess();
|
return d->m_process.stopProcess();
|
||||||
@@ -2423,6 +2398,3 @@ void SynchronousProcess::processStdErr(bool emitSignals)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
#include "qtcprocess.moc"
|
|
||||||
|
|
||||||
|
|||||||
@@ -248,12 +248,6 @@ public:
|
|||||||
QProcess::ProcessChannelMode processChannelMode () const;
|
QProcess::ProcessChannelMode processChannelMode () const;
|
||||||
void setProcessChannelMode(QProcess::ProcessChannelMode m);
|
void setProcessChannelMode(QProcess::ProcessChannelMode m);
|
||||||
|
|
||||||
bool stdOutBufferedSignalsEnabled() const;
|
|
||||||
void setStdOutBufferedSignalsEnabled(bool);
|
|
||||||
|
|
||||||
bool stdErrBufferedSignalsEnabled() const;
|
|
||||||
void setStdErrBufferedSignalsEnabled(bool);
|
|
||||||
|
|
||||||
bool timeOutMessageBoxEnabled() const;
|
bool timeOutMessageBoxEnabled() const;
|
||||||
void setTimeOutMessageBoxEnabled(bool);
|
void setTimeOutMessageBoxEnabled(bool);
|
||||||
|
|
||||||
@@ -274,9 +268,8 @@ public:
|
|||||||
// Starts the command blocking the UI fully
|
// Starts the command blocking the UI fully
|
||||||
SynchronousProcessResponse runBlocking(const CommandLine &cmd);
|
SynchronousProcessResponse runBlocking(const CommandLine &cmd);
|
||||||
|
|
||||||
signals:
|
void setStdOutCallback(const std::function<void(const QString &)> &callback);
|
||||||
void stdOutBuffered(const QString &lines, bool firstTime);
|
void setStdErrCallback(const std::function<void(const QString &)> &callback);
|
||||||
void stdErrBuffered(const QString &lines, bool firstTime);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool terminate();
|
bool terminate();
|
||||||
|
|||||||
@@ -407,9 +407,7 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const CommandLine &cmd,
|
|||||||
if (d->m_flags & MergeOutputChannels) {
|
if (d->m_flags & MergeOutputChannels) {
|
||||||
process.setProcessChannelMode(QProcess::MergedChannels);
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
} else if (d->m_progressiveOutput || !(d->m_flags & SuppressStdErr)) {
|
} else if (d->m_progressiveOutput || !(d->m_flags & SuppressStdErr)) {
|
||||||
process.setStdErrBufferedSignalsEnabled(true);
|
process.setStdErrCallback([this, proxy](const QString &text) {
|
||||||
connect(&process, &SynchronousProcess::stdErrBuffered,
|
|
||||||
this, [this, proxy](const QString &text) {
|
|
||||||
if (d->m_progressParser)
|
if (d->m_progressParser)
|
||||||
d->m_progressParser->parseProgress(text);
|
d->m_progressParser->parseProgress(text);
|
||||||
if (!(d->m_flags & SuppressStdErr))
|
if (!(d->m_flags & SuppressStdErr))
|
||||||
@@ -421,9 +419,7 @@ SynchronousProcessResponse ShellCommand::runSynchronous(const CommandLine &cmd,
|
|||||||
|
|
||||||
// connect stdout to the output window if desired
|
// connect stdout to the output window if desired
|
||||||
if (d->m_progressParser || d->m_progressiveOutput || (d->m_flags & ShowStdOut)) {
|
if (d->m_progressParser || d->m_progressiveOutput || (d->m_flags & ShowStdOut)) {
|
||||||
process.setStdOutBufferedSignalsEnabled(true);
|
process.setStdOutCallback([this, proxy](const QString &text) {
|
||||||
connect(&process, &SynchronousProcess::stdOutBuffered,
|
|
||||||
this, [this, proxy](const QString &text) {
|
|
||||||
if (d->m_progressParser)
|
if (d->m_progressParser)
|
||||||
d->m_progressParser->parseProgress(text);
|
d->m_progressParser->parseProgress(text);
|
||||||
if (d->m_flags & ShowStdOut)
|
if (d->m_flags & ShowStdOut)
|
||||||
|
|||||||
@@ -174,18 +174,15 @@ static void sdkManagerCommand(const AndroidConfig &config, const QStringList &ar
|
|||||||
SynchronousProcess proc;
|
SynchronousProcess proc;
|
||||||
proc.setEnvironment(AndroidConfigurations::toolsEnvironment(config));
|
proc.setEnvironment(AndroidConfigurations::toolsEnvironment(config));
|
||||||
bool assertionFound = false;
|
bool assertionFound = false;
|
||||||
proc.setStdErrBufferedSignalsEnabled(true);
|
|
||||||
proc.setStdOutBufferedSignalsEnabled(true);
|
|
||||||
proc.setTimeoutS(timeout);
|
proc.setTimeoutS(timeout);
|
||||||
QObject::connect(&proc, &SynchronousProcess::stdOutBuffered,
|
proc.setStdOutCallback([offset, progressQuota, &proc, &assertionFound, &fi](const QString &out) {
|
||||||
[offset, progressQuota, &proc, &assertionFound, &fi](const QString &out) {
|
|
||||||
int progressPercent = parseProgress(out, assertionFound);
|
int progressPercent = parseProgress(out, assertionFound);
|
||||||
if (assertionFound)
|
if (assertionFound)
|
||||||
proc.terminate();
|
proc.terminate();
|
||||||
if (progressPercent != -1)
|
if (progressPercent != -1)
|
||||||
fi.setProgressValue(offset + qRound((progressPercent / 100.0) * progressQuota));
|
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;
|
output.stdError = err;
|
||||||
});
|
});
|
||||||
if (interruptible) {
|
if (interruptible) {
|
||||||
|
|||||||
@@ -1249,7 +1249,6 @@ PerforceResponse PerforcePluginPrivate::synchronousProcess(const QString &workin
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(stdInput.isEmpty(), return PerforceResponse()); // Not supported here
|
QTC_ASSERT(stdInput.isEmpty(), return PerforceResponse()); // Not supported here
|
||||||
|
|
||||||
VcsOutputWindow *outputWindow = VcsOutputWindow::instance();
|
|
||||||
// Run, connect stderr to the output window
|
// Run, connect stderr to the output window
|
||||||
SynchronousProcess process;
|
SynchronousProcess process;
|
||||||
const int timeOutS = (flags & LongTimeOut) ? m_settings.longTimeOutS() : m_settings.timeOutS.value();
|
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);
|
process.setWorkingDirectory(workingDir);
|
||||||
|
|
||||||
// connect stderr to the output window if desired
|
// connect stderr to the output window if desired
|
||||||
if (flags & StdErrToWindow) {
|
if (flags & StdErrToWindow)
|
||||||
process.setStdErrBufferedSignalsEnabled(true);
|
process.setStdErrCallback([](const QString &lines) { VcsOutputWindow::append(lines); });
|
||||||
connect(&process, &SynchronousProcess::stdErrBuffered,
|
|
||||||
outputWindow, [](const QString &lines) {
|
|
||||||
VcsOutputWindow::append(lines);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect stdout to the output window if desired
|
// connect stdout to the output window if desired
|
||||||
if (flags & StdOutToWindow) {
|
if (flags & StdOutToWindow) {
|
||||||
process.setStdOutBufferedSignalsEnabled(true);
|
if (flags & SilentStdOut)
|
||||||
if (flags & SilentStdOut) {
|
process.setStdOutCallback(&VcsOutputWindow::appendSilently);
|
||||||
connect(&process, &SynchronousProcess::stdOutBuffered,
|
else
|
||||||
outputWindow, &VcsOutputWindow::appendSilently);
|
process.setStdOutCallback([](const QString &lines) { VcsOutputWindow::append(lines); });
|
||||||
} else {
|
|
||||||
connect(&process, &SynchronousProcess::stdOutBuffered,
|
|
||||||
outputWindow, [](const QString &lines) {
|
|
||||||
VcsOutputWindow::append(lines);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
process.setTimeOutMessageBoxEnabled(true);
|
process.setTimeOutMessageBoxEnabled(true);
|
||||||
const SynchronousProcessResponse sp_resp = process.run({m_settings.p4BinaryPath.value(), args});
|
const SynchronousProcessResponse sp_resp = process.run({m_settings.p4BinaryPath.value(), args});
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ void MainWindow::test()
|
|||||||
Utils::SynchronousProcess process;
|
Utils::SynchronousProcess process;
|
||||||
process.setTimeoutS(2);
|
process.setTimeoutS(2);
|
||||||
qDebug() << "Async: " << cmd << args;
|
qDebug() << "Async: " << cmd << args;
|
||||||
connect(&process, &Utils::SynchronousProcess::stdOutBuffered, this, &MainWindow::append);
|
process.setStdOutCallback([this](const QString &s) { append(s); });
|
||||||
connect(&process, &Utils::SynchronousProcess::stdErrBuffered, this, &MainWindow::append);
|
process.setStdErrCallback([this](const QString &s) { append(s); });
|
||||||
const Utils::SynchronousProcessResponse resp = process.run({Utils::FilePath::fromString(cmd), args});
|
const Utils::SynchronousProcessResponse resp = process.run({cmd, args});
|
||||||
qDebug() << resp;
|
qDebug() << resp;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user