forked from qt-creator/qt-creator
TaskTree: Get rid of onGroupError element
Make it possible to setup onGroupDone element with additional OnDone argument. The onGroupDone handler may accept extra DoneResult argument. The onGroupDone handler may also tweak the success bit of a group. All above features conform to the behavior of the task done handler. Task-number: QTCREATORBUG-29834 Change-Id: I125bdfe155e585678fb33410632246401cbc9390 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -707,6 +707,8 @@ private:
|
||||
\sa onGroupDone(), onGroupError()
|
||||
*/
|
||||
|
||||
// TODO: Fix docs
|
||||
|
||||
/*!
|
||||
\fn template <typename SetupHandler> GroupItem onGroupSetup(SetupHandler &&handler)
|
||||
|
||||
@@ -726,6 +728,8 @@ private:
|
||||
\sa GroupItem::GroupSetupHandler, onGroupDone(), onGroupError()
|
||||
*/
|
||||
|
||||
// TODO: Fix docs
|
||||
|
||||
/*!
|
||||
Constructs a group's element holding the group done handler.
|
||||
The \a handler is invoked whenever the group finishes with success.
|
||||
@@ -740,10 +744,8 @@ private:
|
||||
|
||||
\sa GroupItem::GroupEndHandler, onGroupSetup(), onGroupError()
|
||||
*/
|
||||
GroupItem onGroupDone(const GroupItem::GroupEndHandler &handler)
|
||||
{
|
||||
return Group::onGroupDone(handler);
|
||||
}
|
||||
|
||||
// TODO: Fix docs
|
||||
|
||||
/*!
|
||||
Constructs a group's element holding the group error handler.
|
||||
@@ -759,10 +761,6 @@ GroupItem onGroupDone(const GroupItem::GroupEndHandler &handler)
|
||||
|
||||
\sa GroupItem::GroupEndHandler, onGroupSetup(), onGroupDone()
|
||||
*/
|
||||
GroupItem onGroupError(const GroupItem::GroupEndHandler &handler)
|
||||
{
|
||||
return Group::onGroupError(handler);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a group's element describing the \l{Execution Mode}{execution mode}.
|
||||
@@ -924,12 +922,6 @@ void GroupItem::addChildren(const QList<GroupItem> &children)
|
||||
m_groupData.m_groupHandler.m_doneHandler
|
||||
= child.m_groupData.m_groupHandler.m_doneHandler;
|
||||
}
|
||||
if (child.m_groupData.m_groupHandler.m_errorHandler) {
|
||||
QTC_ASSERT(!m_groupData.m_groupHandler.m_errorHandler,
|
||||
qWarning("Group Error Handler redefinition, overriding..."));
|
||||
m_groupData.m_groupHandler.m_errorHandler
|
||||
= child.m_groupData.m_groupHandler.m_errorHandler;
|
||||
}
|
||||
if (child.m_groupData.m_parallelLimit) {
|
||||
QTC_ASSERT(!m_groupData.m_parallelLimit,
|
||||
qWarning("Group Execution Mode redefinition, overriding..."));
|
||||
@@ -954,7 +946,7 @@ void GroupItem::addChildren(const QList<GroupItem> &children)
|
||||
}
|
||||
|
||||
GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout,
|
||||
const GroupEndHandler &handler)
|
||||
const std::function<void()> &handler)
|
||||
{
|
||||
const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; };
|
||||
return Group {
|
||||
@@ -1032,7 +1024,7 @@ public:
|
||||
SetupResult startChildren(int nextChild);
|
||||
SetupResult childDone(bool success);
|
||||
void stop();
|
||||
void invokeEndHandler();
|
||||
bool invokeDoneHandler(DoneWith result);
|
||||
bool isRunning() const { return m_runtimeData.has_value(); }
|
||||
bool isStarting() const { return isRunning() && m_runtimeData->m_startGuard.isLocked(); }
|
||||
|
||||
@@ -1329,14 +1321,14 @@ SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild)
|
||||
: startAction;
|
||||
QTC_CHECK(isRunning()); // TODO: superfluous
|
||||
if (groupAction != SetupResult::Continue) {
|
||||
const bool success = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithDone);
|
||||
invokeEndHandler();
|
||||
const bool bit = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithDone);
|
||||
const bool result = invokeDoneHandler(bit ? DoneWith::Success : DoneWith::Error);
|
||||
if (TaskContainer *parentContainer = m_constData.m_parentContainer) {
|
||||
QTC_CHECK(parentContainer->isRunning());
|
||||
if (!parentContainer->isStarting())
|
||||
parentContainer->childDone(success);
|
||||
parentContainer->childDone(result);
|
||||
} else {
|
||||
m_constData.m_taskTreePrivate->emitDone(success ? DoneWith::Success : DoneWith::Error);
|
||||
m_constData.m_taskTreePrivate->emitDone(result ? DoneWith::Success : DoneWith::Error);
|
||||
}
|
||||
}
|
||||
return groupAction;
|
||||
@@ -1406,15 +1398,22 @@ void TaskContainer::stop()
|
||||
m_constData.m_taskTreePrivate->advanceProgress(skippedTaskCount);
|
||||
}
|
||||
|
||||
void TaskContainer::invokeEndHandler()
|
||||
static bool shouldCall(CallDoneIf callDoneIf, DoneWith result)
|
||||
{
|
||||
if (result == DoneWith::Success)
|
||||
return callDoneIf != CallDoneIf::Error;
|
||||
return callDoneIf != CallDoneIf::Success;
|
||||
}
|
||||
|
||||
bool TaskContainer::invokeDoneHandler(DoneWith result)
|
||||
{
|
||||
bool success = result == DoneWith::Success;
|
||||
const GroupItem::GroupHandler &groupHandler = m_constData.m_groupHandler;
|
||||
if (m_runtimeData->m_successBit && groupHandler.m_doneHandler)
|
||||
invokeHandler(this, groupHandler.m_doneHandler);
|
||||
else if (!m_runtimeData->m_successBit && groupHandler.m_errorHandler)
|
||||
invokeHandler(this, groupHandler.m_errorHandler);
|
||||
if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, result))
|
||||
success = invokeHandler(this, groupHandler.m_doneHandler, result);
|
||||
m_runtimeData->callStorageDoneHandlers();
|
||||
m_runtimeData.reset();
|
||||
return success;
|
||||
}
|
||||
|
||||
SetupResult TaskNode::start()
|
||||
@@ -1457,7 +1456,7 @@ void TaskNode::stop()
|
||||
if (!m_task) {
|
||||
m_container.stop();
|
||||
m_container.m_runtimeData->updateSuccessBit(false);
|
||||
m_container.invokeEndHandler();
|
||||
m_container.invokeDoneHandler(DoneWith::Cancel);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1467,13 +1466,6 @@ void TaskNode::stop()
|
||||
m_task.reset();
|
||||
}
|
||||
|
||||
static bool shouldCall(CallDoneIf callDoneIf, DoneWith result)
|
||||
{
|
||||
if (result == DoneWith::Success)
|
||||
return callDoneIf != CallDoneIf::Error;
|
||||
return callDoneIf != CallDoneIf::Success;
|
||||
}
|
||||
|
||||
bool TaskNode::invokeDoneHandler(DoneWith result)
|
||||
{
|
||||
bool success = result == DoneWith::Success;
|
||||
|
@@ -157,10 +157,10 @@ public:
|
||||
using TaskSetupHandler = std::function<SetupResult(TaskInterface &)>;
|
||||
// Called on task done, just before deleteLater
|
||||
using TaskDoneHandler = std::function<bool(const TaskInterface &, DoneWith)>;
|
||||
// Called when group entered
|
||||
// Called when group entered, after group's storages are created
|
||||
using GroupSetupHandler = std::function<SetupResult()>;
|
||||
// Called when group done / error
|
||||
using GroupEndHandler = std::function<void()>;
|
||||
// Called when group done, before group's storages are deleted
|
||||
using GroupDoneHandler = std::function<bool(DoneWith)>;
|
||||
|
||||
struct TaskHandler {
|
||||
TaskCreateHandler m_createHandler;
|
||||
@@ -171,8 +171,8 @@ public:
|
||||
|
||||
struct GroupHandler {
|
||||
GroupSetupHandler m_setupHandler;
|
||||
GroupEndHandler m_doneHandler = {};
|
||||
GroupEndHandler m_errorHandler = {};
|
||||
GroupDoneHandler m_doneHandler = {};
|
||||
CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError;
|
||||
};
|
||||
|
||||
struct GroupData {
|
||||
@@ -210,7 +210,7 @@ protected:
|
||||
static GroupItem parallelLimit(int limit) { return GroupItem({{}, limit}); }
|
||||
static GroupItem workflowPolicy(WorkflowPolicy policy) { return GroupItem({{}, {}, policy}); }
|
||||
static GroupItem withTimeout(const GroupItem &item, std::chrono::milliseconds timeout,
|
||||
const GroupEndHandler &handler = {});
|
||||
const std::function<void()> &handler = {});
|
||||
|
||||
private:
|
||||
Type m_type = Type::Group;
|
||||
@@ -227,32 +227,30 @@ public:
|
||||
Group(std::initializer_list<GroupItem> children) { addChildren(children); }
|
||||
|
||||
// GroupData related:
|
||||
template <typename SetupHandler>
|
||||
static GroupItem onGroupSetup(SetupHandler &&handler) {
|
||||
return groupHandler({wrapGroupSetup(std::forward<SetupHandler>(handler))});
|
||||
template <typename Handler>
|
||||
static GroupItem onGroupSetup(Handler &&handler) {
|
||||
return groupHandler({wrapGroupSetup(std::forward<Handler>(handler))});
|
||||
}
|
||||
static GroupItem onGroupDone(const GroupEndHandler &handler) {
|
||||
return groupHandler({{}, handler});
|
||||
}
|
||||
static GroupItem onGroupError(const GroupEndHandler &handler) {
|
||||
return groupHandler({{}, {}, handler});
|
||||
template <typename Handler>
|
||||
static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) {
|
||||
return groupHandler({{}, wrapGroupDone(std::forward<Handler>(handler)), callDoneIf});
|
||||
}
|
||||
using GroupItem::parallelLimit; // Default: 1 (sequential). 0 means unlimited (parallel).
|
||||
using GroupItem::workflowPolicy; // Default: WorkflowPolicy::StopOnError.
|
||||
|
||||
GroupItem withTimeout(std::chrono::milliseconds timeout,
|
||||
const GroupEndHandler &handler = {}) const {
|
||||
const std::function<void()> &handler = {}) const {
|
||||
return GroupItem::withTimeout(*this, timeout, handler);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename SetupHandler>
|
||||
static GroupSetupHandler wrapGroupSetup(SetupHandler &&handler)
|
||||
template<typename Handler>
|
||||
static GroupSetupHandler wrapGroupSetup(Handler &&handler)
|
||||
{
|
||||
static constexpr bool isDynamic
|
||||
= std::is_same_v<SetupResult, std::invoke_result_t<std::decay_t<SetupHandler>>>;
|
||||
= std::is_same_v<SetupResult, std::invoke_result_t<std::decay_t<Handler>>>;
|
||||
constexpr bool isVoid
|
||||
= std::is_same_v<void, std::invoke_result_t<std::decay_t<SetupHandler>>>;
|
||||
= std::is_same_v<void, std::invoke_result_t<std::decay_t<Handler>>>;
|
||||
static_assert(isDynamic || isVoid,
|
||||
"Group setup handler needs to take no arguments and has to return "
|
||||
"void or SetupResult. The passed handler doesn't fulfill these requirements.");
|
||||
@@ -263,16 +261,49 @@ private:
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
};
|
||||
template<typename Handler>
|
||||
static GroupDoneHandler wrapGroupDone(Handler &&handler)
|
||||
{
|
||||
static constexpr bool isBD // stands for [B]ool, [D]oneWith
|
||||
= std::is_invocable_r_v<bool, std::decay_t<Handler>, DoneWith>;
|
||||
static constexpr bool isB
|
||||
= std::is_invocable_r_v<bool, std::decay_t<Handler>>;
|
||||
static constexpr bool isVD // stands for [V]oid, [D]oneWith
|
||||
= std::is_invocable_r_v<void, std::decay_t<Handler>, DoneWith>;
|
||||
static constexpr bool isV
|
||||
= std::is_invocable_r_v<void, std::decay_t<Handler>>;
|
||||
static constexpr bool isInvocable = isBD || isB || isVD || isV;
|
||||
|
||||
static_assert(isInvocable,
|
||||
"Group done handler needs to take (DoneWith) or (void) "
|
||||
"as arguments and has to return void or bool. "
|
||||
"The passed handler doesn't fulfill these requirements.");
|
||||
return [=](DoneWith result) {
|
||||
if constexpr (isBD)
|
||||
return std::invoke(handler, result);
|
||||
if constexpr (isB)
|
||||
return std::invoke(handler);
|
||||
if constexpr (isVD)
|
||||
std::invoke(handler, result);
|
||||
else if constexpr (isV)
|
||||
std::invoke(handler);
|
||||
return result == DoneWith::Success;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <typename SetupHandler>
|
||||
static GroupItem onGroupSetup(SetupHandler &&handler)
|
||||
template <typename Handler>
|
||||
static GroupItem onGroupSetup(Handler &&handler)
|
||||
{
|
||||
return Group::onGroupSetup(std::forward<SetupHandler>(handler));
|
||||
return Group::onGroupSetup(std::forward<Handler>(handler));
|
||||
}
|
||||
|
||||
template <typename Handler>
|
||||
static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
|
||||
{
|
||||
return Group::onGroupDone(std::forward<Handler>(handler), callDoneIf);
|
||||
}
|
||||
|
||||
TASKING_EXPORT GroupItem onGroupDone(const GroupItem::GroupEndHandler &handler);
|
||||
TASKING_EXPORT GroupItem onGroupError(const GroupItem::GroupEndHandler &handler);
|
||||
TASKING_EXPORT GroupItem parallelLimit(int limit);
|
||||
TASKING_EXPORT GroupItem workflowPolicy(WorkflowPolicy policy);
|
||||
|
||||
@@ -354,7 +385,8 @@ public:
|
||||
{}
|
||||
|
||||
GroupItem withTimeout(std::chrono::milliseconds timeout,
|
||||
const GroupEndHandler &handler = {}) const {
|
||||
const std::function<void()> &handler = {}) const
|
||||
{
|
||||
return GroupItem::withTimeout(*this, timeout, handler);
|
||||
}
|
||||
|
||||
|
@@ -834,7 +834,7 @@ Tasking::GroupItem AndroidBuildApkStep::runRecipe()
|
||||
|
||||
const Group root {
|
||||
onGroupSetup(onSetup),
|
||||
onGroupDone(onDone),
|
||||
onGroupDone(onDone, CallDoneIf::Success),
|
||||
defaultProcessTask()
|
||||
};
|
||||
return root;
|
||||
|
@@ -94,9 +94,12 @@ Tasking::GroupItem AutogenStep::runRecipe()
|
||||
}
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDone = [this] { m_runAutogen = false; };
|
||||
|
||||
return Group { onGroupSetup(onSetup), onGroupDone(onDone), defaultProcessTask() };
|
||||
return Group {
|
||||
onGroupSetup(onSetup),
|
||||
onGroupDone([this] { m_runAutogen = false; }, CallDoneIf::Success),
|
||||
defaultProcessTask()
|
||||
};
|
||||
}
|
||||
|
||||
// AutogenStepFactory
|
||||
|
@@ -79,9 +79,12 @@ private:
|
||||
}
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDone = [this] { m_runAutoreconf = false; };
|
||||
|
||||
return Group { onGroupSetup(onSetup), onGroupDone(onDone), defaultProcessTask() };
|
||||
return Group {
|
||||
onGroupSetup(onSetup),
|
||||
onGroupDone([this] { m_runAutoreconf = false; }, CallDoneIf::Success),
|
||||
defaultProcessTask()
|
||||
};
|
||||
}
|
||||
|
||||
bool m_runAutoreconf = false;
|
||||
|
@@ -98,9 +98,12 @@ Tasking::GroupItem ConfigureStep::runRecipe()
|
||||
}
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDone = [this] { m_runConfigure = false; };
|
||||
|
||||
return Group { onGroupSetup(onSetup), onGroupDone(onDone), defaultProcessTask() };
|
||||
return Group {
|
||||
onGroupSetup(onSetup),
|
||||
onGroupDone([this] { m_runConfigure = false; }, CallDoneIf::Success),
|
||||
defaultProcessTask()
|
||||
};
|
||||
}
|
||||
|
||||
// ConfigureStepFactory
|
||||
|
@@ -369,15 +369,11 @@ GroupItem CMakeBuildStep::runRecipe()
|
||||
emit addOutput(Tr::tr("Project did not parse successfully, cannot build."),
|
||||
OutputFormat::ErrorMessage);
|
||||
};
|
||||
const auto onEnd = [this] {
|
||||
updateDeploymentData();
|
||||
};
|
||||
Group root {
|
||||
ignoreReturnValue() ? finishAllAndDone : stopOnError,
|
||||
ProjectParserTask(onParserSetup, onParserError, CallDoneIf::Error),
|
||||
defaultProcessTask(),
|
||||
onGroupDone(onEnd),
|
||||
onGroupError(onEnd)
|
||||
onGroupDone([this] { updateDeploymentData(); })
|
||||
};
|
||||
return root;
|
||||
}
|
||||
|
@@ -457,10 +457,6 @@ void LocatorMatcher::start()
|
||||
};
|
||||
};
|
||||
|
||||
const auto onDone = [](const TreeStorage<LocatorStorage> &storage) {
|
||||
return [storage] { storage->finalize(); };
|
||||
};
|
||||
|
||||
int index = 0;
|
||||
for (const LocatorMatcherTask &task : std::as_const(d->m_tasks)) {
|
||||
const auto storage = task.storage;
|
||||
@@ -468,8 +464,7 @@ void LocatorMatcher::start()
|
||||
finishAllAndDone,
|
||||
Storage(storage),
|
||||
onGroupSetup(onSetup(storage, index)),
|
||||
onGroupDone(onDone(storage)),
|
||||
onGroupError(onDone(storage)),
|
||||
onGroupDone([storage] { storage->finalize(); }),
|
||||
task.task
|
||||
};
|
||||
parallelTasks << group;
|
||||
|
@@ -390,7 +390,7 @@ void Locator::refresh(const QList<ILocatorFilter *> &filters)
|
||||
const Group group {
|
||||
finishAllAndDone,
|
||||
*task,
|
||||
onGroupDone([this, filter] { m_refreshingFilters.removeOne(filter); })
|
||||
onGroupDone([this, filter] { m_refreshingFilters.removeOne(filter); }, CallDoneIf::Success)
|
||||
};
|
||||
tasks.append(group);
|
||||
}
|
||||
|
@@ -68,7 +68,10 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo,
|
||||
tasks.append(compiler->compileFileItem());
|
||||
}
|
||||
|
||||
const auto onDone = [this, storage, compilers] {
|
||||
const auto onDone = [this, storage, compilers](DoneWith result) {
|
||||
m_taskTree.release()->deleteLater();
|
||||
if (result != DoneWith::Success)
|
||||
return;
|
||||
QList<ExtraCompiler *> extraCompilers;
|
||||
QSet<FilePath> compilerFiles;
|
||||
for (const QPointer<ExtraCompiler> &compiler : compilers) {
|
||||
@@ -80,17 +83,12 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo,
|
||||
GeneratedCodeModelSupport::update(extraCompilers);
|
||||
auto updateFuture = CppModelManager::updateProjectInfo(storage->projectInfo, compilerFiles);
|
||||
m_futureSynchronizer.addFuture(updateFuture);
|
||||
m_taskTree.release()->deleteLater();
|
||||
};
|
||||
const auto onError = [this] {
|
||||
m_taskTree.release()->deleteLater();
|
||||
};
|
||||
|
||||
const Group root {
|
||||
Tasking::Storage(storage),
|
||||
Group(tasks),
|
||||
onGroupDone(onDone),
|
||||
onGroupError(onError)
|
||||
onGroupDone(onDone)
|
||||
};
|
||||
m_taskTree.reset(new TaskTree(root));
|
||||
auto progress = new Core::TaskProgress(m_taskTree.get());
|
||||
|
@@ -132,24 +132,21 @@ DiffFilesController::DiffFilesController(IDocument *document)
|
||||
}
|
||||
taskTree.setRecipe(tasks);
|
||||
};
|
||||
const auto onTreeDone = [this, storage] {
|
||||
const QList<std::optional<FileData>> &results = *storage;
|
||||
const auto onTreeDone = [this, storage](DoneWith result) {
|
||||
QList<FileData> finalList;
|
||||
for (const std::optional<FileData> &result : results) {
|
||||
if (result.has_value())
|
||||
finalList.append(*result);
|
||||
if (result == DoneWith::Success) {
|
||||
const QList<std::optional<FileData>> &results = *storage;
|
||||
for (const std::optional<FileData> &result : results) {
|
||||
if (result.has_value())
|
||||
finalList.append(*result);
|
||||
}
|
||||
}
|
||||
setDiffFiles(finalList);
|
||||
};
|
||||
const auto onTreeError = [this, storage] {
|
||||
setDiffFiles({});
|
||||
};
|
||||
|
||||
const Group root = {
|
||||
Storage(storage),
|
||||
TaskTreeTask(onTreeSetup),
|
||||
onGroupDone(onTreeDone),
|
||||
onGroupError(onTreeError)
|
||||
TaskTreeTask(onTreeSetup, onTreeDone)
|
||||
};
|
||||
setReloadRecipe(root);
|
||||
}
|
||||
|
@@ -468,8 +468,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError)
|
||||
const Group root {
|
||||
topRevisionProc,
|
||||
ProcessTask(onForEachRefSetup, onForEachRefDone),
|
||||
onGroupDone(finalize),
|
||||
onGroupError(finalize)
|
||||
onGroupDone(finalize)
|
||||
};
|
||||
d->refreshTask.reset(new TaskTree(root));
|
||||
d->refreshTask->start();
|
||||
|
@@ -568,7 +568,7 @@ TaskTree *BranchView::onFastForwardMerge(const std::function<void()> &callback)
|
||||
onGroupDone([storage, callback] {
|
||||
if (storage->mergeBase == storage->topRevision)
|
||||
callback();
|
||||
})
|
||||
}, CallDoneIf::Success)
|
||||
};
|
||||
auto taskTree = new TaskTree(root);
|
||||
taskTree->start();
|
||||
|
@@ -340,7 +340,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin
|
||||
continueOnDone,
|
||||
ProcessTask(onStagedSetup, onStagedDone, CallDoneIf::Success),
|
||||
ProcessTask(onUnstagedSetup, onUnstagedDone, CallDoneIf::Success),
|
||||
onGroupDone(onDone)
|
||||
onGroupDone(onDone, CallDoneIf::Success)
|
||||
},
|
||||
postProcessTask(diffInputStorage)
|
||||
};
|
||||
@@ -498,7 +498,11 @@ ShowController::ShowController(IDocument *document, const QString &id)
|
||||
updateDescription(*data);
|
||||
};
|
||||
|
||||
QList<GroupItem> tasks { parallel, continueOnDone, onGroupError(onFollowsError) };
|
||||
QList<GroupItem> tasks {
|
||||
parallel,
|
||||
continueOnDone,
|
||||
onGroupDone(onFollowsError, CallDoneIf::Error)
|
||||
};
|
||||
for (int i = 0, total = parents.size(); i < total; ++i) {
|
||||
const auto onFollowSetup = [this, parent = parents.at(i)](Process &process) {
|
||||
setupCommand(process, {"describe", "--tags", "--abbrev=0", parent});
|
||||
|
@@ -648,15 +648,14 @@ void BuildManager::startBuildQueue()
|
||||
if (d->m_futureProgress)
|
||||
d->m_futureProgress.data()->setTitle(name);
|
||||
};
|
||||
const auto onRecipeDone = [buildStep] {
|
||||
const auto onRecipeDone = [buildStep, target](DoneWith result) {
|
||||
disconnect(buildStep, &BuildStep::progress, instance(), nullptr);
|
||||
d->m_outputWindow->flush();
|
||||
++d->m_progress;
|
||||
d->m_progressFutureInterface->setProgressValueAndText(
|
||||
100 * d->m_progress, msgProgress(d->m_progress, d->m_maxProgress));
|
||||
};
|
||||
const auto onRecipeError = [buildStep, target, onRecipeDone] {
|
||||
onRecipeDone();
|
||||
if (result == DoneWith::Success)
|
||||
return;
|
||||
const QString projectName = buildStep->project()->displayName();
|
||||
const QString targetName = target->displayName();
|
||||
addToOutputWindow(Tr::tr("Error while building/deploying project %1 (kit: %2)")
|
||||
@@ -673,8 +672,7 @@ void BuildManager::startBuildQueue()
|
||||
const Group recipeGroup {
|
||||
onGroupSetup(onRecipeSetup),
|
||||
buildStep->runRecipe(),
|
||||
onGroupDone(onRecipeDone),
|
||||
onGroupError(onRecipeError),
|
||||
onGroupDone(onRecipeDone)
|
||||
};
|
||||
targetTasks.append(recipeGroup);
|
||||
}
|
||||
|
@@ -229,7 +229,7 @@ Tasking::GroupItem QmakeMakeStep::runRecipe()
|
||||
return Group {
|
||||
ignoreReturnValue() ? finishAllAndDone : stopOnError,
|
||||
onGroupSetup(onSetup),
|
||||
onGroupError(onError),
|
||||
onGroupDone(onError, CallDoneIf::Error),
|
||||
defaultProcessTask()
|
||||
};
|
||||
}
|
||||
|
@@ -299,7 +299,7 @@ Tasking::GroupItem QMakeStep::runRecipe()
|
||||
};
|
||||
|
||||
QList<GroupItem> processList = {onGroupSetup(onSetup),
|
||||
onGroupDone(onDone),
|
||||
onGroupDone(onDone, CallDoneIf::Success),
|
||||
ProcessTask(onQMakeSetup, onProcessDone)};
|
||||
if (m_runMakeQmake)
|
||||
processList << ProcessTask(onMakeQMakeSetup, onProcessDone);
|
||||
|
@@ -272,7 +272,7 @@ Group QnxDeployQtLibrariesDialogPrivate::deployRecipe()
|
||||
uploadTask(),
|
||||
chmodTree()
|
||||
},
|
||||
onGroupDone(doneHandler)
|
||||
onGroupDone(doneHandler, CallDoneIf::Success)
|
||||
};
|
||||
return root;
|
||||
}
|
||||
|
@@ -148,17 +148,16 @@ GroupItem AbstractRemoteLinuxDeployStep::runRecipe()
|
||||
}
|
||||
return SetupResult::Continue;
|
||||
};
|
||||
const auto onDone = [this] {
|
||||
emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage);
|
||||
};
|
||||
const auto onError = [this] {
|
||||
emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage);
|
||||
const auto onDone = [this](DoneWith result) {
|
||||
if (result == DoneWith::Success)
|
||||
emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage);
|
||||
else
|
||||
emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage);
|
||||
};
|
||||
return Group {
|
||||
onGroupSetup(onSetup),
|
||||
deployRecipe(),
|
||||
onGroupDone(onDone),
|
||||
onGroupError(onError)
|
||||
onGroupDone(onDone)
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -297,7 +297,7 @@ GroupItem GenericDirectUploadStep::deployRecipe()
|
||||
uploadTask(storage),
|
||||
chmodTree(storage),
|
||||
statTree(storage, postFilesToStat, postStatEndHandler),
|
||||
onGroupDone(doneHandler)
|
||||
onGroupDone(doneHandler, CallDoneIf::Success)
|
||||
};
|
||||
return root;
|
||||
}
|
||||
|
@@ -227,16 +227,17 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho
|
||||
GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const
|
||||
{
|
||||
TreeStorage<TransferStorage> storage;
|
||||
return Group{continueOnDone,
|
||||
Tasking::Storage(storage),
|
||||
transferTask(FileTransferMethod::GenericCopy, storage),
|
||||
transferTask(FileTransferMethod::Sftp, storage),
|
||||
transferTask(FileTransferMethod::Rsync, storage),
|
||||
onGroupError([this] {
|
||||
emit q->errorMessage(Tr::tr("Deployment to this device will not "
|
||||
"work out of the box.")
|
||||
+ "\n");
|
||||
})};
|
||||
return Group {
|
||||
continueOnDone,
|
||||
Tasking::Storage(storage),
|
||||
transferTask(FileTransferMethod::GenericCopy, storage),
|
||||
transferTask(FileTransferMethod::Sftp, storage),
|
||||
transferTask(FileTransferMethod::Rsync, storage),
|
||||
onGroupDone([this] {
|
||||
emit q->errorMessage(Tr::tr("Deployment to this device will not work out of the box.")
|
||||
+ "\n");
|
||||
}, CallDoneIf::Error)
|
||||
};
|
||||
}
|
||||
|
||||
GroupItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandName) const
|
||||
@@ -299,8 +300,8 @@ void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguratio
|
||||
|
||||
d->m_device = deviceConfiguration;
|
||||
|
||||
auto allFinished = [this](DeviceTester::TestResult testResult) {
|
||||
emit finished(testResult);
|
||||
auto onDone = [this](DoneWith result) {
|
||||
emit finished(result == DoneWith::Success ? TestSuccess : TestFailure);
|
||||
d->m_taskTree.release()->deleteLater();
|
||||
};
|
||||
|
||||
@@ -313,9 +314,7 @@ void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguratio
|
||||
};
|
||||
if (!d->m_extraTests.isEmpty())
|
||||
taskItems << Group { d->m_extraTests };
|
||||
taskItems << d->commandTasks()
|
||||
<< onGroupDone(std::bind(allFinished, TestSuccess))
|
||||
<< onGroupError(std::bind(allFinished, TestFailure));
|
||||
taskItems << d->commandTasks() << onGroupDone(onDone);
|
||||
|
||||
d->m_taskTree.reset(new TaskTree(taskItems));
|
||||
d->m_taskTree->start();
|
||||
|
@@ -192,7 +192,14 @@ Tasking::GroupItem MakeInstallStep::runRecipe()
|
||||
{
|
||||
using namespace Tasking;
|
||||
|
||||
const auto onDone = [this] {
|
||||
const auto onDone = [this](DoneWith result) {
|
||||
if (result != DoneWith::Success) {
|
||||
if (m_noInstallTarget && m_isCmakeProject) {
|
||||
emit addTask(DeploymentTask(Task::Warning, Tr::tr("You need to add an install "
|
||||
"statement to your CMakeLists.txt file for deployment to work.")));
|
||||
}
|
||||
return;
|
||||
}
|
||||
const FilePath rootDir = makeCommand().withNewPath(m_installRoot().path()); // FIXME: Needed?
|
||||
|
||||
m_deploymentData = DeploymentData();
|
||||
@@ -215,14 +222,8 @@ Tasking::GroupItem MakeInstallStep::runRecipe()
|
||||
|
||||
buildSystem()->setDeploymentData(m_deploymentData);
|
||||
};
|
||||
const auto onError = [this] {
|
||||
if (m_noInstallTarget && m_isCmakeProject) {
|
||||
emit addTask(DeploymentTask(Task::Warning, Tr::tr("You need to add an install "
|
||||
"statement to your CMakeLists.txt file for deployment to work.")));
|
||||
}
|
||||
};
|
||||
|
||||
return Group { onGroupDone(onDone), onGroupError(onError), defaultProcessTask() };
|
||||
return Group { onGroupDone(onDone), defaultProcessTask() };
|
||||
}
|
||||
|
||||
void MakeInstallStep::updateCommandFromAspect()
|
||||
|
@@ -24,7 +24,7 @@ enum class Handler {
|
||||
Canceled,
|
||||
GroupSetup,
|
||||
GroupSuccess,
|
||||
GroupError,
|
||||
GroupError, // TODO: Add GroupCanceled
|
||||
Sync,
|
||||
BarrierAdvance,
|
||||
Timeout
|
||||
@@ -116,8 +116,7 @@ void tst_Tasking::validConstructs()
|
||||
}
|
||||
},
|
||||
task,
|
||||
onGroupDone([] {}),
|
||||
onGroupError([] {})
|
||||
onGroupDone([] {})
|
||||
};
|
||||
|
||||
const auto setupHandler = [](TaskObject &) {};
|
||||
@@ -213,6 +212,11 @@ GroupItem createBarrierAdvance(const TreeStorage<CustomStorage> &storage,
|
||||
});
|
||||
}
|
||||
|
||||
static Handler resultToGroupHandler(DoneWith result)
|
||||
{
|
||||
return result == DoneWith::Success ? Handler::GroupSuccess : Handler::GroupError;
|
||||
}
|
||||
|
||||
void tst_Tasking::testTree_data()
|
||||
{
|
||||
QTest::addColumn<TestData>("testData");
|
||||
@@ -267,13 +271,14 @@ void tst_Tasking::testTree_data()
|
||||
};
|
||||
|
||||
const auto groupSetup = [storage](int taskId) {
|
||||
return onGroupSetup([=] { storage->m_log.append({taskId, Handler::GroupSetup}); });
|
||||
return onGroupSetup([storage, taskId] {
|
||||
storage->m_log.append({taskId, Handler::GroupSetup});
|
||||
});
|
||||
};
|
||||
const auto groupDone = [storage](int taskId) {
|
||||
return onGroupDone([=] { storage->m_log.append({taskId, Handler::GroupSuccess}); });
|
||||
};
|
||||
const auto groupError = [storage](int taskId) {
|
||||
return onGroupError([=] { storage->m_log.append({taskId, Handler::GroupError}); });
|
||||
return onGroupDone([storage, taskId](DoneWith result) {
|
||||
storage->m_log.append({taskId, resultToGroupHandler(result)});
|
||||
});
|
||||
};
|
||||
const auto createSync = [storage](int taskId) {
|
||||
return Sync([=] { storage->m_log.append({taskId, Handler::Sync}); });
|
||||
@@ -285,26 +290,22 @@ void tst_Tasking::testTree_data()
|
||||
{
|
||||
const Group root1 {
|
||||
Storage(storage),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
const Group root2 {
|
||||
Storage(storage),
|
||||
onGroupSetup([] { return SetupResult::Continue; }),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
const Group root3 {
|
||||
Storage(storage),
|
||||
onGroupSetup([] { return SetupResult::StopWithDone; }),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
const Group root4 {
|
||||
Storage(storage),
|
||||
onGroupSetup([] { return SetupResult::StopWithError; }),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
|
||||
const Log logDone {{0, Handler::GroupSuccess}};
|
||||
@@ -322,8 +323,7 @@ void tst_Tasking::testTree_data()
|
||||
Storage(storage),
|
||||
workflowPolicy(policy),
|
||||
onGroupSetup([setupResult] { return setupResult; }),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -641,8 +641,7 @@ void tst_Tasking::testTree_data()
|
||||
createFailingTask(3),
|
||||
createSuccessTask(4),
|
||||
createSuccessTask(5),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Setup},
|
||||
@@ -657,12 +656,11 @@ void tst_Tasking::testTree_data()
|
||||
}
|
||||
|
||||
{
|
||||
const auto createRoot = [storage, groupDone, groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, groupDone](WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
workflowPolicy(policy),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -699,14 +697,13 @@ void tst_Tasking::testTree_data()
|
||||
}
|
||||
|
||||
{
|
||||
const auto createRoot = [storage, createSuccessTask, groupDone, groupError](
|
||||
const auto createRoot = [storage, createSuccessTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
workflowPolicy(policy),
|
||||
createSuccessTask(1),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -752,14 +749,13 @@ void tst_Tasking::testTree_data()
|
||||
}
|
||||
|
||||
{
|
||||
const auto createRoot = [storage, createFailingTask, groupDone, groupError](
|
||||
const auto createRoot = [storage, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
workflowPolicy(policy),
|
||||
createFailingTask(1),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -808,16 +804,15 @@ void tst_Tasking::testTree_data()
|
||||
// These tests check whether the proper root's group end handler is called
|
||||
// when the group is stopped. Test it with different workflow policies.
|
||||
// The root starts one short failing task together with one long task.
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone,
|
||||
groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
parallel,
|
||||
workflowPolicy(policy),
|
||||
createFailingTask(1, 1ms),
|
||||
createSuccessTask(2, 1ms),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -879,8 +874,8 @@ void tst_Tasking::testTree_data()
|
||||
// when the group is stopped. Test it with different workflow policies.
|
||||
// The root starts in parallel: one very short successful task, one short failing task
|
||||
// and one long task.
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone,
|
||||
groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
parallel,
|
||||
@@ -888,8 +883,7 @@ void tst_Tasking::testTree_data()
|
||||
createSuccessTask(1),
|
||||
createFailingTask(2, 1ms),
|
||||
createSuccessTask(3, 1ms),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -966,24 +960,22 @@ void tst_Tasking::testTree_data()
|
||||
// These tests check whether the proper subgroup's end handler is called
|
||||
// when the group is stopped. Test it with different workflow policies.
|
||||
// The subgroup starts one long task.
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone,
|
||||
groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
parallel,
|
||||
Group {
|
||||
workflowPolicy(policy),
|
||||
createSuccessTask(1, 1000ms),
|
||||
groupDone(1),
|
||||
groupError(1)
|
||||
groupDone(1)
|
||||
},
|
||||
createFailingTask(2, 1ms),
|
||||
groupDone(2),
|
||||
groupError(2)
|
||||
groupDone(2)
|
||||
};
|
||||
};
|
||||
|
||||
const Log errorLog = {
|
||||
const Log log = {
|
||||
{1, Handler::Setup},
|
||||
{2, Handler::Setup},
|
||||
{2, Handler::Error},
|
||||
@@ -992,50 +984,43 @@ void tst_Tasking::testTree_data()
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Log doneLog = {
|
||||
{1, Handler::Setup},
|
||||
{2, Handler::Setup},
|
||||
{2, Handler::Error},
|
||||
{1, Handler::Canceled},
|
||||
{1, Handler::GroupSuccess},
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Group root1 = createRoot(WorkflowPolicy::StopOnError);
|
||||
QTest::newRow("StopGroupWithStopOnError")
|
||||
<< TestData{storage, root1, errorLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root1, log, 2, OnDone::Failure};
|
||||
|
||||
const Group root2 = createRoot(WorkflowPolicy::ContinueOnError);
|
||||
QTest::newRow("StopGroupWithContinueOnError")
|
||||
<< TestData{storage, root2, errorLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root2, log, 2, OnDone::Failure};
|
||||
|
||||
const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
|
||||
QTest::newRow("StopGroupWithStopOnDone")
|
||||
<< TestData{storage, root3, errorLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root3, log, 2, OnDone::Failure};
|
||||
|
||||
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
|
||||
QTest::newRow("StopGroupWithContinueOnDone")
|
||||
<< TestData{storage, root4, errorLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root4, log, 2, OnDone::Failure};
|
||||
|
||||
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
|
||||
QTest::newRow("StopGroupWithStopOnFinished")
|
||||
<< TestData{storage, root5, errorLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root5, log, 2, OnDone::Failure};
|
||||
|
||||
// TODO: Behavioral change! Fix Docs!
|
||||
// Cancellation always invokes error handler (i.e. DoneWith is Cancel)
|
||||
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
|
||||
QTest::newRow("StopGroupWithFinishAllAndDone")
|
||||
<< TestData{storage, root6, doneLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root6, log, 2, OnDone::Failure};
|
||||
|
||||
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
|
||||
QTest::newRow("StopGroupWithFinishAllAndError")
|
||||
<< TestData{storage, root7, errorLog, 2, OnDone::Failure};
|
||||
<< TestData{storage, root7, log, 2, OnDone::Failure};
|
||||
}
|
||||
|
||||
{
|
||||
// These tests check whether the proper subgroup's end handler is called
|
||||
// when the group is stopped. Test it with different workflow policies.
|
||||
// The sequential subgroup starts one short successful task followed by one long task.
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone,
|
||||
groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
parallel,
|
||||
@@ -1043,12 +1028,10 @@ void tst_Tasking::testTree_data()
|
||||
workflowPolicy(policy),
|
||||
createSuccessTask(1),
|
||||
createSuccessTask(2, 1000ms),
|
||||
groupDone(1),
|
||||
groupError(1)
|
||||
groupDone(1)
|
||||
},
|
||||
createFailingTask(3, 1ms),
|
||||
groupDone(2),
|
||||
groupError(2)
|
||||
groupDone(2)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1063,7 +1046,7 @@ void tst_Tasking::testTree_data()
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Log shortDoneLog = {
|
||||
const Log doneLog = {
|
||||
{1, Handler::Setup},
|
||||
{3, Handler::Setup},
|
||||
{1, Handler::Success},
|
||||
@@ -1072,17 +1055,6 @@ void tst_Tasking::testTree_data()
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Log longDoneLog = {
|
||||
{1, Handler::Setup},
|
||||
{3, Handler::Setup},
|
||||
{1, Handler::Success},
|
||||
{2, Handler::Setup},
|
||||
{3, Handler::Error},
|
||||
{2, Handler::Canceled},
|
||||
{1, Handler::GroupSuccess},
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Group root1 = createRoot(WorkflowPolicy::StopOnError);
|
||||
QTest::newRow("StopGroupAfterDoneWithStopOnError")
|
||||
<< TestData{storage, root1, errorLog, 3, OnDone::Failure};
|
||||
@@ -1093,19 +1065,21 @@ void tst_Tasking::testTree_data()
|
||||
|
||||
const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
|
||||
QTest::newRow("StopGroupAfterDoneWithStopOnDone")
|
||||
<< TestData{storage, root3, shortDoneLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root3, doneLog, 3, OnDone::Failure};
|
||||
|
||||
// TODO: Behavioral change!
|
||||
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
|
||||
QTest::newRow("StopGroupAfterDoneWithContinueOnDone")
|
||||
<< TestData{storage, root4, longDoneLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root4, errorLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
|
||||
QTest::newRow("StopGroupAfterDoneWithStopOnFinished")
|
||||
<< TestData{storage, root5, shortDoneLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root5, doneLog, 3, OnDone::Failure};
|
||||
|
||||
// TODO: Behavioral change!
|
||||
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
|
||||
QTest::newRow("StopGroupAfterDoneWithFinishAllAndDone")
|
||||
<< TestData{storage, root6, longDoneLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root6, errorLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
|
||||
QTest::newRow("StopGroupAfterDoneWithFinishAllAndError")
|
||||
@@ -1116,8 +1090,8 @@ void tst_Tasking::testTree_data()
|
||||
// These tests check whether the proper subgroup's end handler is called
|
||||
// when the group is stopped. Test it with different workflow policies.
|
||||
// The sequential subgroup starts one short failing task followed by one long task.
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone,
|
||||
groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
parallel,
|
||||
@@ -1125,16 +1099,14 @@ void tst_Tasking::testTree_data()
|
||||
workflowPolicy(policy),
|
||||
createFailingTask(1),
|
||||
createSuccessTask(2, 1000ms),
|
||||
groupDone(1),
|
||||
groupError(1)
|
||||
groupDone(1)
|
||||
},
|
||||
createFailingTask(3, 1ms),
|
||||
groupDone(2),
|
||||
groupError(2)
|
||||
groupDone(2)
|
||||
};
|
||||
};
|
||||
|
||||
const Log shortErrorLog = {
|
||||
const Log shortLog = {
|
||||
{1, Handler::Setup},
|
||||
{3, Handler::Setup},
|
||||
{1, Handler::Error},
|
||||
@@ -1143,7 +1115,7 @@ void tst_Tasking::testTree_data()
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Log longErrorLog = {
|
||||
const Log longLog = {
|
||||
{1, Handler::Setup},
|
||||
{3, Handler::Setup},
|
||||
{1, Handler::Error},
|
||||
@@ -1154,57 +1126,46 @@ void tst_Tasking::testTree_data()
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Log doneLog = {
|
||||
{1, Handler::Setup},
|
||||
{3, Handler::Setup},
|
||||
{1, Handler::Error},
|
||||
{2, Handler::Setup},
|
||||
{3, Handler::Error},
|
||||
{2, Handler::Canceled},
|
||||
{1, Handler::GroupSuccess},
|
||||
{2, Handler::GroupError}
|
||||
};
|
||||
|
||||
const Group root1 = createRoot(WorkflowPolicy::StopOnError);
|
||||
QTest::newRow("StopGroupAfterErrorWithStopOnError")
|
||||
<< TestData{storage, root1, shortErrorLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root1, shortLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root2 = createRoot(WorkflowPolicy::ContinueOnError);
|
||||
QTest::newRow("StopGroupAfterErrorWithContinueOnError")
|
||||
<< TestData{storage, root2, longErrorLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root2, longLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
|
||||
QTest::newRow("StopGroupAfterErrorWithStopOnDone")
|
||||
<< TestData{storage, root3, longErrorLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root3, longLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
|
||||
QTest::newRow("StopGroupAfterErrorWithContinueOnDone")
|
||||
<< TestData{storage, root4, longErrorLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root4, longLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
|
||||
QTest::newRow("StopGroupAfterErrorWithStopOnFinished")
|
||||
<< TestData{storage, root5, shortErrorLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root5, shortLog, 3, OnDone::Failure};
|
||||
|
||||
// TODO: Behavioral change!
|
||||
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
|
||||
QTest::newRow("StopGroupAfterErrorWithFinishAllAndDone")
|
||||
<< TestData{storage, root6, doneLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root6, longLog, 3, OnDone::Failure};
|
||||
|
||||
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
|
||||
QTest::newRow("StopGroupAfterErrorWithFinishAllAndError")
|
||||
<< TestData{storage, root7, longErrorLog, 3, OnDone::Failure};
|
||||
<< TestData{storage, root7, longLog, 3, OnDone::Failure};
|
||||
}
|
||||
|
||||
{
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone,
|
||||
groupError](WorkflowPolicy policy) {
|
||||
const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone](
|
||||
WorkflowPolicy policy) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
workflowPolicy(policy),
|
||||
createSuccessTask(1),
|
||||
createFailingTask(2),
|
||||
createSuccessTask(3),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1266,7 +1227,7 @@ void tst_Tasking::testTree_data()
|
||||
}
|
||||
|
||||
{
|
||||
const auto createRoot = [storage, createTask, groupDone, groupError](
|
||||
const auto createRoot = [storage, createTask, groupDone](
|
||||
bool firstSuccess, bool secondSuccess) {
|
||||
return Group {
|
||||
parallel,
|
||||
@@ -1274,8 +1235,7 @@ void tst_Tasking::testTree_data()
|
||||
Storage(storage),
|
||||
createTask(1, firstSuccess, 1000ms),
|
||||
createTask(2, secondSuccess, 1ms),
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1306,8 +1266,7 @@ void tst_Tasking::testTree_data()
|
||||
}
|
||||
|
||||
{
|
||||
const auto createRoot = [storage, createSuccessTask, groupDone, groupError](
|
||||
SetupResult setupResult) {
|
||||
const auto createRoot = [storage, createSuccessTask, groupDone](SetupResult setupResult) {
|
||||
return Group {
|
||||
Storage(storage),
|
||||
Group {
|
||||
@@ -1319,8 +1278,7 @@ void tst_Tasking::testTree_data()
|
||||
createSuccessTask(3),
|
||||
createSuccessTask(4)
|
||||
},
|
||||
groupDone(0),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1809,7 +1767,7 @@ void tst_Tasking::testTree_data()
|
||||
createSyncWithReturn(3, false),
|
||||
createSuccessTask(4),
|
||||
createSync(5),
|
||||
groupError(0)
|
||||
groupDone(0)
|
||||
};
|
||||
const Log log {
|
||||
{1, Handler::Sync},
|
||||
|
@@ -511,7 +511,7 @@ void tst_Async::mapReduce_data()
|
||||
AsyncTask<int>(std::bind(setupHandler, _1, 3), handleAsync, CallDoneIf::Success),
|
||||
AsyncTask<int>(std::bind(setupHandler, _1, 4), handleAsync, CallDoneIf::Success),
|
||||
AsyncTask<int>(std::bind(setupHandler, _1, 5), handleAsync, CallDoneIf::Success),
|
||||
onGroupDone(doneHandler)
|
||||
onGroupDone(doneHandler, CallDoneIf::Success)
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -25,7 +25,7 @@ static QWidget *hr()
|
||||
return frame;
|
||||
}
|
||||
|
||||
QWidget *taskGroup(QWidget *groupWidget, const QList<QWidget *> &widgets)
|
||||
static QWidget *taskGroup(QWidget *groupWidget, const QList<QWidget *> &widgets)
|
||||
{
|
||||
QWidget *widget = new QWidget;
|
||||
QBoxLayout *layout = new QHBoxLayout(widget);
|
||||
@@ -42,6 +42,11 @@ QWidget *taskGroup(QWidget *groupWidget, const QList<QWidget *> &widgets)
|
||||
return widget;
|
||||
}
|
||||
|
||||
static State resultToState(DoneWith result)
|
||||
{
|
||||
return result == DoneWith::Success ? State::Done : State::Error;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
@@ -172,8 +177,7 @@ int main(int argc, char *argv[])
|
||||
const Group root {
|
||||
widget->isSuccess() ? stopOnError : finishAllAndError,
|
||||
TimeoutTask(setupTask),
|
||||
onGroupDone([widget] { widget->setState(State::Done); }),
|
||||
onGroupError([widget] { widget->setState(State::Error); })
|
||||
onGroupDone([widget](DoneWith result) { widget->setState(resultToState(result)); })
|
||||
};
|
||||
return root;
|
||||
};
|
||||
@@ -183,15 +187,13 @@ int main(int argc, char *argv[])
|
||||
rootGroup->executeMode(),
|
||||
rootGroup->workflowPolicy(),
|
||||
onGroupSetup([rootGroup] { rootGroup->setState(State::Running); }),
|
||||
onGroupDone([rootGroup] { rootGroup->setState(State::Done); }),
|
||||
onGroupError([rootGroup] { rootGroup->setState(State::Error); }),
|
||||
onGroupDone([rootGroup](DoneWith result) { rootGroup->setState(resultToState(result)); }),
|
||||
|
||||
Group {
|
||||
groupTask_1->executeMode(),
|
||||
groupTask_1->workflowPolicy(),
|
||||
onGroupSetup([groupTask_1] { groupTask_1->setState(State::Running); }),
|
||||
onGroupDone([groupTask_1] { groupTask_1->setState(State::Done); }),
|
||||
onGroupError([groupTask_1] { groupTask_1->setState(State::Error); }),
|
||||
onGroupDone([groupTask_1](DoneWith result) { groupTask_1->setState(resultToState(result)); }),
|
||||
|
||||
createTask(task_1_1),
|
||||
createTask(task_1_2),
|
||||
@@ -203,8 +205,7 @@ int main(int argc, char *argv[])
|
||||
groupTask_4->executeMode(),
|
||||
groupTask_4->workflowPolicy(),
|
||||
onGroupSetup([groupTask_4] { groupTask_4->setState(State::Running); }),
|
||||
onGroupDone([groupTask_4] { groupTask_4->setState(State::Done); }),
|
||||
onGroupError([groupTask_4] { groupTask_4->setState(State::Error); }),
|
||||
onGroupDone([groupTask_4](DoneWith result) { groupTask_4->setState(resultToState(result)); }),
|
||||
|
||||
createTask(task_4_1),
|
||||
createTask(task_4_2),
|
||||
@@ -212,8 +213,7 @@ int main(int argc, char *argv[])
|
||||
groupTask_4_3->executeMode(),
|
||||
groupTask_4_3->workflowPolicy(),
|
||||
onGroupSetup([groupTask_4_3] { groupTask_4_3->setState(State::Running); }),
|
||||
onGroupDone([groupTask_4_3] { groupTask_4_3->setState(State::Done); }),
|
||||
onGroupError([groupTask_4_3] { groupTask_4_3->setState(State::Error); }),
|
||||
onGroupDone([groupTask_4_3](DoneWith result) { groupTask_4_3->setState(resultToState(result)); }),
|
||||
|
||||
createTask(task_4_3_1),
|
||||
createTask(task_4_3_2),
|
||||
|
@@ -20,8 +20,9 @@ QT_END_NAMESPACE
|
||||
enum class State {
|
||||
Initial,
|
||||
Running,
|
||||
Done,
|
||||
Error
|
||||
Done, // TODO: Rename to Success
|
||||
Error,
|
||||
// TODO: Add Canceled state
|
||||
};
|
||||
|
||||
enum class ExecuteMode {
|
||||
|
@@ -68,7 +68,7 @@ void Images::process()
|
||||
finishAllAndDone,
|
||||
parallel,
|
||||
onGroupSetup(onRootSetup),
|
||||
onGroupDone(onRootDone)
|
||||
onGroupDone(onRootDone, CallDoneIf::Success)
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
|
Reference in New Issue
Block a user