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 ExtensionSystem {
namespace Internal { namespace Internal {
class ObjectInitializer
{
public:
ObjectCreator creator;
ObjectDestructor destructor;
ObjectCreationPolicy policy;
};
class IPluginPrivate class IPluginPrivate
{ {
public: public:
void tryCreateObjects();
QList<TestCreator> testCreators; 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 } // Internal
/*! /*!
@@ -182,10 +217,20 @@ IPlugin::IPlugin()
*/ */
IPlugin::~IPlugin() IPlugin::~IPlugin()
{ {
for (const std::function<void()> &dtor : std::as_const(d->objectDestructors))
dtor();
delete d; delete d;
d = nullptr; 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) bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
{ {
Q_UNUSED(arguments) Q_UNUSED(arguments)
@@ -194,6 +239,14 @@ bool IPlugin::initialize(const QStringList &arguments, QString *errorString)
return true; return true;
} }
/*!
\internal
*/
void IPlugin::tryCreateObjects()
{
d->tryCreateObjects();
}
/*! /*!
Registers a function object that creates a test object. Registers a function object that creates a test object.

View File

@@ -5,6 +5,8 @@
#include "extensionsystem_global.h" #include "extensionsystem_global.h"
#include <utils/id.h>
#include <QObject> #include <QObject>
#include <functional> #include <functional>
@@ -15,6 +17,17 @@ namespace Internal { class IPluginPrivate; }
using TestCreator = std::function<QObject *()>; 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 class EXTENSIONSYSTEM_EXPORT IPlugin : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -39,6 +52,7 @@ public:
// Deprecated in 10.0, use addTest() // Deprecated in 10.0, use addTest()
virtual QVector<QObject *> createTestObjects() const; virtual QVector<QObject *> createTestObjects() const;
virtual void tryCreateObjects();
protected: protected:
virtual void initialize() {} virtual void initialize() {}
@@ -47,6 +61,17 @@ protected:
void addTest(Args && ...args) { addTestCreator([args...] { return new Test(args...); }); } void addTest(Args && ...args) { addTestCreator([args...] { return new Test(args...); }); }
void addTestCreator(const TestCreator &creator); 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: signals:
void asynchronousShutdownFinished(); void asynchronousShutdownFinished();

View File

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