TaskTree: Return Group type from Executable::with[xxx] methods

This makes it convenient to execute a Group decorated with timeout,
log or cancel.

Change-Id: I847a0e97840f35b04ef20c2ebc6aa8381b6ed57a
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2024-10-02 11:59:02 +02:00
parent b701b1d547
commit df2486d060
2 changed files with 44 additions and 45 deletions

View File

@@ -1539,7 +1539,7 @@ void GroupItem::addChildren(const GroupItems &children)
immediately with the task's result. Otherwise, \a handler is invoked (if provided), immediately with the task's result. Otherwise, \a handler is invoked (if provided),
the task is canceled, and the returned item finishes with an error. the task is canceled, and the returned item finishes with an error.
*/ */
ExecutableItem ExecutableItem::withTimeout(milliseconds timeout, Group ExecutableItem::withTimeout(milliseconds timeout,
const std::function<void()> &handler) const const std::function<void()> &handler) const
{ {
const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; }; const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; };
@@ -1573,7 +1573,7 @@ static QString logHeader(const QString &logName)
synchronous or asynchronous, its result (the value described by the DoneWith enum), synchronous or asynchronous, its result (the value described by the DoneWith enum),
and the total execution time in milliseconds. and the total execution time in milliseconds.
*/ */
ExecutableItem ExecutableItem::withLog(const QString &logName) const Group ExecutableItem::withLog(const QString &logName) const
{ {
struct LogStorage struct LogStorage
{ {
@@ -1604,9 +1604,9 @@ ExecutableItem ExecutableItem::withLog(const QString &logName) const
} }
/*! /*!
\fn ExecutableItem ExecutableItem::operator!(const ExecutableItem &item) \fn Group ExecutableItem::operator!(const ExecutableItem &item)
Returns an ExecutableItem with the DoneResult of \a item negated. Returns a Group with the DoneResult of \a item negated.
If \a item reports DoneResult::Success, the returned item reports DoneResult::Error. If \a item reports DoneResult::Success, the returned item reports DoneResult::Error.
If \a item reports DoneResult::Error, the returned item reports DoneResult::Success. If \a item reports DoneResult::Error, the returned item reports DoneResult::Success.
@@ -1621,18 +1621,18 @@ ExecutableItem ExecutableItem::withLog(const QString &logName) const
\sa operator&&(), operator||() \sa operator&&(), operator||()
*/ */
ExecutableItem operator!(const ExecutableItem &item) Group operator!(const ExecutableItem &item)
{ {
return Group { return {
item, item,
onGroupDone([](DoneWith doneWith) { return toDoneResult(doneWith == DoneWith::Error); }) onGroupDone([](DoneWith doneWith) { return toDoneResult(doneWith == DoneWith::Error); })
}; };
} }
/*! /*!
\fn ExecutableItem ExecutableItem::operator&&(const ExecutableItem &first, const ExecutableItem &second) \fn Group ExecutableItem::operator&&(const ExecutableItem &first, const ExecutableItem &second)
Returns an ExecutableItem with \a first and \a second tasks merged with conjunction. Returns a Group with \a first and \a second tasks merged with conjunction.
Both \a first and \a second tasks execute in sequence. Both \a first and \a second tasks execute in sequence.
If both tasks report DoneResult::Success, the returned item reports DoneResult::Success. If both tasks report DoneResult::Success, the returned item reports DoneResult::Success.
@@ -1655,15 +1655,15 @@ ExecutableItem operator!(const ExecutableItem &item)
\sa operator||(), operator!() \sa operator||(), operator!()
*/ */
ExecutableItem operator&&(const ExecutableItem &first, const ExecutableItem &second) Group operator&&(const ExecutableItem &first, const ExecutableItem &second)
{ {
return Group { stopOnError, first, second }; return { stopOnError, first, second };
} }
/*! /*!
\fn ExecutableItem ExecutableItem::operator||(const ExecutableItem &first, const ExecutableItem &second) \fn Group ExecutableItem::operator||(const ExecutableItem &first, const ExecutableItem &second)
Returns an ExecutableItem with \a first and \a second tasks merged with disjunction. Returns a Group with \a first and \a second tasks merged with disjunction.
Both \a first and \a second tasks execute in sequence. Both \a first and \a second tasks execute in sequence.
If both tasks report DoneResult::Error, the returned item reports DoneResult::Error. If both tasks report DoneResult::Error, the returned item reports DoneResult::Error.
@@ -1686,13 +1686,13 @@ ExecutableItem operator&&(const ExecutableItem &first, const ExecutableItem &sec
\sa operator&&(), operator!() \sa operator&&(), operator!()
*/ */
ExecutableItem operator||(const ExecutableItem &first, const ExecutableItem &second) Group operator||(const ExecutableItem &first, const ExecutableItem &second)
{ {
return Group { stopOnSuccess, first, second }; return { stopOnSuccess, first, second };
} }
/*! /*!
\fn ExecutableItem ExecutableItem::operator&&(const ExecutableItem &item, DoneResult result) \fn Group ExecutableItem::operator&&(const ExecutableItem &item, DoneResult result)
\overload ExecutableItem::operator&&() \overload ExecutableItem::operator&&()
Returns the \a item task if the \a result is DoneResult::Success; otherwise returns Returns the \a item task if the \a result is DoneResult::Success; otherwise returns
@@ -1701,15 +1701,13 @@ ExecutableItem operator||(const ExecutableItem &first, const ExecutableItem &sec
The \c {task && DoneResult::Error} is an eqivalent to tweaking the task's done result The \c {task && DoneResult::Error} is an eqivalent to tweaking the task's done result
into DoneResult::Error unconditionally. into DoneResult::Error unconditionally.
*/ */
ExecutableItem operator&&(const ExecutableItem &item, DoneResult result) Group operator&&(const ExecutableItem &item, DoneResult result)
{ {
if (result == DoneResult::Success) return { result == DoneResult::Success ? stopOnError : finishAllAndError, item };
return item;
return Group { finishAllAndError, item };
} }
/*! /*!
\fn ExecutableItem ExecutableItem::operator||(const ExecutableItem &item, DoneResult result) \fn Group ExecutableItem::operator||(const ExecutableItem &item, DoneResult result)
\overload ExecutableItem::operator||() \overload ExecutableItem::operator||()
Returns the \a item task if the \a result is DoneResult::Error; otherwise returns Returns the \a item task if the \a result is DoneResult::Error; otherwise returns
@@ -1718,14 +1716,12 @@ ExecutableItem operator&&(const ExecutableItem &item, DoneResult result)
The \c {task || DoneResult::Success} is an eqivalent to tweaking the task's done result The \c {task || DoneResult::Success} is an eqivalent to tweaking the task's done result
into DoneResult::Success unconditionally. into DoneResult::Success unconditionally.
*/ */
ExecutableItem operator||(const ExecutableItem &item, DoneResult result) Group operator||(const ExecutableItem &item, DoneResult result)
{ {
if (result == DoneResult::Error) return { result == DoneResult::Error ? stopOnError : finishAllAndSuccess, item };
return item;
return Group { finishAllAndSuccess, item };
} }
ExecutableItem ExecutableItem::withCancelImpl( Group ExecutableItem::withCancelImpl(
const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const
{ {
const auto onSetup = [connectWrapper](Barrier &barrier) { const auto onSetup = [connectWrapper](Barrier &barrier) {

View File

@@ -296,35 +296,26 @@ private:
class TASKING_EXPORT ExecutableItem : public GroupItem class TASKING_EXPORT ExecutableItem : public GroupItem
{ {
public: public:
ExecutableItem withTimeout(std::chrono::milliseconds timeout, Group withTimeout(std::chrono::milliseconds timeout,
const std::function<void()> &handler = {}) const; const std::function<void()> &handler = {}) const;
ExecutableItem withLog(const QString &logName) const; Group withLog(const QString &logName) const;
template <typename SenderSignalPairGetter> template <typename SenderSignalPairGetter>
ExecutableItem withCancel(SenderSignalPairGetter &&getter) const Group withCancel(SenderSignalPairGetter &&getter) const;
{
const auto connectWrapper = [getter](QObject *guard, const std::function<void()> &trigger) {
const auto senderSignalPair = getter();
QObject::connect(senderSignalPair.first, senderSignalPair.second, guard, [trigger] {
trigger();
}, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
};
return withCancelImpl(connectWrapper);
}
protected: protected:
ExecutableItem() = default; ExecutableItem() = default;
ExecutableItem(const TaskHandler &handler) : GroupItem(handler) {} ExecutableItem(const TaskHandler &handler) : GroupItem(handler) {}
private: private:
TASKING_EXPORT friend ExecutableItem operator!(const ExecutableItem &item); TASKING_EXPORT friend Group operator!(const ExecutableItem &item);
TASKING_EXPORT friend ExecutableItem operator&&(const ExecutableItem &first, TASKING_EXPORT friend Group operator&&(const ExecutableItem &first,
const ExecutableItem &second); const ExecutableItem &second);
TASKING_EXPORT friend ExecutableItem operator||(const ExecutableItem &first, TASKING_EXPORT friend Group operator||(const ExecutableItem &first,
const ExecutableItem &second); const ExecutableItem &second);
TASKING_EXPORT friend ExecutableItem operator&&(const ExecutableItem &item, DoneResult result); TASKING_EXPORT friend Group operator&&(const ExecutableItem &item, DoneResult result);
TASKING_EXPORT friend ExecutableItem operator||(const ExecutableItem &item, DoneResult result); TASKING_EXPORT friend Group operator||(const ExecutableItem &item, DoneResult result);
ExecutableItem withCancelImpl( Group withCancelImpl(
const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const; const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const;
}; };
@@ -396,6 +387,18 @@ private:
} }
}; };
template <typename SenderSignalPairGetter>
Group ExecutableItem::withCancel(SenderSignalPairGetter &&getter) const
{
const auto connectWrapper = [getter](QObject *guard, const std::function<void()> &trigger) {
const auto senderSignalPair = getter();
QObject::connect(senderSignalPair.first, senderSignalPair.second, guard, [trigger] {
trigger();
}, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
};
return withCancelImpl(connectWrapper);
}
template <typename Handler> template <typename Handler>
static GroupItem onGroupSetup(Handler &&handler) static GroupItem onGroupSetup(Handler &&handler)
{ {