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