forked from qt-creator/qt-creator
TaskTree: Introduce TreeStorage class
TreeStorage enables delayed creation of instances of StorageStruct. It encapsutates recipe on how create / delete instance of StorageStruct. It doesn't create any instance of StorageStruct when TreeStorage is created. These instances will be created later, by TaskTree. It will enable getting StorageStruct instance inside task / group handlers (passed by lambda argument). Change-Id: Id707353f196aa5ba3e7876d6c601e04ca08d6e63 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -9,6 +9,57 @@
|
||||
namespace Utils {
|
||||
namespace Tasking {
|
||||
|
||||
bool TreeStorageBase::isValid() const
|
||||
{
|
||||
return m_storageData && m_storageData->m_constructor && m_storageData->m_destructor;
|
||||
}
|
||||
|
||||
TreeStorageBase::TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor)
|
||||
: m_storageData(new StorageData{ctor, dtor}) { }
|
||||
|
||||
void *TreeStorageBase::activeStorageVoid() const
|
||||
{
|
||||
QTC_ASSERT(m_storageData->m_activeStorage, return nullptr);
|
||||
const auto it = m_storageData->m_storageHash.constFind(m_storageData->m_activeStorage);
|
||||
QTC_ASSERT(it != m_storageData->m_storageHash.constEnd(), return nullptr);
|
||||
return it.value();
|
||||
}
|
||||
|
||||
int TreeStorageBase::createStorage()
|
||||
{
|
||||
QTC_ASSERT(m_storageData->m_constructor, return 0); // TODO: add isValid()?
|
||||
QTC_ASSERT(m_storageData->m_destructor, return 0);
|
||||
QTC_ASSERT(m_storageData->m_activeStorage == 0, return 0); // TODO: should be allowed?
|
||||
const int newId = ++m_storageData->m_storageCounter;
|
||||
m_storageData->m_storageHash.insert(newId, m_storageData->m_constructor());
|
||||
return newId;
|
||||
}
|
||||
|
||||
void TreeStorageBase::deleteStorage(int id)
|
||||
{
|
||||
QTC_ASSERT(m_storageData->m_constructor, return); // TODO: add isValid()?
|
||||
QTC_ASSERT(m_storageData->m_destructor, return);
|
||||
QTC_ASSERT(m_storageData->m_activeStorage == 0, return); // TODO: should be allowed?
|
||||
const auto it = m_storageData->m_storageHash.find(id);
|
||||
QTC_ASSERT(it != m_storageData->m_storageHash.end(), return);
|
||||
m_storageData->m_destructor(it.value());
|
||||
m_storageData->m_storageHash.erase(it);
|
||||
}
|
||||
|
||||
// passing 0 deactivates currently active storage
|
||||
void TreeStorageBase::activateStorage(int id)
|
||||
{
|
||||
if (id == 0) {
|
||||
QTC_ASSERT(m_storageData->m_activeStorage, return);
|
||||
m_storageData->m_activeStorage = 0;
|
||||
return;
|
||||
}
|
||||
QTC_ASSERT(m_storageData->m_activeStorage == 0, return);
|
||||
const auto it = m_storageData->m_storageHash.find(id);
|
||||
QTC_ASSERT(it != m_storageData->m_storageHash.end(), return);
|
||||
m_storageData->m_activeStorage = id;
|
||||
}
|
||||
|
||||
Execute sequential(ExecuteMode::Sequential);
|
||||
Execute parallel(ExecuteMode::Parallel);
|
||||
Workflow stopOnError(WorkflowPolicy::StopOnError);
|
||||
|
@@ -7,8 +7,12 @@
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class TaskContainer;
|
||||
|
||||
namespace Tasking {
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT TaskInterface : public QObject
|
||||
@@ -23,6 +27,51 @@ 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();
|
||||
void deleteStorage(int id);
|
||||
void activateStorage(int id);
|
||||
|
||||
struct 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;
|
||||
};
|
||||
|
||||
template <typename StorageStruct>
|
||||
class TreeStorage : public TreeStorageBase
|
||||
{
|
||||
public:
|
||||
TreeStorage() : TreeStorageBase(TreeStorage::ctor(), TreeStorage::dtor()) {}
|
||||
StorageStruct *operator->() const noexcept { return activeStorage(); }
|
||||
|
||||
private:
|
||||
StorageStruct *activeStorage() const {
|
||||
return static_cast<StorageStruct *>(activeStorageVoid());
|
||||
}
|
||||
static StorageConstructor ctor() { return [] { return new StorageStruct; }; }
|
||||
static StorageDestructor dtor() {
|
||||
return [](void *storage) { delete static_cast<StorageStruct *>(storage); };
|
||||
}
|
||||
};
|
||||
|
||||
enum class ExecuteMode {
|
||||
Sequential, // default
|
||||
Parallel
|
||||
|
Reference in New Issue
Block a user