forked from qt-creator/qt-creator
TaskTree: Add Task c'tor taking one handler for done and error
The overloaded c'tor takes one done handler with an additional "bool success" argument. Task-number: QTCREATORBUG-29834 Change-Id: Id579d055721a2a07a5a9f0900aa4a73655f21610 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -324,6 +324,7 @@ public:
|
|||||||
static_assert(std::is_base_of_v<TaskAdapter<Task, Deleter>, Adapter>,
|
static_assert(std::is_base_of_v<TaskAdapter<Task, Deleter>, Adapter>,
|
||||||
"The Adapter type for the CustomTask<Adapter> needs to be derived from "
|
"The Adapter type for the CustomTask<Adapter> needs to be derived from "
|
||||||
"TaskAdapter<Task>.");
|
"TaskAdapter<Task>.");
|
||||||
|
using DoneHandler = std::function<void(const Task &, bool)>;
|
||||||
using EndHandler = std::function<void(const Task &)>;
|
using EndHandler = std::function<void(const Task &)>;
|
||||||
static Adapter *createAdapter() { return new Adapter; }
|
static Adapter *createAdapter() { return new Adapter; }
|
||||||
CustomTask() : GroupItem({&createAdapter}) {}
|
CustomTask() : GroupItem({&createAdapter}) {}
|
||||||
@@ -332,6 +333,11 @@ public:
|
|||||||
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)),
|
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)),
|
||||||
wrapEnds(done, error)}) {}
|
wrapEnds(done, error)}) {}
|
||||||
|
|
||||||
|
template <typename SetupHandler>
|
||||||
|
CustomTask(SetupHandler &&setup, const DoneHandler &done)
|
||||||
|
: GroupItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)), wrapDone(done)})
|
||||||
|
{}
|
||||||
|
|
||||||
GroupItem withTimeout(std::chrono::milliseconds timeout,
|
GroupItem withTimeout(std::chrono::milliseconds timeout,
|
||||||
const GroupEndHandler &handler = {}) const {
|
const GroupEndHandler &handler = {}) const {
|
||||||
return GroupItem::withTimeout(*this, timeout, handler);
|
return GroupItem::withTimeout(*this, timeout, handler);
|
||||||
@@ -366,6 +372,15 @@ private:
|
|||||||
handler(*adapter.task());
|
handler(*adapter.task());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static TaskDoneHandler wrapDone(const DoneHandler &handler) {
|
||||||
|
if (!handler)
|
||||||
|
return {};
|
||||||
|
return [handler](const TaskInterface &taskInterface, bool success) {
|
||||||
|
const Adapter &adapter = static_cast<const Adapter &>(taskInterface);
|
||||||
|
handler(*adapter.task(), success);
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class TaskTreePrivate;
|
class TaskTreePrivate;
|
||||||
|
@@ -113,24 +113,22 @@ DiffFilesController::DiffFilesController(IDocument *document)
|
|||||||
const auto setupTree = [this, storage](TaskTree &taskTree) {
|
const auto setupTree = [this, storage](TaskTree &taskTree) {
|
||||||
QList<std::optional<FileData>> *outputList = storage.activeStorage();
|
QList<std::optional<FileData>> *outputList = storage.activeStorage();
|
||||||
|
|
||||||
const auto setupDiff = [this](Async<FileData> &async, const ReloadInput &reloadInput) {
|
|
||||||
async.setConcurrentCallData(
|
|
||||||
DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput);
|
|
||||||
async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
|
|
||||||
};
|
|
||||||
const auto onDiffDone = [outputList](const Async<FileData> &async, int i) {
|
|
||||||
if (async.isResultAvailable())
|
|
||||||
(*outputList)[i] = async.result();
|
|
||||||
};
|
|
||||||
|
|
||||||
const QList<ReloadInput> inputList = reloadInputList();
|
const QList<ReloadInput> inputList = reloadInputList();
|
||||||
outputList->resize(inputList.size());
|
outputList->resize(inputList.size());
|
||||||
|
|
||||||
using namespace std::placeholders;
|
QList<GroupItem> tasks { parallel, finishAllAndDone };
|
||||||
QList<GroupItem> tasks {parallel, finishAllAndDone};
|
|
||||||
for (int i = 0; i < inputList.size(); ++i) {
|
for (int i = 0; i < inputList.size(); ++i) {
|
||||||
tasks.append(AsyncTask<FileData>(std::bind(setupDiff, _1, inputList.at(i)),
|
const auto setupDiff = [this, reloadInput = inputList.at(i)](Async<FileData> &async) {
|
||||||
std::bind(onDiffDone, _1, i)));
|
async.setConcurrentCallData(
|
||||||
|
DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput);
|
||||||
|
async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer());
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto onDiffDone = [outputList, i](const Async<FileData> &async) {
|
||||||
|
if (async.isResultAvailable())
|
||||||
|
(*outputList)[i] = async.result();
|
||||||
|
};
|
||||||
|
tasks.append(AsyncTask<FileData>(setupDiff, onDiffDone));
|
||||||
}
|
}
|
||||||
taskTree.setRecipe(tasks);
|
taskTree.setRecipe(tasks);
|
||||||
};
|
};
|
||||||
|
@@ -497,23 +497,21 @@ ShowController::ShowController(IDocument *document, const QString &id)
|
|||||||
data->m_follows = {busyMessage};
|
data->m_follows = {busyMessage};
|
||||||
data->m_follows.resize(parents.size());
|
data->m_follows.resize(parents.size());
|
||||||
|
|
||||||
const auto setupFollow = [this](Process &process, const QString &parent) {
|
|
||||||
setupCommand(process, {"describe", "--tags", "--abbrev=0", parent});
|
|
||||||
};
|
|
||||||
const auto onFollowDone = [data, updateDescription](const Process &process, int index) {
|
|
||||||
data->m_follows[index] = process.cleanedStdOut().trimmed();
|
|
||||||
updateDescription(*data);
|
|
||||||
};
|
|
||||||
const auto onFollowsError = [data, updateDescription] {
|
const auto onFollowsError = [data, updateDescription] {
|
||||||
data->m_follows.clear();
|
data->m_follows.clear();
|
||||||
updateDescription(*data);
|
updateDescription(*data);
|
||||||
};
|
};
|
||||||
|
|
||||||
using namespace std::placeholders;
|
QList<GroupItem> tasks { parallel, continueOnDone, onGroupError(onFollowsError) };
|
||||||
QList<GroupItem> tasks {parallel, continueOnDone, onGroupError(onFollowsError)};
|
|
||||||
for (int i = 0, total = parents.size(); i < total; ++i) {
|
for (int i = 0, total = parents.size(); i < total; ++i) {
|
||||||
tasks.append(ProcessTask(std::bind(setupFollow, _1, parents.at(i)),
|
const auto setupFollow = [this, parent = parents.at(i)](Process &process) {
|
||||||
std::bind(onFollowDone, _1, i)));
|
setupCommand(process, {"describe", "--tags", "--abbrev=0", parent});
|
||||||
|
};
|
||||||
|
const auto onFollowDone = [data, updateDescription, i](const Process &process) {
|
||||||
|
data->m_follows[i] = process.cleanedStdOut().trimmed();
|
||||||
|
updateDescription(*data);
|
||||||
|
};
|
||||||
|
tasks.append(ProcessTask(setupFollow, onFollowDone));
|
||||||
}
|
}
|
||||||
taskTree.setRecipe(tasks);
|
taskTree.setRecipe(tasks);
|
||||||
};
|
};
|
||||||
|
@@ -111,14 +111,16 @@ void tst_Tasking::validConstructs()
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto setupHandler = [](TaskObject &) {};
|
const auto setupHandler = [](TaskObject &) {};
|
||||||
const auto doneHandler = [](const TaskObject &) {};
|
const auto finishHandler = [](const TaskObject &) {};
|
||||||
const auto errorHandler = [](const TaskObject &) {};
|
const auto errorHandler = [](const TaskObject &) {};
|
||||||
|
const auto doneHandler = [](const TaskObject &, bool) {};
|
||||||
|
|
||||||
const Group task2 {
|
const Group task2 {
|
||||||
parallel,
|
parallel,
|
||||||
TestTask(setupHandler),
|
TestTask(setupHandler),
|
||||||
|
TestTask(setupHandler, finishHandler),
|
||||||
|
TestTask(setupHandler, finishHandler, errorHandler),
|
||||||
TestTask(setupHandler, doneHandler),
|
TestTask(setupHandler, doneHandler),
|
||||||
TestTask(setupHandler, doneHandler, errorHandler),
|
|
||||||
// need to explicitly pass empty handler for done
|
// need to explicitly pass empty handler for done
|
||||||
TestTask(setupHandler, {}, errorHandler)
|
TestTask(setupHandler, {}, errorHandler)
|
||||||
};
|
};
|
||||||
@@ -220,14 +222,8 @@ void tst_Tasking::testTree_data()
|
|||||||
};
|
};
|
||||||
|
|
||||||
const auto setupDone = [storage](int taskId) {
|
const auto setupDone = [storage](int taskId) {
|
||||||
return [storage, taskId](const TaskObject &) {
|
return [storage, taskId](const TaskObject &, bool success) {
|
||||||
storage->m_log.append({taskId, Handler::Done});
|
storage->m_log.append({taskId, success ? Handler::Done : Handler::Error});
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto setupError = [storage](int taskId) {
|
|
||||||
return [storage, taskId](const TaskObject &) {
|
|
||||||
storage->m_log.append({taskId, Handler::Error});
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -237,14 +233,13 @@ void tst_Tasking::testTree_data()
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto createTask = [storage, setupTask, setupDone, setupError](
|
const auto createTask = [storage, setupTask, setupDone](
|
||||||
int taskId, bool successTask, milliseconds timeout = 0ms) -> GroupItem {
|
int taskId, bool successTask, milliseconds timeout = 0ms) -> GroupItem {
|
||||||
if (successTask)
|
if (successTask)
|
||||||
return TestTask(setupTask(taskId, timeout), setupDone(taskId), setupError(taskId));
|
return TestTask(setupTask(taskId, timeout), setupDone(taskId));
|
||||||
const Group root {
|
const Group root {
|
||||||
finishAllAndError,
|
finishAllAndError,
|
||||||
TestTask(setupTask(taskId, timeout)),
|
TestTask(setupTask(taskId, timeout)),
|
||||||
onGroupDone([storage, taskId] { storage->m_log.append({taskId, Handler::Done}); }),
|
|
||||||
onGroupError([storage, taskId] { storage->m_log.append({taskId, Handler::Error}); })
|
onGroupError([storage, taskId] { storage->m_log.append({taskId, Handler::Error}); })
|
||||||
};
|
};
|
||||||
return root;
|
return root;
|
||||||
@@ -258,9 +253,9 @@ void tst_Tasking::testTree_data()
|
|||||||
return createTask(taskId, false, timeout);
|
return createTask(taskId, false, timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto createDynamicTask = [storage, setupDynamicTask, setupDone, setupError](
|
const auto createDynamicTask = [storage, setupDynamicTask, setupDone](int taskId,
|
||||||
int taskId, SetupResult action) {
|
SetupResult action) {
|
||||||
return TestTask(setupDynamicTask(taskId, action), setupDone(taskId), setupError(taskId));
|
return TestTask(setupDynamicTask(taskId, action), setupDone(taskId));
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto groupSetup = [storage](int taskId) {
|
const auto groupSetup = [storage](int taskId) {
|
||||||
@@ -2121,7 +2116,7 @@ void tst_Tasking::testTree_data()
|
|||||||
// 2. With and without timeout handler.
|
// 2. With and without timeout handler.
|
||||||
const Group root1 {
|
const Group root1 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
TestTask(setupTask(1, 1000ms), setupDone(1), setupError(1))
|
TestTask(setupTask(1, 1000ms), setupDone(1))
|
||||||
.withTimeout(1ms)
|
.withTimeout(1ms)
|
||||||
};
|
};
|
||||||
const Log log1 {
|
const Log log1 {
|
||||||
@@ -2133,7 +2128,7 @@ void tst_Tasking::testTree_data()
|
|||||||
|
|
||||||
const Group root2 {
|
const Group root2 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
TestTask(setupTask(1, 1000ms), setupDone(1), setupError(1))
|
TestTask(setupTask(1, 1000ms), setupDone(1))
|
||||||
.withTimeout(1ms, setupTimeout(1))
|
.withTimeout(1ms, setupTimeout(1))
|
||||||
};
|
};
|
||||||
const Log log2 {
|
const Log log2 {
|
||||||
@@ -2146,7 +2141,7 @@ void tst_Tasking::testTree_data()
|
|||||||
|
|
||||||
const Group root3 {
|
const Group root3 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
TestTask(setupTask(1, 1ms), setupDone(1), setupError(1))
|
TestTask(setupTask(1, 1ms), setupDone(1))
|
||||||
.withTimeout(1000ms)
|
.withTimeout(1000ms)
|
||||||
};
|
};
|
||||||
const Log doneLog {
|
const Log doneLog {
|
||||||
@@ -2158,7 +2153,7 @@ void tst_Tasking::testTree_data()
|
|||||||
|
|
||||||
const Group root4 {
|
const Group root4 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
TestTask(setupTask(1, 1ms), setupDone(1), setupError(1))
|
TestTask(setupTask(1, 1ms), setupDone(1))
|
||||||
.withTimeout(1000ms, setupTimeout(1))
|
.withTimeout(1000ms, setupTimeout(1))
|
||||||
};
|
};
|
||||||
QTest::newRow("TaskDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2,
|
QTest::newRow("TaskDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2,
|
||||||
|
Reference in New Issue
Block a user