diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 8e79485a8f3..06a3804f9dd 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -40,6 +40,16 @@ private: Guard &m_guard; }; +TaskItem onGroupDone(const TaskItem::GroupEndHandler &handler) +{ + return Group::onGroupDone(handler); +} + +TaskItem onGroupError(const TaskItem::GroupEndHandler &handler) +{ + return Group::onGroupError(handler); +} + static TaskAction toTaskAction(bool success) { return success ? TaskAction::StopWithDone : TaskAction::StopWithError; diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 407db58b0ae..08391d9d633 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -183,6 +183,7 @@ protected: void setTaskSetupHandler(const TaskSetupHandler &handler); void setTaskDoneHandler(const TaskEndHandler &handler); void setTaskErrorHandler(const TaskEndHandler &handler); + static TaskItem createGroupHandler(const GroupHandler &handler) { return TaskItem(handler); } private: Type m_type = Type::Group; @@ -199,8 +200,47 @@ class TASKING_EXPORT Group : public TaskItem public: Group(const QList &children) { addChildren(children); } Group(std::initializer_list children) { addChildren(children); } + + template + static TaskItem onGroupSetup(SetupHandler &&handler) { + return createGroupHandler({wrapGroupSetup(std::forward(handler))}); + } + static TaskItem onGroupDone(const GroupEndHandler &handler) { + return createGroupHandler({{}, handler}); + } + static TaskItem onGroupError(const GroupEndHandler &handler) { + return createGroupHandler({{}, {}, handler}); + } + +private: + template + static GroupSetupHandler wrapGroupSetup(SetupHandler &&handler) + { + static constexpr bool isDynamic + = std::is_same_v>>; + constexpr bool isVoid + = std::is_same_v>>; + static_assert(isDynamic || isVoid, + "Group setup handler needs to take no arguments and has to return " + "void or TaskAction. The passed handler doesn't fulfill these requirements."); + return [=] { + if constexpr (isDynamic) + return std::invoke(handler); + std::invoke(handler); + return TaskAction::Continue; + }; + }; }; +template +static TaskItem onGroupSetup(SetupHandler &&handler) +{ + return Group::onGroupSetup(std::forward(handler)); +} + +TASKING_EXPORT TaskItem onGroupDone(const TaskItem::GroupEndHandler &handler); +TASKING_EXPORT TaskItem onGroupError(const TaskItem::GroupEndHandler &handler); + class TASKING_EXPORT Storage : public TaskItem { public: @@ -276,10 +316,10 @@ private: 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 + return {onGroupSetup([function] { return function() ? TaskAction::StopWithDone : TaskAction::StopWithError; })}; } - return {OnGroupSetup([function] { function(); return TaskAction::StopWithDone; })}; + return {onGroupSetup([function] { function(); return TaskAction::StopWithDone; })}; }; };