forked from qt-creator/qt-creator
TaskTree: Enhance Sync's function
Make it possible to pass a void returning function to the Sync constructor. In this case it's assumed that function returns true by default and finishes successfully. Add some helpful error messages when requirements for the passed function are not met. Change-Id: I8be75acd277d06e87db3c87a6eb96173aa9cd890 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -306,11 +306,28 @@ public:
|
||||
// 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; })}) {}
|
||||
template<typename Function>
|
||||
Sync(Function &&function) : Group(init(std::forward<Function>(function))) {}
|
||||
|
||||
private:
|
||||
template<typename Function>
|
||||
static QList<TaskItem> init(Function &&function) {
|
||||
constexpr bool isInvocable = std::is_invocable_v<std::decay_t<Function>>;
|
||||
static_assert(isInvocable,
|
||||
"Sync element: The synchronous function can't take any arguments.");
|
||||
constexpr bool isBool = std::is_same_v<bool, std::invoke_result_t<std::decay_t<Function>>>;
|
||||
constexpr bool isVoid = std::is_same_v<void, std::invoke_result_t<std::decay_t<Function>>>;
|
||||
static_assert(isBool || isVoid,
|
||||
"Sync element: The synchronous function has to return void or bool.");
|
||||
if constexpr (isBool) {
|
||||
return {OnGroupSetup([function] { return function() ? TaskAction::StopWithDone
|
||||
: TaskAction::StopWithError; })};
|
||||
}
|
||||
return {OnGroupSetup([function] { function(); return TaskAction::StopWithDone; })};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
QTCREATOR_UTILS_EXPORT extern ParallelLimit sequential;
|
||||
|
@@ -122,6 +122,32 @@ void tst_TaskTree::validConstructs()
|
||||
OnGroupDone([] {}),
|
||||
OnGroupError([] {})
|
||||
};
|
||||
|
||||
// When turning each of below blocks on, you should see the specific compiler error message.
|
||||
|
||||
#if 0
|
||||
{
|
||||
// "Sync element: The synchronous function has to return void or bool."
|
||||
const auto setupSync = [] { return 3; };
|
||||
const Sync sync(setupSync);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
// "Sync element: The synchronous function can't take any arguments."
|
||||
const auto setupSync = [](int) { };
|
||||
const Sync sync(setupSync);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
// "Sync element: The synchronous function can't take any arguments."
|
||||
const auto setupSync = [](int) { return true; };
|
||||
const Sync sync(setupSync);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_TaskTree::processTree_data()
|
||||
@@ -174,7 +200,10 @@ 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) {
|
||||
const auto setupSync = [storage](int syncId) {
|
||||
return [=] { storage->m_log.append({syncId, Handler::Sync}); };
|
||||
};
|
||||
const auto setupSyncWithReturn = [storage](int syncId, bool success) {
|
||||
return [=] { storage->m_log.append({syncId, Handler::Sync}); return success; };
|
||||
};
|
||||
|
||||
@@ -997,11 +1026,11 @@ void tst_TaskTree::processTree_data()
|
||||
{
|
||||
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))
|
||||
Sync(setupSync(1)),
|
||||
Sync(setupSync(2)),
|
||||
Sync(setupSync(3)),
|
||||
Sync(setupSync(4)),
|
||||
Sync(setupSync(5))
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Sync},
|
||||
@@ -1014,15 +1043,35 @@ void tst_TaskTree::processTree_data()
|
||||
<< TestData{storage, root, log, 0, OnStart::NotRunning, OnDone::Success};
|
||||
}
|
||||
|
||||
{
|
||||
const Group root {
|
||||
Storage(storage),
|
||||
Sync(setupSyncWithReturn(1, true)),
|
||||
Sync(setupSyncWithReturn(2, true)),
|
||||
Sync(setupSyncWithReturn(3, true)),
|
||||
Sync(setupSyncWithReturn(4, true)),
|
||||
Sync(setupSyncWithReturn(5, true))
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Sync},
|
||||
{2, Handler::Sync},
|
||||
{3, Handler::Sync},
|
||||
{4, Handler::Sync},
|
||||
{5, Handler::Sync}
|
||||
};
|
||||
QTest::newRow("SyncWithReturn")
|
||||
<< 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))
|
||||
Sync(setupSync(1)),
|
||||
Sync(setupSync(2)),
|
||||
Sync(setupSync(3)),
|
||||
Sync(setupSync(4)),
|
||||
Sync(setupSync(5))
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Sync},
|
||||
@@ -1039,11 +1088,11 @@ void tst_TaskTree::processTree_data()
|
||||
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))
|
||||
Sync(setupSync(1)),
|
||||
Sync(setupSync(2)),
|
||||
Sync(setupSyncWithReturn(3, false)),
|
||||
Sync(setupSync(4)),
|
||||
Sync(setupSync(5))
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Sync},
|
||||
@@ -1057,11 +1106,11 @@ void tst_TaskTree::processTree_data()
|
||||
{
|
||||
const Group root {
|
||||
Storage(storage),
|
||||
Sync(setupSync(1, true)),
|
||||
Sync(setupSync(1)),
|
||||
Process(setupProcess(2)),
|
||||
Sync(setupSync(3, true)),
|
||||
Sync(setupSync(3)),
|
||||
Process(setupProcess(4)),
|
||||
Sync(setupSync(5, true)),
|
||||
Sync(setupSync(5)),
|
||||
OnGroupDone(groupDone(0))
|
||||
};
|
||||
const Log log {
|
||||
@@ -1076,6 +1125,26 @@ void tst_TaskTree::processTree_data()
|
||||
<< TestData{storage, root, log, 2, OnStart::Running, OnDone::Success};
|
||||
}
|
||||
|
||||
{
|
||||
const Group root {
|
||||
Storage(storage),
|
||||
Sync(setupSync(1)),
|
||||
Process(setupProcess(2)),
|
||||
Sync(setupSyncWithReturn(3, false)),
|
||||
Process(setupProcess(4)),
|
||||
Sync(setupSync(5)),
|
||||
OnGroupError(groupError(0))
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Sync},
|
||||
{2, Handler::Setup},
|
||||
{3, Handler::Sync},
|
||||
{0, Handler::GroupError}
|
||||
};
|
||||
QTest::newRow("SyncAndAsyncError")
|
||||
<< TestData{storage, root, log, 2, OnStart::Running, OnDone::Failure};
|
||||
}
|
||||
|
||||
{
|
||||
Condition condition;
|
||||
|
||||
|
Reference in New Issue
Block a user