TaskTree: Handle progress inside iterations

For temporary simplicity, take the strategy that only
zero-iterations (up to root) advance progress.

Task-number: QTCREATORBUG-30081
Change-Id: I7a0da2f141043622a07fa3e0cd03e3fb53417932
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2024-01-07 20:15:27 +01:00
parent 1fe1055277
commit a50bc70b87

View File

@@ -1490,19 +1490,27 @@ static bool initialSuccessBit(WorkflowPolicy workflowPolicy)
return false;
}
static bool isProgressive(RuntimeContainer *container);
class RuntimeIteration
{
Q_DISABLE_COPY(RuntimeIteration)
public:
RuntimeIteration(int index, RuntimeContainer *container)
: m_iterationIndex(index)
, m_isProgressive(index ? false : isProgressive(container))
, m_container(container)
{}
int continueIndex() const;
int currentLimit() const;
void deleteChild(RuntimeTask *node);
const int m_iterationIndex = 0;
const bool m_isProgressive = true;
RuntimeContainer *m_container = nullptr;
std::vector<std::unique_ptr<RuntimeTask>> m_children = {}; // Owning.
int m_doneCount = 0;
std::vector<std::unique_ptr<RuntimeTask>> m_children = {}; // Owning.
};
class RuntimeContainer
@@ -1555,6 +1563,12 @@ public:
std::unique_ptr<TaskInterface> m_task = {}; // Owning.
};
bool isProgressive(RuntimeContainer *container)
{
RuntimeIteration *iteration = container->m_parentTask->m_parentIteration;
return iteration ? iteration->m_isProgressive : true;
}
void ExecutionContextActivator::activateContext(RuntimeIteration *iteration)
{
// TODO: activate iterator
@@ -1717,7 +1731,7 @@ SetupResult TaskTreePrivate::start(RuntimeContainer *container)
if (container->m_containerNode.m_groupHandler.m_setupHandler) {
startAction = invokeHandler(container, container->m_containerNode.m_groupHandler.m_setupHandler);
if (startAction != SetupResult::Continue) {
// TODO: Handle progress well.
if (isProgressive(container))
advanceProgress(container->m_containerNode.m_taskCount);
// Non-Continue SetupResult takes precedence over the workflow policy.
container->m_successBit = startAction == SetupResult::StopWithSuccess;
@@ -1756,10 +1770,8 @@ SetupResult TaskTreePrivate::startChildren(RuntimeContainer *container)
if (container->m_containerNode.m_parallelLimit == 0 && !container->m_iterations.empty())
return SetupResult::Continue;
if (container->m_iterations.empty()) {
RuntimeIteration *iteration = new RuntimeIteration{0, container};
container->m_iterations.emplace_back(iteration);
}
if (container->m_iterations.empty())
container->m_iterations.emplace_back(std::make_unique<RuntimeIteration>(0, container));
GuardLocker locker(container->m_startGuard);
for (auto &iteration : container->m_iterations) {
@@ -1781,12 +1793,13 @@ SetupResult TaskTreePrivate::startChildren(RuntimeContainer *container)
if (finalizeAction == SetupResult::Continue)
continue;
if (iteration->m_isProgressive) {
int skippedTaskCount = 0;
// Skip scheduled but not run yet. The current (i) was already notified.
for (int j = i + 1; j < limit; ++j)
skippedTaskCount += container->m_containerNode.m_children.at(j).taskCount();
// TODO: Handle progress well
advanceProgress(skippedTaskCount);
}
return finalizeAction;
}
}
@@ -1816,18 +1829,19 @@ SetupResult TaskTreePrivate::childDone(RuntimeIteration *iteration, bool success
void TaskTreePrivate::stop(RuntimeContainer *container)
{
int skippedTaskCount = 0;
for (auto &iteration : container->m_iterations) {
for (auto &child : iteration->m_children)
stop(child.get());
// TODO: Do it only for 0-index iteration (up to root).
for (int i = iteration->currentLimit(); i < int(container->m_containerNode.m_children.size()); ++i)
if (iteration->m_isProgressive) {
int skippedTaskCount = 0;
for (int i = iteration->currentLimit();
i < int(container->m_containerNode.m_children.size()); ++i) {
skippedTaskCount += container->m_containerNode.m_children.at(i).taskCount();
}
// TODO: Handle progress well
// How to advance skipped tasks inside nested iterations?
advanceProgress(skippedTaskCount);
}
}
}
static bool shouldCall(CallDoneIf callDoneIf, DoneWith result)
@@ -1861,7 +1875,7 @@ SetupResult TaskTreePrivate::start(RuntimeTask *node)
? invokeHandler(node->m_parentIteration, handler.m_setupHandler, *node->m_task.get())
: SetupResult::Continue;
if (startAction != SetupResult::Continue) {
// TODO: Handle progress well
if (node->m_parentIteration->m_isProgressive)
advanceProgress(1);
node->m_task.reset();
return startAction;
@@ -1908,7 +1922,7 @@ bool TaskTreePrivate::invokeDoneHandler(RuntimeTask *node, DoneWith doneWith)
result = invokeHandler(node->m_parentIteration,
handler.m_doneHandler, *node->m_task.get(), doneWith);
}
// TODO: Handle progress well
if (node->m_parentIteration->m_isProgressive)
advanceProgress(1);
return result == DoneResult::Success;
}