TaskTree: Rename TaskAction into SetupResult

It's only used as a return value from group's or task's
setup handler. It instructs the running task tree on
how to proceed further.

It addresses the 21th point in the bugreport below.

Task-number: QTCREATORBUG-28741
Change-Id: I25802c76b9e7bc044c6a38197935798d2da9ad02
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-06-16 21:33:59 +02:00
parent 52badc2fa6
commit 664d409489
17 changed files with 159 additions and 159 deletions

View File

@@ -236,7 +236,7 @@ private:
*/
/*!
\enum Tasking::TaskAction
\enum Tasking::SetupResult
This enum is optionally returned from the group's or task's setup handler function.
It instructs the running task tree on how to proceed after the setup handler's execution
@@ -264,21 +264,21 @@ private:
/*!
\typealias GroupItem::GroupSetupHandler
Type alias for \c std::function<TaskAction()>.
Type alias for \c std::function<SetupResult()>.
The GroupSetupHandler is used when constructing the onGroupSetup() element.
Any function with the above signature, when passed as a group setup handler,
will be called by the running task tree when the group execution starts.
The return value of the handler instructs the running group on how to proceed
after the handler's invocation is finished. The default return value of TaskAction::Continue
after the handler's invocation is finished. The default return value of SetupResult::Continue
instructs the group to continue running, i.e. to start executing its child tasks.
The return value of TaskAction::StopWithDone or TaskAction::StopWithError
The return value of SetupResult::StopWithDone or SetupResult::StopWithError
instructs the group to skip the child tasks' execution and finish immediately with
success or an error, respectively.
When the return type is either TaskAction::StopWithDone
of TaskAction::StopWithError, the group's done or error handler (if provided)
When the return type is either SetupResult::StopWithDone
of SetupResult::StopWithError, the group's done or error handler (if provided)
is called synchronously immediately afterwards.
\note Even if the group setup handler returns StopWithDone or StopWithError,
@@ -287,7 +287,7 @@ private:
The onGroupSetup() accepts also functions in the shortened form of \c std::function<void()>,
i.e. the return value is void. In this case it's assumed that the return value
is TaskAction::Continue by default.
is SetupResult::Continue by default.
\sa onGroupSetup()
*/
@@ -311,7 +311,7 @@ private:
Constructs a group's element holding the group setup handler.
The \a handler is invoked whenever the group starts.
The passed \a handler is either of \c std::function<TaskAction()> or \c std::function<void()>
The passed \a handler is either of \c std::function<SetupResult()> or \c std::function<void()>
type. For more information on possible argument type, refer to
\l {GroupItem::GroupSetupHandler}.
@@ -432,9 +432,9 @@ const GroupItem stopOnFinished = workflowPolicy(WorkflowPolicy::StopOnFinished);
const GroupItem finishAllAndDone = workflowPolicy(WorkflowPolicy::FinishAllAndDone);
const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError);
static TaskAction toTaskAction(bool success)
static SetupResult toSetupResult(bool success)
{
return success ? TaskAction::StopWithDone : TaskAction::StopWithError;
return success ? SetupResult::StopWithDone : SetupResult::StopWithError;
}
bool TreeStorageBase::isValid() const
@@ -660,10 +660,10 @@ public:
TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task,
TaskNode *parentNode, TaskContainer *parentContainer)
: m_constData(taskTreePrivate, task, parentNode, parentContainer, this) {}
TaskAction start();
TaskAction continueStart(TaskAction startAction, int nextChild);
TaskAction startChildren(int nextChild);
TaskAction childDone(bool success);
SetupResult start();
SetupResult continueStart(SetupResult startAction, int nextChild);
SetupResult startChildren(int nextChild);
SetupResult childDone(bool success);
void stop();
void invokeEndHandler();
bool isRunning() const { return m_runtimeData.has_value(); }
@@ -718,7 +718,7 @@ public:
// If returned value != Continue, childDone() needs to be called in parent container (in caller)
// in order to unwind properly.
TaskAction start();
SetupResult start();
void stop();
void invokeEndHandler(bool success);
bool isRunning() const { return m_task || m_container.isRunning(); }
@@ -947,34 +947,34 @@ int TaskContainer::RuntimeData::currentLimit() const
? qMin(m_doneCount + m_constData.m_parallelLimit, childCount) : childCount;
}
TaskAction TaskContainer::start()
SetupResult TaskContainer::start()
{
QTC_CHECK(!isRunning());
m_runtimeData.emplace(m_constData);
TaskAction startAction = TaskAction::Continue;
SetupResult startAction = SetupResult::Continue;
if (m_constData.m_groupHandler.m_setupHandler) {
startAction = invokeHandler(this, m_constData.m_groupHandler.m_setupHandler);
if (startAction != TaskAction::Continue) {
if (startAction != SetupResult::Continue) {
m_constData.m_taskTreePrivate->advanceProgress(m_constData.m_taskCount);
// Non-Continue TaskAction takes precedence over the workflow policy.
m_runtimeData->m_successBit = startAction == TaskAction::StopWithDone;
// Non-Continue SetupResult takes precedence over the workflow policy.
m_runtimeData->m_successBit = startAction == SetupResult::StopWithDone;
}
}
if (startAction == TaskAction::Continue) {
if (startAction == SetupResult::Continue) {
if (m_constData.m_children.isEmpty())
startAction = toTaskAction(m_runtimeData->m_successBit);
startAction = toSetupResult(m_runtimeData->m_successBit);
}
return continueStart(startAction, 0);
}
TaskAction TaskContainer::continueStart(TaskAction startAction, int nextChild)
SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild)
{
const TaskAction groupAction = startAction == TaskAction::Continue ? startChildren(nextChild)
const SetupResult groupAction = startAction == SetupResult::Continue ? startChildren(nextChild)
: startAction;
QTC_CHECK(isRunning()); // TODO: superfluous
if (groupAction != TaskAction::Continue) {
const bool success = m_runtimeData->updateSuccessBit(groupAction == TaskAction::StopWithDone);
if (groupAction != SetupResult::Continue) {
const bool success = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithDone);
invokeEndHandler();
if (TaskContainer *parentContainer = m_constData.m_parentContainer) {
QTC_CHECK(parentContainer->isRunning());
@@ -989,7 +989,7 @@ TaskAction TaskContainer::continueStart(TaskAction startAction, int nextChild)
return groupAction;
}
TaskAction TaskContainer::startChildren(int nextChild)
SetupResult TaskContainer::startChildren(int nextChild)
{
QTC_CHECK(isRunning());
GuardLocker locker(m_runtimeData->m_startGuard);
@@ -998,12 +998,12 @@ TaskAction TaskContainer::startChildren(int nextChild)
if (i >= limit)
break;
const TaskAction startAction = m_constData.m_children.at(i)->start();
if (startAction == TaskAction::Continue)
const SetupResult startAction = m_constData.m_children.at(i)->start();
if (startAction == SetupResult::Continue)
continue;
const TaskAction finalizeAction = childDone(startAction == TaskAction::StopWithDone);
if (finalizeAction == TaskAction::Continue)
const SetupResult finalizeAction = childDone(startAction == SetupResult::StopWithDone);
if (finalizeAction == SetupResult::Continue)
continue;
int skippedTaskCount = 0;
@@ -1013,10 +1013,10 @@ TaskAction TaskContainer::startChildren(int nextChild)
m_constData.m_taskTreePrivate->advanceProgress(skippedTaskCount);
return finalizeAction;
}
return TaskAction::Continue;
return SetupResult::Continue;
}
TaskAction TaskContainer::childDone(bool success)
SetupResult TaskContainer::childDone(bool success)
{
QTC_CHECK(isRunning());
const int limit = m_runtimeData->currentLimit(); // Read before bumping m_doneCount and stop()
@@ -1028,9 +1028,9 @@ TaskAction TaskContainer::childDone(bool success)
++m_runtimeData->m_doneCount;
const bool updatedSuccess = m_runtimeData->updateSuccessBit(success);
const TaskAction startAction
const SetupResult startAction
= (shouldStop || m_runtimeData->m_doneCount == m_constData.m_children.size())
? toTaskAction(updatedSuccess) : TaskAction::Continue;
? toSetupResult(updatedSuccess) : SetupResult::Continue;
if (isStarting())
return startAction;
@@ -1064,30 +1064,30 @@ void TaskContainer::invokeEndHandler()
m_runtimeData.reset();
}
TaskAction TaskNode::start()
SetupResult TaskNode::start()
{
QTC_CHECK(!isRunning());
if (!isTask())
return m_container.start();
m_task.reset(m_taskHandler.m_createHandler());
const TaskAction startAction = m_taskHandler.m_setupHandler
const SetupResult startAction = m_taskHandler.m_setupHandler
? invokeHandler(parentContainer(), m_taskHandler.m_setupHandler, *m_task.get())
: TaskAction::Continue;
if (startAction != TaskAction::Continue) {
: SetupResult::Continue;
if (startAction != SetupResult::Continue) {
m_container.m_constData.m_taskTreePrivate->advanceProgress(1);
m_task.reset();
return startAction;
}
const std::shared_ptr<TaskAction> unwindAction
= std::make_shared<TaskAction>(TaskAction::Continue);
const std::shared_ptr<SetupResult> unwindAction
= std::make_shared<SetupResult>(SetupResult::Continue);
QObject::connect(m_task.get(), &TaskInterface::done, taskTree(), [=](bool success) {
invokeEndHandler(success);
QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr);
m_task.release()->deleteLater();
QTC_ASSERT(parentContainer() && parentContainer()->isRunning(), return);
if (parentContainer()->isStarting())
*unwindAction = toTaskAction(success);
*unwindAction = toSetupResult(success);
else
parentContainer()->childDone(success);
});
@@ -1326,18 +1326,18 @@ void TaskNode::invokeEndHandler(bool success)
as the task tree calls it when needed. The setup handler is optional. When used,
it must be the first argument of the task's constructor.
Optionally, the setup handler may return a TaskAction. The returned
TaskAction influences the further start behavior of a given task. The
Optionally, the setup handler may return a SetupResult. The returned
SetupResult influences the further start behavior of a given task. The
possible values are:
\table
\header
\li TaskAction Value
\li SetupResult Value
\li Brief Description
\row
\li Continue
\li The task will be started normally. This is the default behavior when the
setup handler doesn't return TaskAction (that is, its return type is
setup handler doesn't return SetupResult (that is, its return type is
void).
\row
\li StopWithDone
@@ -1409,12 +1409,12 @@ void TaskNode::invokeEndHandler(bool success)
handler. If you add more than one onGroupSetup() element to a group, an assert
is triggered at runtime that includes an error message.
Like the task's start handler, the group start handler may return TaskAction.
The returned TaskAction value affects the start behavior of the
Like the task's start handler, the group start handler may return SetupResult.
The returned SetupResult value affects the start behavior of the
whole group. If you do not specify a group start handler or its return type
is void, the default group's action is TaskAction::Continue, so that all
is void, the default group's action is SetupResult::Continue, so that all
tasks are started normally. Otherwise, when the start handler returns
TaskAction::StopWithDone or TaskAction::StopWithError, the tasks are not
SetupResult::StopWithDone or SetupResult::StopWithError, the tasks are not
started (they are skipped) and the group itself reports success or failure,
depending on the returned value, respectively.
@@ -1422,15 +1422,15 @@ void TaskNode::invokeEndHandler(bool success)
const Group root {
onGroupSetup([] { qDebug() << "Root setup"; }),
Group {
onGroupSetup([] { qDebug() << "Group 1 setup"; return TaskAction::Continue; }),
onGroupSetup([] { qDebug() << "Group 1 setup"; return SetupResult::Continue; }),
ProcessTask(...) // Process 1
},
Group {
onGroupSetup([] { qDebug() << "Group 2 setup"; return TaskAction::StopWithDone; }),
onGroupSetup([] { qDebug() << "Group 2 setup"; return SetupResult::StopWithDone; }),
ProcessTask(...) // Process 2
},
Group {
onGroupSetup([] { qDebug() << "Group 3 setup"; return TaskAction::StopWithError; }),
onGroupSetup([] { qDebug() << "Group 3 setup"; return SetupResult::StopWithError; }),
ProcessTask(...) // Process 3
},
ProcessTask(...) // Process 4
@@ -1446,7 +1446,7 @@ void TaskNode::invokeEndHandler(bool success)
\li Comment
\row
\li Root Group starts
\li Doesn't return TaskAction, so its tasks are executed.
\li Doesn't return SetupResult, so its tasks are executed.
\row
\li Group 1 starts
\li Returns Continue, so its tasks are executed.
@@ -1838,7 +1838,7 @@ void TaskTree::setRecipe(const Group &recipe)
Otherwise, the task tree is started.
The started task tree may finish synchronously,
for example when the main group's start handler returns TaskAction::StopWithError.
for example when the main group's start handler returns SetupResult::StopWithError.
For this reason, the connections to the done and errorOccurred signals should be
established before calling start. Use isRunning() in order to detect whether
the task tree is still running after a call to start().