TaskTree: Add synchronous invocation (Tasking::Sync)

Make it possible to mix synchronous and asynchronous calls
inside task tree.

Basically, it's a shortcut for:

bool syncMethod();
Group {
    OnGroupSetup([syncMethod] { return syncMethod()
                                ? TaskAction::StopWithDone
                                : TaskAction::StopWithError; })
}

Please note: similarly to Group, Sync isn't counted as a task
inside taskCount() and doesn't emit TaskTree::progressValueChanged()
when finished. It's being considered as a simple handler
that doesn't last long and shouldn't block the GUI thread.
Otherwise, use AsyncTask instead.

Change-Id: If71c5da2f9b202a69c41a555cc93d314476952f4
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Jarek Kobus
2023-02-06 20:27:59 +01:00
parent 2f5aed6c78
commit 06dda40ccc
2 changed files with 95 additions and 1 deletions

View File

@@ -244,6 +244,16 @@ public:
OnGroupError(const GroupEndHandler &handler) : TaskItem({{}, {}, handler}) {}
};
// Synchronous invocation. Similarly to Group - isn't counted as a task inside taskCount()
class QTCREATOR_UTILS_EXPORT Sync : public Group
{
public:
using SynchronousMethod = std::function<bool()>;
Sync(const SynchronousMethod &sync)
: Group({OnGroupSetup([sync] { return sync() ? TaskAction::StopWithDone
: TaskAction::StopWithError; })}) {}
};
QTCREATOR_UTILS_EXPORT extern ParallelLimit sequential;
QTCREATOR_UTILS_EXPORT extern ParallelLimit parallel;
QTCREATOR_UTILS_EXPORT extern Workflow stopOnError;

View File

@@ -19,7 +19,8 @@ enum class Handler {
Error,
GroupSetup,
GroupDone,
GroupError
GroupError,
Sync
};
using Log = QList<QPair<int, Handler>>;
@@ -172,6 +173,9 @@ void tst_TaskTree::processTree_data()
const auto groupError = [storage](int groupId) {
return [=] { storage->m_log.append({groupId, Handler::GroupError}); };
};
const auto setupSync = [storage](int syncId, bool success) {
return [=] { storage->m_log.append({syncId, Handler::Sync}); return success; };
};
const auto constructSimpleSequence = [=](const Workflow &policy) {
return Group {
@@ -988,6 +992,86 @@ void tst_TaskTree::processTree_data()
QTest::newRow("DeeplyNestedParallelError")
<< TestData{storage, root, log, 5, OnStart::Running, OnDone::Failure};
}
{
const Group root {
Storage(storage),
Sync(setupSync(1, true)),
Sync(setupSync(2, true)),
Sync(setupSync(3, true)),
Sync(setupSync(4, true)),
Sync(setupSync(5, true))
};
const Log log {
{1, Handler::Sync},
{2, Handler::Sync},
{3, Handler::Sync},
{4, Handler::Sync},
{5, Handler::Sync}
};
QTest::newRow("SyncSequential")
<< TestData{storage, root, log, 0, OnStart::NotRunning, OnDone::Success};
}
{
const Group root {
Storage(storage),
parallel,
Sync(setupSync(1, true)),
Sync(setupSync(2, true)),
Sync(setupSync(3, true)),
Sync(setupSync(4, true)),
Sync(setupSync(5, true))
};
const Log log {
{1, Handler::Sync},
{2, Handler::Sync},
{3, Handler::Sync},
{4, Handler::Sync},
{5, Handler::Sync}
};
QTest::newRow("SyncParallel")
<< TestData{storage, root, log, 0, OnStart::NotRunning, OnDone::Success};
}
{
const Group root {
Storage(storage),
parallel,
Sync(setupSync(1, true)),
Sync(setupSync(2, true)),
Sync(setupSync(3, false)),
Sync(setupSync(4, true)),
Sync(setupSync(5, true))
};
const Log log {
{1, Handler::Sync},
{2, Handler::Sync},
{3, Handler::Sync}
};
QTest::newRow("SyncError")
<< TestData{storage, root, log, 0, OnStart::NotRunning, OnDone::Failure};
}
const Group root {
Storage(storage),
Sync(setupSync(1, true)),
Process(setupProcess(2)),
Sync(setupSync(3, true)),
Process(setupProcess(4)),
Sync(setupSync(5, true)),
OnGroupDone(groupDone(0))
};
const Log log {
{1, Handler::Sync},
{2, Handler::Setup},
{3, Handler::Sync},
{4, Handler::Setup},
{5, Handler::Sync},
{0, Handler::GroupDone}
};
QTest::newRow("SyncAndAsync")
<< TestData{storage, root, log, 2, OnStart::Running, OnDone::Success};
}
void tst_TaskTree::processTree()