ExtensionSystem: Start reworking initialization order system

Allow specifying object creation without immediate creation
(but create them nevetheless very soon).

Change-Id: I01b91f7cf753ced61705d3f26352548b268be6b5
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2023-03-02 15:29:50 +01:00
parent 7869c4e810
commit b91f234c7d
3 changed files with 83 additions and 1 deletions

View File

@@ -161,12 +161,47 @@
namespace ExtensionSystem {
namespace Internal {
class ObjectInitializer
{
public:
ObjectCreator creator;
ObjectDestructor destructor;
ObjectCreationPolicy policy;
};
class IPluginPrivate
{
public:
void tryCreateObjects();
QList<TestCreator> testCreators;
QList<ObjectInitializer> objectInitializers;
QList<std::function<void()>> objectDestructors;
// For debugging purposes:
QList<void *> createdObjects; // Not owned.
};
void IPluginPrivate::tryCreateObjects()
{
QList<ObjectInitializer> unhandledObjectInitializers;
for (const ObjectInitializer &initializer : std::as_const(objectInitializers)) {
if (!initializer.policy.dependsOn.isEmpty()) {
qWarning("Initialization dependencies are not supported yet");
unhandledObjectInitializers.append(initializer);
continue;
}
void *object = initializer.creator();
createdObjects.append(object);
objectDestructors.append([initializer, object] { initializer.destructor(object); });
}
objectInitializers = unhandledObjectInitializers;
}
} // Internal
/*!
@@ -182,10 +217,20 @@ IPlugin::IPlugin()
*/
IPlugin::~IPlugin()
{
for (const std::function<void()> &dtor : std::as_const(d->objectDestructors))
dtor();
delete d;
d = nullptr;
}
void IPlugin::addManagedHelper(const ObjectCreator &creator,
const ObjectDestructor &destructor,
const ObjectCreationPolicy &policy)
{
d->objectInitializers.append({creator, destructor, policy});
}
bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
{
Q_UNUSED(arguments)
@@ -194,6 +239,14 @@ bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
return true;
}
/*!
\internal
*/
void IPlugin::tryCreateObjects()
{
d->tryCreateObjects();
}
/*!
Registers a function object that creates a test object.

View File

@@ -5,6 +5,8 @@
#include "extensionsystem_global.h"
#include <utils/id.h>
#include <QObject>
#include <functional>
@@ -15,6 +17,17 @@ namespace Internal { class IPluginPrivate; }
using TestCreator = std::function<QObject *()>;
using ObjectCreator = std::function<void *()>;
using ObjectDestructor = std::function<void(void *)>;
struct EXTENSIONSYSTEM_EXPORT ObjectCreationPolicy
{
// Can be empty if nothing depends on it.
Utils::Id id;
// Objects with empty dependencies are created as soon as possible.
QList<Utils::Id> dependsOn;
};
class EXTENSIONSYSTEM_EXPORT IPlugin : public QObject
{
Q_OBJECT
@@ -39,6 +52,7 @@ public:
// Deprecated in 10.0, use addTest()
virtual QVector<QObject *> createTestObjects() const;
virtual void tryCreateObjects();
protected:
virtual void initialize() {}
@@ -47,6 +61,17 @@ protected:
void addTest(Args && ...args) { addTestCreator([args...] { return new Test(args...); }); }
void addTestCreator(const TestCreator &creator);
template <typename Type>
void addManaged(const ObjectCreationPolicy &policy = {}) {
addManagedHelper([]() -> void * { return new Type(); },
[](void *p) { delete static_cast<Type *>(p); },
policy);
}
void addManagedHelper(const ObjectCreator &creator,
const ObjectDestructor &destructor,
const ObjectCreationPolicy &policy);
signals:
void asynchronousShutdownFinished();

View File

@@ -1119,6 +1119,7 @@ bool PluginSpecPrivate::initializePlugin()
hasError = true;
return false;
}
plugin->tryCreateObjects();
state = PluginSpec::Initialized;
return true;
}
@@ -1145,6 +1146,7 @@ bool PluginSpecPrivate::initializeExtensions()
return false;
}
plugin->extensionsInitialized();
plugin->tryCreateObjects();
state = PluginSpec::Running;
return true;
}
@@ -1164,7 +1166,9 @@ bool PluginSpecPrivate::delayedInitialize()
hasError = true;
return false;
}
return plugin->delayedInitialize();
const bool res = plugin->delayedInitialize();
plugin->tryCreateObjects();
return res;
}
/*!