TaskTree: Unify TaskInterface::done(DoneResult) signal

Change the argument of TaskInterface::done() signal
from bool into DoneResult. Make it consistent with
other TaskTree API.

Introduce toDoneResult(bool success) helper.

Change-Id: I7b3041d7c1ed0317c76adbc1fd37448231e85f82
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2023-11-15 10:33:31 +01:00
parent 6f3bc431fc
commit 659f0f000c
39 changed files with 191 additions and 160 deletions

View File

@@ -35,18 +35,18 @@ void Barrier::advance()
return; return;
++m_current; ++m_current;
if (m_current == m_limit) if (m_current == m_limit)
stopWithResult(true); stopWithResult(DoneResult::Success);
} }
void Barrier::stopWithResult(bool success) void Barrier::stopWithResult(DoneResult result)
{ {
// Calling stopWithResult on finished is OK when the same success is passed // Calling stopWithResult on finished is OK when the same success is passed
QTC_ASSERT(isRunning() || (m_result && *m_result == success), return); QTC_ASSERT(isRunning() || (m_result && *m_result == result), return);
if (!isRunning()) // no-op if (!isRunning()) // no-op
return; return;
m_current = -1; m_current = -1;
m_result = success; m_result = result;
emit done(success); emit done(result);
} }
} // namespace Tasking } // namespace Tasking

View File

@@ -19,17 +19,17 @@ public:
void start(); void start();
void advance(); // If limit reached, stops with true void advance(); // If limit reached, stops with true
void stopWithResult(bool success); // Ignores limit void stopWithResult(DoneResult result); // Ignores limit
bool isRunning() const { return m_current >= 0; } bool isRunning() const { return m_current >= 0; }
int current() const { return m_current; } int current() const { return m_current; }
std::optional<bool> result() const { return m_result; } std::optional<DoneResult> result() const { return m_result; }
signals: signals:
void done(bool success); void done(DoneResult success);
private: private:
std::optional<bool> m_result = {}; std::optional<DoneResult> m_result = {};
int m_limit = 1; int m_limit = 1;
int m_current = -1; int m_current = -1;
}; };
@@ -80,9 +80,11 @@ GroupItem waitForBarrierTask(const MultiBarrier<Limit> &sharedBarrier)
return SetupResult::StopWithError; return SetupResult::StopWithError;
} }
Barrier *activeSharedBarrier = activeBarrier->barrier(); Barrier *activeSharedBarrier = activeBarrier->barrier();
const std::optional<bool> result = activeSharedBarrier->result(); const std::optional<DoneResult> result = activeSharedBarrier->result();
if (result.has_value()) if (result.has_value()) {
return result.value() ? SetupResult::StopWithSuccess : SetupResult::StopWithError; return result.value() == DoneResult::Success ? SetupResult::StopWithSuccess
: SetupResult::StopWithError;
}
QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult); QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult);
return SetupResult::Continue; return SetupResult::Continue;
}); });

View File

@@ -78,12 +78,12 @@ public:
void start() { void start() {
if (!this->task()->m_startHandler) { if (!this->task()->m_startHandler) {
emit this->done(false); // TODO: Add runtime assert emit this->done(DoneResult::Error); // TODO: Add runtime assert
return; return;
} }
m_watcher.reset(new QFutureWatcher<ResultType>); m_watcher.reset(new QFutureWatcher<ResultType>);
this->connect(m_watcher.get(), &QFutureWatcherBase::finished, this, [this] { this->connect(m_watcher.get(), &QFutureWatcherBase::finished, this, [this] {
emit this->done(!m_watcher->isCanceled()); emit this->done(toDoneResult(!m_watcher->isCanceled()));
m_watcher.release()->deleteLater(); m_watcher.release()->deleteLater();
}); });
this->task()->m_future = this->task()->m_startHandler(); this->task()->m_future = this->task()->m_startHandler();

View File

@@ -16,13 +16,13 @@ void NetworkQuery::start()
if (!m_manager) { if (!m_manager) {
qWarning("Can't start the NetworkQuery without the QNetworkAccessManager. " qWarning("Can't start the NetworkQuery without the QNetworkAccessManager. "
"Stopping with an error."); "Stopping with an error.");
emit done(false); emit done(DoneResult::Error);
return; return;
} }
m_reply.reset(m_manager->get(m_request)); m_reply.reset(m_manager->get(m_request));
connect(m_reply.get(), &QNetworkReply::finished, this, [this] { connect(m_reply.get(), &QNetworkReply::finished, this, [this] {
disconnect(m_reply.get(), nullptr, this, nullptr); disconnect(m_reply.get(), nullptr, this, nullptr);
emit done(m_reply->error() == QNetworkReply::NoError); emit done(toDoneResult(m_reply->error() == QNetworkReply::NoError));
m_reply.release()->deleteLater(); m_reply.release()->deleteLater();
}); });
if (m_reply->isRunning()) if (m_reply->isRunning())

View File

@@ -35,7 +35,7 @@ public:
signals: signals:
void started(); void started();
void done(bool success); void done(DoneResult result);
private: private:
QNetworkRequest m_request; QNetworkRequest m_request;

View File

@@ -50,12 +50,12 @@ private:
const bool success = task()->exitStatus() == QProcess::NormalExit const bool success = task()->exitStatus() == QProcess::NormalExit
&& task()->error() == QProcess::UnknownError && task()->error() == QProcess::UnknownError
&& task()->exitCode() == 0; && task()->exitCode() == 0;
emit done(success); emit done(toDoneResult(success));
}); });
connect(task(), &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) { connect(task(), &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
if (error != QProcess::FailedToStart) if (error != QProcess::FailedToStart)
return; return;
emit done(false); emit done(DoneResult::Error);
}); });
task()->start(); task()->start();
} }

View File

@@ -836,6 +836,11 @@ const GroupItem stopOnSuccessOrError = workflowPolicy(WorkflowPolicy::StopOnSucc
const GroupItem finishAllAndSuccess = workflowPolicy(WorkflowPolicy::FinishAllAndSuccess); const GroupItem finishAllAndSuccess = workflowPolicy(WorkflowPolicy::FinishAllAndSuccess);
const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError); const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError);
DoneResult toDoneResult(bool success)
{
return success ? DoneResult::Success : DoneResult::Error;
}
static SetupResult toSetupResult(bool success) static SetupResult toSetupResult(bool success)
{ {
return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError; return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError;
@@ -846,6 +851,11 @@ static DoneResult toDoneResult(DoneWith doneWith)
return doneWith == DoneWith::Success ? DoneResult::Success : DoneResult::Error; return doneWith == DoneWith::Success ? DoneResult::Success : DoneResult::Error;
} }
static DoneWith toDoneWith(DoneResult result)
{
return result == DoneResult::Success ? DoneWith::Success : DoneWith::Error;
}
class StorageThreadData class StorageThreadData
{ {
Q_DISABLE_COPY_MOVE(StorageThreadData) Q_DISABLE_COPY_MOVE(StorageThreadData)
@@ -1548,8 +1558,8 @@ SetupResult TaskTreePrivate::start(TaskRuntimeNode *node)
const std::shared_ptr<SetupResult> unwindAction const std::shared_ptr<SetupResult> unwindAction
= std::make_shared<SetupResult>(SetupResult::Continue); = std::make_shared<SetupResult>(SetupResult::Continue);
QObject::connect(node->m_task.get(), &TaskInterface::done, QObject::connect(node->m_task.get(), &TaskInterface::done,
q, [this, node, unwindAction](bool success) { q, [this, node, unwindAction](DoneResult doneResult) {
const bool result = invokeDoneHandler(node, success ? DoneWith::Success : DoneWith::Error); const bool result = invokeDoneHandler(node, toDoneWith(doneResult));
QObject::disconnect(node->m_task.get(), &TaskInterface::done, q, nullptr); QObject::disconnect(node->m_task.get(), &TaskInterface::done, q, nullptr);
node->m_task.release()->deleteLater(); node->m_task.release()->deleteLater();
TaskRuntimeContainer *parentContainer = node->m_parentContainer; TaskRuntimeContainer *parentContainer = node->m_parentContainer;
@@ -2650,7 +2660,7 @@ void TaskTree::setupStorageHandler(const TreeStorageBase &storage,
TaskTreeTaskAdapter::TaskTreeTaskAdapter() TaskTreeTaskAdapter::TaskTreeTaskAdapter()
{ {
connect(task(), &TaskTree::done, this, connect(task(), &TaskTree::done, this,
[this](DoneWith result) { emit done(result == DoneWith::Success); }); [this](DoneWith result) { emit done(toDoneResult(result)); });
} }
void TaskTreeTaskAdapter::start() void TaskTreeTaskAdapter::start()
@@ -2743,7 +2753,10 @@ TimeoutTaskAdapter::~TimeoutTaskAdapter()
void TimeoutTaskAdapter::start() void TimeoutTaskAdapter::start()
{ {
m_timerId = scheduleTimeout(*task(), this, [this] { m_timerId = {}; emit done(true); }); m_timerId = scheduleTimeout(*task(), this, [this] {
m_timerId = {};
emit done(DoneResult::Success);
});
} }
} // namespace Tasking } // namespace Tasking

View File

@@ -19,6 +19,63 @@ namespace Tasking {
Q_NAMESPACE_EXPORT(TASKING_EXPORT) Q_NAMESPACE_EXPORT(TASKING_EXPORT)
// WorkflowPolicy:
// 1. When all children finished with success -> report success, otherwise:
// a) Report error on first error and stop executing other children (including their subtree).
// b) On first error - continue executing all children and report error afterwards.
// 2. When all children finished with error -> report error, otherwise:
// a) Report success on first success and stop executing other children (including their subtree).
// b) On first success - continue executing all children and report success afterwards.
// 3. Stops on first finished child. In sequential mode it will never run other children then the first one.
// Useful only in parallel mode.
// 4. Always run all children, let them finish, ignore their results and report success afterwards.
// 5. Always run all children, let them finish, ignore their results and report error afterwards.
enum class WorkflowPolicy
{
StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success).
ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children.
StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error).
ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children.
StopOnSuccessOrError, // 3 - Stops on first finished child and report its result.
FinishAllAndSuccess, // 4 - Reports success after all children finished.
FinishAllAndError // 5 - Reports error after all children finished.
};
Q_ENUM_NS(WorkflowPolicy);
enum class SetupResult
{
Continue,
StopWithSuccess,
StopWithError
};
Q_ENUM_NS(SetupResult);
enum class DoneResult
{
Success,
Error
};
Q_ENUM_NS(DoneResult);
enum class DoneWith
{
Success,
Error,
Cancel
};
Q_ENUM_NS(DoneWith);
enum class CallDoneIf
{
SuccessOrError,
Success,
Error
};
Q_ENUM_NS(CallDoneIf);
TASKING_EXPORT DoneResult toDoneResult(bool success);
class StorageData; class StorageData;
class TaskTreePrivate; class TaskTreePrivate;
@@ -27,7 +84,7 @@ class TASKING_EXPORT TaskInterface : public QObject
Q_OBJECT Q_OBJECT
signals: signals:
void done(bool success); void done(DoneResult result);
private: private:
template <typename Task, typename Deleter> friend class TaskAdapter; template <typename Task, typename Deleter> friend class TaskAdapter;
@@ -88,61 +145,6 @@ private:
} }
}; };
// WorkflowPolicy:
// 1. When all children finished with success -> report success, otherwise:
// a) Report error on first error and stop executing other children (including their subtree).
// b) On first error - continue executing all children and report error afterwards.
// 2. When all children finished with error -> report error, otherwise:
// a) Report success on first success and stop executing other children (including their subtree).
// b) On first success - continue executing all children and report success afterwards.
// 3. Stops on first finished child. In sequential mode it will never run other children then the first one.
// Useful only in parallel mode.
// 4. Always run all children, let them finish, ignore their results and report success afterwards.
// 5. Always run all children, let them finish, ignore their results and report error afterwards.
enum class WorkflowPolicy
{
StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success).
ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children.
StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error).
ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children.
StopOnSuccessOrError, // 3 - Stops on first finished child and report its result.
FinishAllAndSuccess, // 4 - Reports success after all children finished.
FinishAllAndError // 5 - Reports error after all children finished.
};
Q_ENUM_NS(WorkflowPolicy);
enum class SetupResult
{
Continue,
StopWithSuccess,
StopWithError
};
Q_ENUM_NS(SetupResult);
enum class DoneResult
{
Success,
Error
};
Q_ENUM_NS(DoneResult);
enum class DoneWith
{
Success,
Error,
Cancel
};
Q_ENUM_NS(DoneWith);
enum class CallDoneIf
{
SuccessOrError,
Success,
Error
};
Q_ENUM_NS(CallDoneIf);
class TASKING_EXPORT GroupItem class TASKING_EXPORT GroupItem
{ {
public: public:

View File

@@ -204,7 +204,7 @@ class AsyncTaskAdapter : public Tasking::TaskAdapter<Async<ResultType>>
public: public:
AsyncTaskAdapter() { AsyncTaskAdapter() {
this->connect(this->task(), &AsyncBase::done, this, [this] { this->connect(this->task(), &AsyncBase::done, this, [this] {
emit this->done(!this->task()->isCanceled()); emit this->done(Tasking::toDoneResult(!this->task()->isCanceled()));
}); });
} }
void start() final { this->task()->start(); } void start() final { this->task()->start(); }

View File

@@ -34,13 +34,13 @@ public:
m_taskTree.reset(new TaskTree({task})); m_taskTree.reset(new TaskTree({task}));
connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) {
m_taskTree.release()->deleteLater(); m_taskTree.release()->deleteLater();
emit done(result == DoneWith::Success); emit done(toDoneResult(result == DoneWith::Success));
}); });
m_taskTree->start(); m_taskTree->start();
} }
signals: signals:
void done(bool success); void done(DoneResult result);
protected: protected:
FilePath m_filePath; FilePath m_filePath;
@@ -381,7 +381,7 @@ public:
FilePath m_destination; FilePath m_destination;
QByteArray m_readBuffer; QByteArray m_readBuffer;
QByteArray m_writeBuffer; QByteArray m_writeBuffer;
StreamResult m_streamResult = StreamResult::FinishedWithError; DoneResult m_streamResult = DoneResult::Error;
std::unique_ptr<TaskTree> m_taskTree; std::unique_ptr<TaskTree> m_taskTree;
GroupItem task() { GroupItem task() {
@@ -454,7 +454,7 @@ void FileStreamer::setWriteData(const QByteArray &writeData)
d->m_writeBuffer = writeData; d->m_writeBuffer = writeData;
} }
StreamResult FileStreamer::result() const DoneResult FileStreamer::result() const
{ {
return d->m_streamResult; return d->m_streamResult;
} }
@@ -465,8 +465,7 @@ void FileStreamer::start()
QTC_ASSERT(!d->m_taskTree, return); QTC_ASSERT(!d->m_taskTree, return);
d->m_taskTree.reset(new TaskTree({d->task()})); d->m_taskTree.reset(new TaskTree({d->task()}));
connect(d->m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { connect(d->m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) {
d->m_streamResult = result == DoneWith::Success ? StreamResult::FinishedWithSuccess d->m_streamResult = toDoneResult(result == DoneWith::Success);
: StreamResult::FinishedWithError;
d->m_taskTree.release()->deleteLater(); d->m_taskTree.release()->deleteLater();
emit done(); emit done();
}); });

View File

@@ -19,8 +19,6 @@ namespace Utils {
enum class StreamMode { Reader, Writer, Transfer }; enum class StreamMode { Reader, Writer, Transfer };
enum class StreamResult { FinishedWithSuccess, FinishedWithError };
class QTCREATOR_UTILS_EXPORT FileStreamer final : public QObject class QTCREATOR_UTILS_EXPORT FileStreamer final : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -38,7 +36,7 @@ public:
// Only for Writer mode // Only for Writer mode
void setWriteData(const QByteArray &writeData); void setWriteData(const QByteArray &writeData);
StreamResult result() const; Tasking::DoneResult result() const;
void start(); void start();
void stop(); void stop();
@@ -53,8 +51,9 @@ private:
class FileStreamerTaskAdapter : public Tasking::TaskAdapter<FileStreamer> class FileStreamerTaskAdapter : public Tasking::TaskAdapter<FileStreamer>
{ {
public: public:
FileStreamerTaskAdapter() { connect(task(), &FileStreamer::done, this, FileStreamerTaskAdapter() {
[this] { emit done(task()->result() == StreamResult::FinishedWithSuccess); }); } connect(task(), &FileStreamer::done, this, [this] { emit done(task()->result()); });
}
void start() override { task()->start(); } void start() override { task()->start(); }
}; };

View File

@@ -129,7 +129,7 @@ FileStreamHandle FileStreamerManager::copy(const FilePath &source, const FilePat
return execute(onSetup, {}, context); return execute(onSetup, {}, context);
const auto onDone = [=](FileStreamer *streamer) { const auto onDone = [=](FileStreamer *streamer) {
if (streamer->result() == StreamResult::FinishedWithSuccess) if (streamer->result() == Tasking::DoneResult::Success)
cont({}); cont({});
else else
cont(make_unexpected(Tr::tr("Failed copying file."))); cont(make_unexpected(Tr::tr("Failed copying file.")));
@@ -153,7 +153,7 @@ FileStreamHandle FileStreamerManager::read(const FilePath &source, QObject *cont
return execute(onSetup, {}, context); return execute(onSetup, {}, context);
const auto onDone = [=](FileStreamer *streamer) { const auto onDone = [=](FileStreamer *streamer) {
if (streamer->result() == StreamResult::FinishedWithSuccess) if (streamer->result() == Tasking::DoneResult::Success)
cont(streamer->readData()); cont(streamer->readData());
else else
cont(make_unexpected(Tr::tr("Failed reading file."))); cont(make_unexpected(Tr::tr("Failed reading file.")));
@@ -179,7 +179,7 @@ FileStreamHandle FileStreamerManager::write(const FilePath &destination, const Q
return execute(onSetup, {}, context); return execute(onSetup, {}, context);
const auto onDone = [=](FileStreamer *streamer) { const auto onDone = [=](FileStreamer *streamer) {
if (streamer->result() == StreamResult::FinishedWithSuccess) if (streamer->result() == Tasking::DoneResult::Success)
cont(0); // TODO: return write count? cont(0); // TODO: return write count?
else else
cont(make_unexpected(Tr::tr("Failed writing file."))); cont(make_unexpected(Tr::tr("Failed writing file.")));

View File

@@ -2160,7 +2160,7 @@ void ProcessPrivate::storeEventLoopDebugInfo(const QVariant &value)
ProcessTaskAdapter::ProcessTaskAdapter() ProcessTaskAdapter::ProcessTaskAdapter()
{ {
connect(task(), &Process::done, this, [this] { connect(task(), &Process::done, this, [this] {
emit done(task()->result() == ProcessResult::FinishedWithSuccess); emit done(Tasking::toDoneResult(task()->result() == ProcessResult::FinishedWithSuccess));
}); });
} }

View File

@@ -10,6 +10,8 @@
#include <QSettings> #include <QSettings>
using namespace Tasking;
namespace Utils { namespace Utils {
namespace { namespace {
@@ -128,16 +130,16 @@ static CommandLine unarchiveCommand(const CommandLine &commandTemplate, const Fi
void Unarchiver::start() void Unarchiver::start()
{ {
QTC_ASSERT(!m_process, emit done(false); return); QTC_ASSERT(!m_process, emit done(DoneResult::Error); return);
if (!m_sourceAndCommand) { if (!m_sourceAndCommand) {
emit outputReceived(Tr::tr("No source file set.")); emit outputReceived(Tr::tr("No source file set."));
emit done(false); emit done(DoneResult::Error);
return; return;
} }
if (m_destDir.isEmpty()) { if (m_destDir.isEmpty()) {
emit outputReceived(Tr::tr("No destination directory set.")); emit outputReceived(Tr::tr("No destination directory set."));
emit done(false); emit done(DoneResult::Error);
return; return;
} }
@@ -154,7 +156,7 @@ void Unarchiver::start()
const bool success = m_process->result() == ProcessResult::FinishedWithSuccess; const bool success = m_process->result() == ProcessResult::FinishedWithSuccess;
if (!success) if (!success)
emit outputReceived(Tr::tr("Command failed.")); emit outputReceived(Tr::tr("Command failed."));
emit done(success); emit done(toDoneResult(success));
}); });
emit outputReceived(Tr::tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>") emit outputReceived(Tr::tr("Running %1\nin \"%2\".\n\n", "Running <cmd> in <workingdirectory>")
@@ -167,7 +169,7 @@ void Unarchiver::start()
UnarchiverTaskAdapter::UnarchiverTaskAdapter() UnarchiverTaskAdapter::UnarchiverTaskAdapter()
{ {
connect(task(), &Unarchiver::done, this, &Tasking::TaskInterface::done); connect(task(), &Unarchiver::done, this, &TaskInterface::done);
} }
void UnarchiverTaskAdapter::start() void UnarchiverTaskAdapter::start()

View File

@@ -37,7 +37,7 @@ public:
signals: signals:
void outputReceived(const QString &output); void outputReceived(const QString &output);
void done(bool success); void done(Tasking::DoneResult result);
private: private:
std::optional<SourceAndCommand> m_sourceAndCommand; std::optional<SourceAndCommand> m_sourceAndCommand;

View File

@@ -75,11 +75,13 @@ class ProjectBuilderTaskAdapter : public TaskAdapter<QPointer<RunControl>>
public: public:
void start() final { void start() final {
connect(BuildManager::instance(), &BuildManager::buildQueueFinished, connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
this, &TaskInterface::done); this, [this](bool success) {
emit done(toDoneResult(success));
});
RunControl *runControl = *task(); RunControl *runControl = *task();
QTC_ASSERT(runControl, emit done(false); return); QTC_ASSERT(runControl, emit done(DoneResult::Error); return);
Target *target = runControl->target(); Target *target = runControl->target();
QTC_ASSERT(target, emit done(false); return); QTC_ASSERT(target, emit done(DoneResult::Error); return);
if (!BuildManager::isBuilding(target)) { if (!BuildManager::isBuilding(target)) {
BuildManager::buildProjectWithDependencies(target->project(), ConfigSelection::Active, BuildManager::buildProjectWithDependencies(target->project(), ConfigSelection::Active,
runControl); runControl);
@@ -822,7 +824,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings,
}; };
topTasks.append(Group { topTasks.append(Group {
Tasking::Storage(storage), Storage(storage),
TaskTreeTask(onTreeSetup, onTreeDone, CallDoneIf::Success) TaskTreeTask(onTreeSetup, onTreeDone, CallDoneIf::Success)
}); });
return {topTasks}; return {topTasks};

View File

@@ -68,10 +68,12 @@ public:
void start() final { void start() final {
Target *target = *task(); Target *target = *task();
if (!target) { if (!target) {
emit done(false); emit done(DoneResult::Error);
return; return;
} }
connect(target, &Target::parsingFinished, this, &TaskInterface::done); connect(target, &Target::parsingFinished, this, [this](bool success) {
emit done(toDoneResult(success));
});
} }
}; };

View File

@@ -322,7 +322,7 @@ class ResultsCollectorTaskAdapter : public TaskAdapter<ResultsCollector>
{ {
public: public:
ResultsCollectorTaskAdapter() { ResultsCollectorTaskAdapter() {
connect(task(), &ResultsCollector::done, this, [this] { emit done(true); }); connect(task(), &ResultsCollector::done, this, [this] { emit done(DoneResult::Success); });
} }
void start() final { task()->start(); } void start() final { task()->start(); }
}; };

View File

@@ -305,7 +305,7 @@ public:
m_timer.reset(); m_timer.reset();
m_output = output; m_output = output;
m_id = {}; m_id = {};
emit done(output.m_result == JavaScriptResult::FinishedWithSuccess); emit done(toDoneResult(output.m_result == JavaScriptResult::FinishedWithSuccess));
}; };
m_id = m_engine->addRequest(input); m_id = m_engine->addRequest(input);
if (m_timeout > 0ms) { if (m_timeout > 0ms) {
@@ -318,7 +318,7 @@ public:
m_timer.release()->deleteLater(); m_timer.release()->deleteLater();
m_id = {}; m_id = {};
m_output = {Tr::tr("Engine aborted after timeout."), JavaScriptResult::Canceled}; m_output = {Tr::tr("Engine aborted after timeout."), JavaScriptResult::Canceled};
emit done(false); emit done(DoneResult::Error);
}); });
m_timer->start(); m_timer->start();
} }
@@ -328,7 +328,7 @@ public:
JavaScriptOutput output() const { return m_output; } JavaScriptOutput output() const { return m_output; }
signals: signals:
void done(bool success); void done(DoneResult result);
private: private:
QPointer<JavaScriptEngine> m_engine; QPointer<JavaScriptEngine> m_engine;

View File

@@ -41,7 +41,7 @@ public:
void setExpectSuccess(bool success) { m_expectSuccess = success; } void setExpectSuccess(bool success) { m_expectSuccess = success; }
void start() void start()
{ {
QTC_ASSERT(m_deviceType, emit done(false); return); QTC_ASSERT(m_deviceType, emit done(DoneResult::Error); return);
QTC_ASSERT(!m_toolHandler, return); QTC_ASSERT(!m_toolHandler, return);
m_toolHandler.reset(new IosToolHandler(*m_deviceType)); m_toolHandler.reset(new IosToolHandler(*m_deviceType));
@@ -65,19 +65,19 @@ public:
TaskHub::addTask(DeploymentTask(Task::Error, Tr::tr("Deployment failed. " TaskHub::addTask(DeploymentTask(Task::Error, Tr::tr("Deployment failed. "
"The settings in the Devices window of Xcode might be incorrect."))); "The settings in the Devices window of Xcode might be incorrect.")));
} }
emit done(status == IosToolHandler::Success); emit done(toDoneResult(status == IosToolHandler::Success));
}); });
connect(m_toolHandler.get(), &IosToolHandler::finished, this, [this] { connect(m_toolHandler.get(), &IosToolHandler::finished, this, [this] {
disconnect(m_toolHandler.get(), nullptr, this, nullptr); disconnect(m_toolHandler.get(), nullptr, this, nullptr);
m_toolHandler.release()->deleteLater(); m_toolHandler.release()->deleteLater();
TaskHub::addTask(DeploymentTask(Task::Error, Tr::tr("Deployment failed."))); TaskHub::addTask(DeploymentTask(Task::Error, Tr::tr("Deployment failed.")));
emit done(false); emit done(DoneResult::Error);
}); });
m_toolHandler->requestTransferApp(m_bundlePath, m_deviceType->identifier); m_toolHandler->requestTransferApp(m_bundlePath, m_deviceType->identifier);
} }
signals: signals:
void done(bool success); void done(DoneResult result);
void progressValueChanged(int progress, const QString &info); // progress in % void progressValueChanged(int progress, const QString &info); // progress in %
void errorMessage(const QString &message); void errorMessage(const QString &message);

View File

@@ -4,13 +4,14 @@
#include "clientrequest.h" #include "clientrequest.h"
using namespace LanguageServerProtocol; using namespace LanguageServerProtocol;
using namespace Tasking;
namespace LanguageClient { namespace LanguageClient {
ClientWorkspaceSymbolRequestTaskAdapter::ClientWorkspaceSymbolRequestTaskAdapter() ClientWorkspaceSymbolRequestTaskAdapter::ClientWorkspaceSymbolRequestTaskAdapter()
{ {
task()->setResponseCallback([this](const WorkspaceSymbolRequest::Response &response){ task()->setResponseCallback([this](const WorkspaceSymbolRequest::Response &response){
emit done(response.result().has_value()); emit done(toDoneResult(response.result().has_value()));
}); });
} }

View File

@@ -10,6 +10,7 @@
using namespace Core; using namespace Core;
using namespace LanguageServerProtocol; using namespace LanguageServerProtocol;
using namespace Tasking;
using namespace TextEditor; using namespace TextEditor;
using namespace Utils; using namespace Utils;
@@ -24,7 +25,7 @@ void CurrentDocumentSymbolsRequest::start()
TextDocument *document = TextDocument::currentTextDocument(); TextDocument *document = TextDocument::currentTextDocument();
Client *client = LanguageClientManager::clientForDocument(document); Client *client = LanguageClientManager::clientForDocument(document);
if (!client) { if (!client) {
emit done(false); emit done(DoneResult::Error);
return; return;
} }
@@ -34,7 +35,7 @@ void CurrentDocumentSymbolsRequest::start()
const auto reportFailure = [this] { const auto reportFailure = [this] {
clearConnections(); clearConnections();
emit done(false); emit done(DoneResult::Error);
}; };
const auto updateSymbols = [this, currentUri, pathMapper](const DocumentUri &uri, const auto updateSymbols = [this, currentUri, pathMapper](const DocumentUri &uri,
@@ -46,7 +47,7 @@ void CurrentDocumentSymbolsRequest::start()
const FilePath filePath = pathMapper ? currentUri.toFilePath(pathMapper) : FilePath(); const FilePath filePath = pathMapper ? currentUri.toFilePath(pathMapper) : FilePath();
m_currentDocumentSymbolsData = {filePath, pathMapper, symbols}; m_currentDocumentSymbolsData = {filePath, pathMapper, symbols};
clearConnections(); clearConnections();
emit done(true); emit done(DoneResult::Success);
}; };
m_connections.append(connect(EditorManager::instance(), &EditorManager::currentEditorChanged, m_connections.append(connect(EditorManager::instance(), &EditorManager::currentEditorChanged,

View File

@@ -30,7 +30,7 @@ public:
CurrentDocumentSymbolsData currentDocumentSymbolsData() const { return m_currentDocumentSymbolsData; } CurrentDocumentSymbolsData currentDocumentSymbolsData() const { return m_currentDocumentSymbolsData; }
signals: signals:
void done(bool success); void done(Tasking::DoneResult result);
private: private:
void clearConnections(); void clearConnections();

View File

@@ -67,14 +67,14 @@ private:
this, [this, buildSystem](bool success) { this, [this, buildSystem](bool success) {
disconnect(buildSystem, &BuildSystem::parsingFinished, this, nullptr); disconnect(buildSystem, &BuildSystem::parsingFinished, this, nullptr);
if (!success) { if (!success) {
emit done(false); emit done(DoneResult::Error);
return; return;
} }
checkParsing(); checkParsing();
}); });
return; return;
} }
emit done(true); emit done(DoneResult::Success);
} }
}; };

View File

@@ -11,6 +11,8 @@
#include <utils/portlist.h> #include <utils/portlist.h>
using namespace Tasking;
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
@@ -45,12 +47,12 @@ private:
}; };
class PROJECTEXPLORER_EXPORT DeviceUsedPortsGathererTaskAdapter class PROJECTEXPLORER_EXPORT DeviceUsedPortsGathererTaskAdapter
: public Tasking::TaskAdapter<DeviceUsedPortsGatherer> : public TaskAdapter<DeviceUsedPortsGatherer>
{ {
public: public:
DeviceUsedPortsGathererTaskAdapter() { DeviceUsedPortsGathererTaskAdapter() {
connect(task(), &DeviceUsedPortsGatherer::portListReady, this, [this] { emit done(true); }); connect(task(), &DeviceUsedPortsGatherer::portListReady, this, [this] { emit done(DoneResult::Success); });
connect(task(), &DeviceUsedPortsGatherer::error, this, [this] { emit done(false); }); connect(task(), &DeviceUsedPortsGatherer::error, this, [this] { emit done(DoneResult::Error); });
} }
void start() final { task()->start(); } void start() final { task()->start(); }
}; };
@@ -87,6 +89,6 @@ private:
QVector<Internal::SubChannelProvider *> m_channelProviders; QVector<Internal::SubChannelProvider *> m_channelProviders;
}; };
using DeviceUsedPortsGathererTask = Tasking::CustomTask<DeviceUsedPortsGathererTaskAdapter>; using DeviceUsedPortsGathererTask = CustomTask<DeviceUsedPortsGathererTaskAdapter>;
} // namespace ProjectExplorer } // namespace ProjectExplorer

View File

@@ -196,9 +196,10 @@ QString FileTransfer::transferMethodName(FileTransferMethod method)
FileTransferTaskAdapter::FileTransferTaskAdapter() FileTransferTaskAdapter::FileTransferTaskAdapter()
{ {
connect(task(), &FileTransfer::done, this, [this](const ProcessResultData &result) { connect(task(), &FileTransfer::done, this, [this](const ProcessResultData &result) {
emit done(result.m_exitStatus == QProcess::NormalExit const bool success = result.m_exitStatus == QProcess::NormalExit
&& result.m_error == QProcess::UnknownError && result.m_error == QProcess::UnknownError
&& result.m_exitCode == 0); && result.m_exitCode == 0;
emit done(Tasking::toDoneResult(success));
}); });
} }

View File

@@ -5,7 +5,6 @@
#include "devicemanager.h" #include "devicemanager.h"
#include "idevicefactory.h" #include "idevicefactory.h"
#include "processlist.h"
#include "sshparameters.h" #include "sshparameters.h"
#include "../kit.h" #include "../kit.h"
@@ -710,6 +709,8 @@ void DeviceProcessSignalOperation::setDebuggerCommand(const FilePath &cmd)
DeviceProcessSignalOperation::DeviceProcessSignalOperation() = default; DeviceProcessSignalOperation::DeviceProcessSignalOperation() = default;
using namespace Tasking;
void DeviceProcessKiller::start() void DeviceProcessKiller::start()
{ {
m_signalOperation.reset(); m_signalOperation.reset();
@@ -718,7 +719,7 @@ void DeviceProcessKiller::start()
const IDevice::ConstPtr device = DeviceManager::deviceForPath(m_processPath); const IDevice::ConstPtr device = DeviceManager::deviceForPath(m_processPath);
if (!device) { if (!device) {
m_errorString = Tr::tr("No device for given path: \"%1\".").arg(m_processPath.toUserOutput()); m_errorString = Tr::tr("No device for given path: \"%1\".").arg(m_processPath.toUserOutput());
emit done(false); emit done(DoneResult::Error);
return; return;
} }
@@ -726,14 +727,14 @@ void DeviceProcessKiller::start()
if (!m_signalOperation) { if (!m_signalOperation) {
m_errorString = Tr::tr("Device for path \"%1\" does not support killing processes.") m_errorString = Tr::tr("Device for path \"%1\" does not support killing processes.")
.arg(m_processPath.toUserOutput()); .arg(m_processPath.toUserOutput());
emit done(false); emit done(DoneResult::Error);
return; return;
} }
connect(m_signalOperation.get(), &DeviceProcessSignalOperation::finished, connect(m_signalOperation.get(), &DeviceProcessSignalOperation::finished,
this, [this](const QString &errorMessage) { this, [this](const QString &errorMessage) {
m_errorString = errorMessage; m_errorString = errorMessage;
emit done(m_errorString.isEmpty()); emit done(toDoneResult(m_errorString.isEmpty()));
}); });
m_signalOperation->killProcess(m_processPath.path()); m_signalOperation->killProcess(m_processPath.path());

View File

@@ -279,7 +279,7 @@ public:
QString errorString() const { return m_errorString; } QString errorString() const { return m_errorString; }
signals: signals:
void done(bool success); void done(Tasking::DoneResult result);
private: private:
Utils::FilePath m_processPath; Utils::FilePath m_processPath;

View File

@@ -13,6 +13,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Tasking;
using namespace Utils; using namespace Utils;
namespace QbsProjectManager::Internal { namespace QbsProjectManager::Internal {
@@ -40,7 +41,7 @@ public:
void cancel(); void cancel();
signals: signals:
void done(bool success); void done(DoneResult result);
void progressChanged(int progress, const QString &info); // progress in % void progressChanged(int progress, const QString &info); // progress in %
void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format); void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format);
void taskAdded(const ProjectExplorer::Task &task); void taskAdded(const ProjectExplorer::Task &task);
@@ -114,7 +115,7 @@ void QbsRequestObject::start()
if (m_parseData) { if (m_parseData) {
connect(m_parseData->target(), &Target::parsingFinished, this, [this](bool success) { connect(m_parseData->target(), &Target::parsingFinished, this, [this](bool success) {
disconnect(m_parseData->target(), &Target::parsingFinished, this, nullptr); disconnect(m_parseData->target(), &Target::parsingFinished, this, nullptr);
emit done(success); emit done(toDoneResult(success));
}); });
QMetaObject::invokeMethod(m_parseData.get(), &QbsBuildSystem::startParsing, QMetaObject::invokeMethod(m_parseData.get(), &QbsBuildSystem::startParsing,
Qt::QueuedConnection); Qt::QueuedConnection);
@@ -127,7 +128,7 @@ void QbsRequestObject::start()
emit outputAdded(item.description, BuildStep::OutputFormat::Stdout); emit outputAdded(item.description, BuildStep::OutputFormat::Stdout);
emit taskAdded(CompileTask(Task::Error, item.description, item.filePath, item.line)); emit taskAdded(CompileTask(Task::Error, item.description, item.filePath, item.line));
} }
emit done(error.items.isEmpty()); emit done(toDoneResult(error.items.isEmpty()));
}; };
connect(m_session, &QbsSession::projectBuilt, this, handleDone); connect(m_session, &QbsSession::projectBuilt, this, handleDone);
connect(m_session, &QbsSession::projectCleaned, this, handleDone); connect(m_session, &QbsSession::projectCleaned, this, handleDone);
@@ -188,7 +189,7 @@ QbsRequest::~QbsRequest()
void QbsRequest::start() void QbsRequest::start()
{ {
QTC_ASSERT(!m_requestObject, return); QTC_ASSERT(!m_requestObject, return);
QTC_ASSERT(m_parseData || (m_session && m_requestData), emit done(false); return); QTC_ASSERT(m_parseData || (m_session && m_requestData), emit done(DoneResult::Error); return);
m_requestObject = new QbsRequestObject; m_requestObject = new QbsRequestObject;
m_requestObject->setSession(m_session); m_requestObject->setSession(m_session);
@@ -199,10 +200,10 @@ void QbsRequest::start()
m_requestObject->setParseData(m_parseData); m_requestObject->setParseData(m_parseData);
} }
connect(m_requestObject, &QbsRequestObject::done, this, [this](bool success) { connect(m_requestObject, &QbsRequestObject::done, this, [this](DoneResult result) {
m_requestObject->deleteLater(); m_requestObject->deleteLater();
m_requestObject = nullptr; m_requestObject = nullptr;
emit done(success); emit done(result);
}); });
connect(m_requestObject, &QbsRequestObject::progressChanged, connect(m_requestObject, &QbsRequestObject::progressChanged,
this, &QbsRequest::progressChanged); this, &QbsRequest::progressChanged);

View File

@@ -28,7 +28,7 @@ public:
void start(); void start();
signals: signals:
void done(bool success); void done(Tasking::DoneResult result);
void progressChanged(int progress, const QString &info); // progress in % void progressChanged(int progress, const QString &info); // progress in %
void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format); void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format);
void taskAdded(const ProjectExplorer::Task &task); void taskAdded(const ProjectExplorer::Task &task);

View File

@@ -243,9 +243,9 @@ void FileExtractor::extract()
emit detailedTextChanged(); emit detailedTextChanged();
}); });
QObject::connect(m_unarchiver.get(), &Unarchiver::done, this, [this](bool success) { QObject::connect(m_unarchiver.get(), &Unarchiver::done, this, [this](Tasking::DoneResult result) {
m_unarchiver.release()->deleteLater(); m_unarchiver.release()->deleteLater();
m_finished = success; m_finished = result == Tasking::DoneResult::Success;
m_timer.stop(); m_timer.stop();
m_progress = 100; m_progress = 100;
@@ -253,7 +253,7 @@ void FileExtractor::extract()
emit targetFolderExistsChanged(); emit targetFolderExistsChanged();
emit finishedChanged(); emit finishedChanged();
QTC_CHECK(success); QTC_CHECK(m_finished);
}); });
m_unarchiver->start(); m_unarchiver->start();
} }

View File

@@ -37,6 +37,7 @@
#include <algorithm> #include <algorithm>
using namespace Tasking;
using namespace Utils; using namespace Utils;
void ExampleCheckout::registerTypes() void ExampleCheckout::registerTypes()
@@ -124,8 +125,9 @@ DataModelDownloader::DataModelDownloader(QObject * /* parent */)
auto unarchiver = new Unarchiver; auto unarchiver = new Unarchiver;
unarchiver->setSourceAndCommand(*sourceAndCommand); unarchiver->setSourceAndCommand(*sourceAndCommand);
unarchiver->setDestDir(tempFilePath()); unarchiver->setDestDir(tempFilePath());
QObject::connect(unarchiver, &Unarchiver::done, this, [this, unarchiver](bool success) { QObject::connect(unarchiver, &Unarchiver::done, this,
QTC_CHECK(success); [this, unarchiver](DoneResult result) {
QTC_CHECK(result == DoneResult::Success);
unarchiver->deleteLater(); unarchiver->deleteLater();
emit finished(); emit finished();
}); });

View File

@@ -1051,8 +1051,8 @@ void MemcheckToolPrivate::loadXmlLogFile(const QString &filePath)
m_logParser.reset(new Parser); m_logParser.reset(new Parser);
connect(m_logParser.get(), &Parser::error, this, &MemcheckToolPrivate::parserError); connect(m_logParser.get(), &Parser::error, this, &MemcheckToolPrivate::parserError);
connect(m_logParser.get(), &Parser::done, this, [this](bool success, const QString &err) { connect(m_logParser.get(), &Parser::done, this, [this](DoneResult result, const QString &err) {
if (!success) if (result == DoneResult::Error)
internalParserError(err); internalParserError(err);
loadingExternalXmlLogFileFinished(); loadingExternalXmlLogFileFinished();
m_logParser.release()->deleteLater(); m_logParser.release()->deleteLater();

View File

@@ -93,7 +93,7 @@ public:
const bool success = process->result() == ProcessResult::FinishedWithSuccess; const bool success = process->result() == ProcessResult::FinishedWithSuccess;
if (!success) if (!success)
emit q->processErrorReceived(process->errorString(), process->error()); emit q->processErrorReceived(process->errorString(), process->error());
emit q->done(success); emit q->done(toDoneResult(success));
}); });
connect(process, &Process::readyReadStandardOutput, this, [this, process] { connect(process, &Process::readyReadStandardOutput, this, [this, process] {
emit q->appendMessage(process->readAllStandardOutput(), StdOutFormat); emit q->appendMessage(process->readAllStandardOutput(), StdOutFormat);
@@ -215,7 +215,7 @@ bool ValgrindProcessPrivate::run()
m_taskTree->setRecipe(runRecipe()); m_taskTree->setRecipe(runRecipe());
connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) {
m_taskTree.release()->deleteLater(); m_taskTree.release()->deleteLater();
emit q->done(result == DoneWith::Success); emit q->done(toDoneResult(result == DoneWith::Success));
}); });
m_taskTree->start(); m_taskTree->start();
return bool(m_taskTree); return bool(m_taskTree);
@@ -268,8 +268,8 @@ bool ValgrindProcess::runBlocking()
bool ok = false; bool ok = false;
QEventLoop loop; QEventLoop loop;
const auto finalize = [&loop, &ok](bool success) { const auto finalize = [&loop, &ok](DoneResult result) {
ok = success; ok = result == DoneResult::Success;
// Refer to the QObject::deleteLater() docs. // Refer to the QObject::deleteLater() docs.
QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection); QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection);
}; };

View File

@@ -50,7 +50,7 @@ signals:
void logMessageReceived(const QByteArray &); void logMessageReceived(const QByteArray &);
void processErrorReceived(const QString &, QProcess::ProcessError); void processErrorReceived(const QString &, QProcess::ProcessError);
void valgrindStarted(qint64 pid); void valgrindStarted(qint64 pid);
void done(bool success); void done(Tasking::DoneResult result);
// Parser's signals // Parser's signals
void status(const Valgrind::XmlProtocol::Status &status); void status(const Valgrind::XmlProtocol::Status &status);

View File

@@ -25,6 +25,7 @@
#include <QWaitCondition> #include <QWaitCondition>
#include <QXmlStreamReader> #include <QXmlStreamReader>
using namespace Tasking;
using namespace Utils; using namespace Utils;
namespace Valgrind::XmlProtocol { namespace Valgrind::XmlProtocol {
@@ -710,7 +711,7 @@ public:
m_errorString = data.m_internalError; m_errorString = data.m_internalError;
}); });
QObject::connect(m_watcher.get(), &QFutureWatcherBase::finished, q, [this] { QObject::connect(m_watcher.get(), &QFutureWatcherBase::finished, q, [this] {
emit q->done(!m_errorString, *m_errorString); emit q->done(toDoneResult(!m_errorString), *m_errorString);
m_watcher.release()->deleteLater(); m_watcher.release()->deleteLater();
m_thread.reset(); m_thread.reset();
m_socket.reset(); m_socket.reset();
@@ -786,8 +787,8 @@ bool Parser::runBlocking()
bool ok = false; bool ok = false;
QEventLoop loop; QEventLoop loop;
const auto finalize = [&loop, &ok](bool success) { const auto finalize = [&loop, &ok](DoneResult result) {
ok = success; ok = result == DoneResult::Success;
// Refer to the QObject::deleteLater() docs. // Refer to the QObject::deleteLater() docs.
QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection); QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection);
}; };

View File

@@ -45,7 +45,7 @@ signals:
void errorCount(qint64 unique, qint64 count); void errorCount(qint64 unique, qint64 count);
void suppressionCount(const QString &name, qint64 count); void suppressionCount(const QString &name, qint64 count);
void announceThread(const AnnounceThread &announceThread); void announceThread(const AnnounceThread &announceThread);
void done(bool success, const QString &errorString); void done(Tasking::DoneResult result, const QString &errorString);
private: private:
std::unique_ptr<ParserPrivate> d; std::unique_ptr<ParserPrivate> d;

View File

@@ -345,7 +345,7 @@ class TickAndDoneTaskAdapter : public TaskAdapter<TickAndDone>
{ {
public: public:
TickAndDoneTaskAdapter() { connect(task(), &TickAndDone::done, this, TickAndDoneTaskAdapter() { connect(task(), &TickAndDone::done, this,
[this] { emit done(true); }); } [this] { emit done(DoneResult::Success); }); }
void start() final { task()->start(); } void start() final { task()->start(); }
}; };

View File

@@ -36,8 +36,8 @@ int main(int argc, char *argv[])
QObject::connect(&runner, &ValgrindProcess::processErrorReceived, &app, [](const QString &err) { QObject::connect(&runner, &ValgrindProcess::processErrorReceived, &app, [](const QString &err) {
qDebug() << err; qDebug() << err;
}); });
QObject::connect(&runner, &ValgrindProcess::done, &app, [](bool success) { QObject::connect(&runner, &ValgrindProcess::done, &app, [](Tasking::DoneResult result) {
qApp->exit(success ? 0 : 1); qApp->exit(result == Tasking::DoneResult::Success ? 0 : 1);
}); });
ErrorListModel model; ErrorListModel model;
QObject::connect(&runner, &ValgrindProcess::error, &model, &ErrorListModel::addError, QObject::connect(&runner, &ValgrindProcess::error, &model, &ErrorListModel::addError,