aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils/tasktree.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils/tasktree.h')
-rw-r--r--src/libs/utils/tasktree.h385
1 files changed, 0 insertions, 385 deletions
diff --git a/src/libs/utils/tasktree.h b/src/libs/utils/tasktree.h
deleted file mode 100644
index 54a0cfda53..0000000000
--- a/src/libs/utils/tasktree.h
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#pragma once
-
-#include "utils_global.h"
-
-#include <QHash>
-#include <QObject>
-#include <QSharedPointer>
-
-namespace Utils {
-
-class StorageActivator;
-class TaskContainer;
-class TaskTreePrivate;
-
-namespace Tasking {
-
-class QTCREATOR_UTILS_EXPORT TaskInterface : public QObject
-{
- Q_OBJECT
-
-public:
- TaskInterface() = default;
- virtual void start() = 0;
-
-signals:
- void done(bool success);
-};
-
-class QTCREATOR_UTILS_EXPORT TreeStorageBase
-{
-public:
- bool isValid() const;
-
-protected:
- using StorageConstructor = std::function<void *(void)>;
- using StorageDestructor = std::function<void(void *)>;
-
- TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor);
- void *activeStorageVoid() const;
-
-private:
- int createStorage() const;
- void deleteStorage(int id) const;
- void activateStorage(int id) const;
-
- friend bool operator==(const TreeStorageBase &first, const TreeStorageBase &second)
- { return first.m_storageData == second.m_storageData; }
-
- friend bool operator!=(const TreeStorageBase &first, const TreeStorageBase &second)
- { return first.m_storageData != second.m_storageData; }
-
- friend size_t qHash(const TreeStorageBase &storage, uint seed = 0)
- { return size_t(storage.m_storageData.get()) ^ seed; }
-
- struct StorageData {
- ~StorageData();
- StorageConstructor m_constructor = {};
- StorageDestructor m_destructor = {};
- QHash<int, void *> m_storageHash = {};
- int m_activeStorage = 0; // 0 means no active storage
- int m_storageCounter = 0;
- };
- QSharedPointer<StorageData> m_storageData;
- friend TaskContainer;
- friend TaskTreePrivate;
- friend StorageActivator;
-};
-
-template <typename StorageStruct>
-class TreeStorage : public TreeStorageBase
-{
-public:
- TreeStorage() : TreeStorageBase(TreeStorage::ctor(), TreeStorage::dtor()) {}
- StorageStruct *operator->() const noexcept { return activeStorage(); }
- StorageStruct *activeStorage() const {
- return static_cast<StorageStruct *>(activeStorageVoid());
- }
-
-private:
- static StorageConstructor ctor() { return [] { return new StorageStruct; }; }
- static StorageDestructor dtor() {
- return [](void *storage) { delete static_cast<StorageStruct *>(storage); };
- }
-};
-
-// 4 policies:
-// 1. When all children finished with done -> report done, otherwise:
-// a) Report error on first error and stop executing other children (including their subtree)
-// b) On first error - wait for all children to be finished and report error afterwards
-// 2. When all children finished with error -> report error, otherwise:
-// a) Report done on first done and stop executing other children (including their subtree)
-// b) On first done - wait for all children to be finished and report done afterwards
-
-enum class WorkflowPolicy {
- StopOnError, // 1a - Will report error on any child error, otherwise done (if all children were done)
- ContinueOnError, // 1b - the same. When no children it reports done.
- StopOnDone, // 2a - Will report done on any child done, otherwise error (if all children were error)
- ContinueOnDone, // 2b - the same. When no children it reports done. (?)
- Optional // Returns always done after all children finished
-};
-
-enum class TaskAction
-{
- Continue,
- StopWithDone,
- StopWithError
-};
-
-class QTCREATOR_UTILS_EXPORT TaskItem
-{
-public:
- // Internal, provided by QTC_DECLARE_CUSTOM_TASK
- using TaskCreateHandler = std::function<TaskInterface *(void)>;
- // Called prior to task start, just after createHandler
- using TaskSetupHandler = std::function<TaskAction(TaskInterface &)>;
- // Called on task done / error
- using TaskEndHandler = std::function<void(const TaskInterface &)>;
- // Called when group entered
- using GroupSetupHandler = std::function<TaskAction()>;
- // Called when group done / error
- using GroupEndHandler = std::function<void()>;
-
- struct TaskHandler {
- TaskCreateHandler m_createHandler;
- TaskSetupHandler m_setupHandler;
- TaskEndHandler m_doneHandler;
- TaskEndHandler m_errorHandler;
- };
-
- struct GroupHandler {
- GroupSetupHandler m_setupHandler;
- GroupEndHandler m_doneHandler = {};
- GroupEndHandler m_errorHandler = {};
- };
-
- int parallelLimit() const { return m_parallelLimit; }
- WorkflowPolicy workflowPolicy() const { return m_workflowPolicy; }
- TaskHandler taskHandler() const { return m_taskHandler; }
- GroupHandler groupHandler() const { return m_groupHandler; }
- QList<TaskItem> children() const { return m_children; }
- QList<TreeStorageBase> storageList() const { return m_storageList; }
-
-protected:
- enum class Type {
- Group,
- Storage,
- Limit,
- Policy,
- TaskHandler,
- GroupHandler
- };
-
- TaskItem() = default;
- TaskItem(int parallelLimit)
- : m_type(Type::Limit)
- , m_parallelLimit(parallelLimit) {}
- TaskItem(WorkflowPolicy policy)
- : m_type(Type::Policy)
- , m_workflowPolicy(policy) {}
- TaskItem(const TaskHandler &handler)
- : m_type(Type::TaskHandler)
- , m_taskHandler(handler) {}
- TaskItem(const GroupHandler &handler)
- : m_type(Type::GroupHandler)
- , m_groupHandler(handler) {}
- TaskItem(const TreeStorageBase &storage)
- : m_type(Type::Storage)
- , m_storageList{storage} {}
- void addChildren(const QList<TaskItem> &children);
-
-private:
- Type m_type = Type::Group;
- int m_parallelLimit = 1; // 0 means unlimited
- WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError;
- TaskHandler m_taskHandler;
- GroupHandler m_groupHandler;
- QList<TreeStorageBase> m_storageList;
- QList<TaskItem> m_children;
-};
-
-class QTCREATOR_UTILS_EXPORT Group : public TaskItem
-{
-public:
- Group(const QList<TaskItem> &children) { addChildren(children); }
- Group(std::initializer_list<TaskItem> children) { addChildren(children); }
-};
-
-class QTCREATOR_UTILS_EXPORT Storage : public TaskItem
-{
-public:
- Storage(const TreeStorageBase &storage) : TaskItem(storage) { }
-};
-
-class QTCREATOR_UTILS_EXPORT ParallelLimit : public TaskItem
-{
-public:
- ParallelLimit(int parallelLimit) : TaskItem(qMax(parallelLimit, 0)) {}
-};
-
-class QTCREATOR_UTILS_EXPORT Workflow : public TaskItem
-{
-public:
- Workflow(WorkflowPolicy policy) : TaskItem(policy) {}
-};
-
-class QTCREATOR_UTILS_EXPORT OnGroupSetup : public TaskItem
-{
-public:
- template <typename SetupFunction>
- OnGroupSetup(SetupFunction &&function)
- : TaskItem({wrapSetup(std::forward<SetupFunction>(function))}) {}
-
-private:
- template<typename SetupFunction>
- static TaskItem::GroupSetupHandler wrapSetup(SetupFunction &&function) {
- static constexpr bool isDynamic = std::is_same_v<TaskAction,
- std::invoke_result_t<std::decay_t<SetupFunction>>>;
- constexpr bool isVoid = std::is_same_v<void,
- std::invoke_result_t<std::decay_t<SetupFunction>>>;
- static_assert(isDynamic || isVoid,
- "Group setup handler needs to take no arguments and has to return "
- "void or TaskAction. The passed handler doesn't fulfill these requirements.");
- return [=] {
- if constexpr (isDynamic)
- return std::invoke(function);
- std::invoke(function);
- return TaskAction::Continue;
- };
- };
-};
-
-class QTCREATOR_UTILS_EXPORT OnGroupDone : public TaskItem
-{
-public:
- OnGroupDone(const GroupEndHandler &handler) : TaskItem({{}, handler}) {}
-};
-
-class QTCREATOR_UTILS_EXPORT OnGroupError : public TaskItem
-{
-public:
- OnGroupError(const GroupEndHandler &handler) : TaskItem({{}, {}, handler}) {}
-};
-
-QTCREATOR_UTILS_EXPORT extern ParallelLimit sequential;
-QTCREATOR_UTILS_EXPORT extern ParallelLimit parallel;
-QTCREATOR_UTILS_EXPORT extern Workflow stopOnError;
-QTCREATOR_UTILS_EXPORT extern Workflow continueOnError;
-QTCREATOR_UTILS_EXPORT extern Workflow stopOnDone;
-QTCREATOR_UTILS_EXPORT extern Workflow continueOnDone;
-QTCREATOR_UTILS_EXPORT extern Workflow optional;
-
-template <typename Task>
-class TaskAdapter : public TaskInterface
-{
-public:
- using Type = Task;
- TaskAdapter() = default;
- Task *task() { return &m_task; }
- const Task *task() const { return &m_task; }
-private:
- Task m_task;
-};
-
-template <typename Adapter>
-class CustomTask : public TaskItem
-{
-public:
- using Task = typename Adapter::Type;
- using EndHandler = std::function<void(const Task &)>;
- static Adapter *createAdapter() { return new Adapter; }
- template <typename SetupFunction>
- CustomTask(SetupFunction &&function, const EndHandler &done = {}, const EndHandler &error = {})
- : TaskItem({&createAdapter, wrapSetup(std::forward<SetupFunction>(function)),
- wrapEnd(done), wrapEnd(error)}) {}
-
-private:
- template<typename SetupFunction>
- static TaskItem::TaskSetupHandler wrapSetup(SetupFunction &&function) {
- static constexpr bool isDynamic = std::is_same_v<TaskAction,
- std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
- constexpr bool isVoid = std::is_same_v<void,
- std::invoke_result_t<std::decay_t<SetupFunction>, typename Adapter::Type &>>;
- static_assert(isDynamic || isVoid,
- "Task setup handler needs to take (Task &) as an argument and has to return "
- "void or TaskAction. The passed handler doesn't fulfill these requirements.");
- return [=](TaskInterface &taskInterface) {
- Adapter &adapter = static_cast<Adapter &>(taskInterface);
- if constexpr (isDynamic)
- return std::invoke(function, *adapter.task());
- std::invoke(function, *adapter.task());
- return TaskAction::Continue;
- };
- };
-
- static TaskEndHandler wrapEnd(const EndHandler &handler) {
- if (!handler)
- return {};
- return [handler](const TaskInterface &taskInterface) {
- const Adapter &adapter = static_cast<const Adapter &>(taskInterface);
- handler(*adapter.task());
- };
- };
-};
-
-} // namespace Tasking
-
-class TaskTreePrivate;
-
-class QTCREATOR_UTILS_EXPORT TaskTree : public QObject
-{
- Q_OBJECT
-
-public:
- TaskTree();
- TaskTree(const Tasking::Group &root);
- ~TaskTree();
-
- void setupRoot(const Tasking::Group &root);
-
- void start();
- void stop();
- bool isRunning() const;
-
- int taskCount() const;
- int progressMaximum() const { return taskCount(); }
- int progressValue() const; // all finished / skipped / stopped tasks, groups itself excluded
-
- template <typename StorageStruct, typename StorageHandler>
- void onStorageSetup(const Tasking::TreeStorage<StorageStruct> &storage,
- StorageHandler &&handler) {
- setupStorageHandler(storage,
- wrapHandler<StorageStruct>(std::forward<StorageHandler>(handler)), {});
- }
- template <typename StorageStruct, typename StorageHandler>
- void onStorageDone(const Tasking::TreeStorage<StorageStruct> &storage,
- StorageHandler &&handler) {
- setupStorageHandler(storage,
- {}, wrapHandler<StorageStruct>(std::forward<StorageHandler>(handler)));
- }
-
-signals:
- void started();
- void done();
- void errorOccurred();
- void progressValueChanged(int value); // updated whenever task finished / skipped / stopped
-
-private:
- using StorageVoidHandler = std::function<void(void *)>;
- void setupStorageHandler(const Tasking::TreeStorageBase &storage,
- StorageVoidHandler setupHandler,
- StorageVoidHandler doneHandler);
- template <typename StorageStruct, typename StorageHandler>
- StorageVoidHandler wrapHandler(StorageHandler &&handler) {
- return [=](void *voidStruct) {
- StorageStruct *storageStruct = static_cast<StorageStruct *>(voidStruct);
- std::invoke(handler, storageStruct);
- };
- }
-
- friend class TaskTreePrivate;
- TaskTreePrivate *d;
-};
-
-class QTCREATOR_UTILS_EXPORT TaskTreeAdapter : public Tasking::TaskAdapter<TaskTree>
-{
-public:
- TaskTreeAdapter();
- void start() final;
-};
-
-} // namespace Utils
-
-#define QTC_DECLARE_CUSTOM_TASK(CustomTaskName, TaskAdapterClass)\
-namespace Utils::Tasking { using CustomTaskName = CustomTask<TaskAdapterClass>; }
-
-#define QTC_DECLARE_CUSTOM_TEMPLATE_TASK(CustomTaskName, TaskAdapterClass)\
-namespace Utils::Tasking {\
-template <typename ...Args>\
-using CustomTaskName = CustomTask<TaskAdapterClass<Args...>>;\
-} // namespace Utils::Tasking
-
-QTC_DECLARE_CUSTOM_TASK(Tree, Utils::TaskTreeAdapter);