aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2022-11-21 15:05:39 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2022-11-23 12:59:18 +0000
commit3468cd20ca8feeccf023091582d1390947822bd8 (patch)
treeb978531b171ba6de9bfe94dbc63a9df9852eea6b /src/libs
parent1667b062362f844d2542a4af2d47c40c63584e78 (diff)
TaskTree: Introduce Storage item
The Storage item makes it possible to define the whole subtree as a self-contained, full-functional recipe, without a need for passing (together with recipe) a one-use only (disposable) pointer to storage object. That's the last closing element of making the idea of pure, value-based recipe real. It makes the TaskTree machinery ultimately powerful. Change-Id: Icd81bdd3e94251e8b241b2b550957d566fa4ab75 Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/utils/tasktree.cpp118
-rw-r--r--src/libs/utils/tasktree.h13
2 files changed, 111 insertions, 20 deletions
diff --git a/src/libs/utils/tasktree.cpp b/src/libs/utils/tasktree.cpp
index c99729a5d8..557b922ec7 100644
--- a/src/libs/utils/tasktree.cpp
+++ b/src/libs/utils/tasktree.cpp
@@ -117,6 +117,9 @@ void TaskItem::addChildren(const QList<TaskItem> &children)
if (child.m_groupHandler.m_dynamicSetupHandler)
m_groupHandler.m_dynamicSetupHandler = child.m_groupHandler.m_dynamicSetupHandler;
break;
+ case Type::Storage:
+ m_storageList.append(child.m_storageList);
+ break;
}
}
}
@@ -144,11 +147,18 @@ public:
void resetSuccessBit();
void updateSuccessBit(bool success);
+ void createStorages();
+ void deleteStorages();
+ void activateStorages();
+ void deactivateStorages();
+
TaskTreePrivate *m_taskTreePrivate = nullptr;
TaskContainer *m_parentContainer = nullptr;
const ExecuteMode m_executeMode = ExecuteMode::Parallel;
WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError;
const TaskItem::GroupHandler m_groupHandler;
+ QList<TreeStorageBase> m_storageList;
+ QList<int> m_storageIdList;
int m_taskCount = 0;
GroupConfig m_groupConfig;
QList<TaskNode *> m_children;
@@ -157,6 +167,22 @@ public:
bool m_successBit = true;
};
+class StorageActivator
+{
+public:
+ StorageActivator(TaskContainer &container)
+ : m_container(container)
+ {
+ m_container.activateStorages();
+ }
+ ~StorageActivator()
+ {
+ m_container.deactivateStorages();
+ }
+private:
+ TaskContainer &m_container;
+};
+
class TaskNode : public QObject
{
public:
@@ -244,6 +270,7 @@ TaskContainer::TaskContainer(TaskTreePrivate *taskTreePrivate, TaskContainer *pa
, m_executeMode(task.executeMode())
, m_workflowPolicy(task.workflowPolicy())
, m_groupHandler(task.groupHandler())
+ , m_storageList(task.storageList())
{
const QList<TaskItem> &children = task.children();
for (const TaskItem &child : children) {
@@ -264,14 +291,18 @@ void TaskContainer::start()
m_groupConfig = {};
m_selectedChildren.clear();
- if (m_groupHandler.m_setupHandler) {
- GuardLocker locker(m_taskTreePrivate->m_guard);
- m_groupHandler.m_setupHandler();
- }
+ createStorages();
+ {
+ StorageActivator activator(*this);
+ if (m_groupHandler.m_setupHandler) {
+ GuardLocker locker(m_taskTreePrivate->m_guard);
+ m_groupHandler.m_setupHandler();
+ }
- if (m_groupHandler.m_dynamicSetupHandler) {
- GuardLocker locker(m_taskTreePrivate->m_guard);
- m_groupConfig = m_groupHandler.m_dynamicSetupHandler();
+ if (m_groupHandler.m_dynamicSetupHandler) {
+ GuardLocker locker(m_taskTreePrivate->m_guard);
+ m_groupConfig = m_groupHandler.m_dynamicSetupHandler();
+ }
}
if (m_groupConfig.action == GroupAction::StopWithDone || m_groupConfig.action == GroupAction::StopWithError) {
@@ -374,13 +405,17 @@ void TaskContainer::invokeEndHandler(bool success, bool propagateToParent)
{
m_currentIndex = -1;
m_successBit = success;
- if (success && m_groupHandler.m_doneHandler) {
- GuardLocker locker(m_taskTreePrivate->m_guard);
- m_groupHandler.m_doneHandler();
- } else if (!success && m_groupHandler.m_errorHandler) {
- GuardLocker locker(m_taskTreePrivate->m_guard);
- m_groupHandler.m_errorHandler();
+ {
+ StorageActivator activator(*this);
+ if (success && m_groupHandler.m_doneHandler) {
+ GuardLocker locker(m_taskTreePrivate->m_guard);
+ m_groupHandler.m_doneHandler();
+ } else if (!success && m_groupHandler.m_errorHandler) {
+ GuardLocker locker(m_taskTreePrivate->m_guard);
+ m_groupHandler.m_errorHandler();
+ }
}
+ deleteStorages();
if (!propagateToParent)
return;
@@ -420,6 +455,46 @@ void TaskContainer::updateSuccessBit(bool success)
}
}
+void TaskContainer::createStorages()
+{
+ // TODO: Don't create new storage for already created storages with the same shared pointer.
+
+ for (int i = 0; i < m_storageList.size(); ++i)
+ m_storageIdList << m_storageList[i].createStorage();
+}
+
+void TaskContainer::deleteStorages()
+{
+ // TODO: Do the opposite
+
+ for (int i = 0; i < m_storageList.size(); ++i) // iterate in reverse order?
+ m_storageList[i].deleteStorage(m_storageIdList.value(i));
+
+ m_storageIdList.clear();
+}
+
+void TaskContainer::activateStorages()
+{
+ // TODO: check if the same shared storage was already activated. Don't activate recursively.
+
+ if (m_parentContainer)
+ m_parentContainer->activateStorages();
+
+ for (int i = 0; i < m_storageList.size(); ++i)
+ m_storageList[i].activateStorage(m_storageIdList.value(i));
+}
+
+void TaskContainer::deactivateStorages()
+{
+ // TODO: Do the opposite
+
+ for (int i = 0; i < m_storageList.size(); ++i) // iterate in reverse order?
+ m_storageList[i].activateStorage(0);
+
+ if (m_parentContainer)
+ m_parentContainer->deactivateStorages();
+}
+
bool TaskNode::start()
{
if (!isTask()) {
@@ -428,16 +503,20 @@ bool TaskNode::start()
}
m_task.reset(m_taskHandler.m_createHandler());
{
+ StorageActivator activator(m_container);
GuardLocker locker(m_container.m_taskTreePrivate->m_guard);
m_taskHandler.m_setupHandler(*m_task.get());
}
connect(m_task.get(), &TaskInterface::done, this, [this](bool success) {
- if (success && m_taskHandler.m_doneHandler) {
- GuardLocker locker(m_container.m_taskTreePrivate->m_guard);
- m_taskHandler.m_doneHandler(*m_task.get());
- } else if (!success && m_taskHandler.m_errorHandler) {
- GuardLocker locker(m_container.m_taskTreePrivate->m_guard);
- m_taskHandler.m_errorHandler(*m_task.get());
+ {
+ StorageActivator activator(m_container);
+ if (success && m_taskHandler.m_doneHandler) {
+ GuardLocker locker(m_container.m_taskTreePrivate->m_guard);
+ m_taskHandler.m_doneHandler(*m_task.get());
+ } else if (!success && m_taskHandler.m_errorHandler) {
+ GuardLocker locker(m_container.m_taskTreePrivate->m_guard);
+ m_taskHandler.m_errorHandler(*m_task.get());
+ }
}
m_container.m_taskTreePrivate->advanceProgress(1);
@@ -465,6 +544,7 @@ void TaskNode::stop()
// TODO: cancelHandler?
// TODO: call TaskInterface::stop() ?
if (m_taskHandler.m_errorHandler) {
+ StorageActivator activator(m_container);
GuardLocker locker(m_container.m_taskTreePrivate->m_guard);
m_taskHandler.m_errorHandler(*m_task.get());
}
diff --git a/src/libs/utils/tasktree.h b/src/libs/utils/tasktree.h
index 9f54d6a3da..1cd6c53330 100644
--- a/src/libs/utils/tasktree.h
+++ b/src/libs/utils/tasktree.h
@@ -143,15 +143,16 @@ public:
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,
Mode,
Policy,
TaskHandler,
GroupHandler
- // TODO: Add Cond type (with CondHandler and True and False branches)?
};
TaskItem() = default;
@@ -167,6 +168,9 @@ protected:
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:
@@ -175,6 +179,7 @@ private:
WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError;
TaskHandler m_taskHandler;
GroupHandler m_groupHandler;
+ QList<TreeStorageBase> m_storageList;
QList<TaskItem> m_children;
};
@@ -185,6 +190,12 @@ public:
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 Execute : public TaskItem
{
public: