diff options
author | hjk <hjk@qt.io> | 2023-03-02 15:29:50 +0100 |
---|---|---|
committer | hjk <hjk@qt.io> | 2023-05-16 10:51:14 +0000 |
commit | b91f234c7daf03b116ac5bd882cac286d520ee7f (patch) | |
tree | a2c6e5cdc29209b4dda73a3817944d53f4307381 /src | |
parent | 7869c4e8103d1ba6e71b683e94ed7ae8dd04b8c0 (diff) | |
download | qt-creator-b91f234c7daf03b116ac5bd882cac286d520ee7f.tar.gz |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/extensionsystem/iplugin.cpp | 53 | ||||
-rw-r--r-- | src/libs/extensionsystem/iplugin.h | 25 | ||||
-rw-r--r-- | src/libs/extensionsystem/pluginspec.cpp | 6 |
3 files changed, 83 insertions, 1 deletions
diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp index 9f7ca221e5..6661a46f61 100644 --- a/src/libs/extensionsystem/iplugin.cpp +++ b/src/libs/extensionsystem/iplugin.cpp @@ -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) @@ -195,6 +240,14 @@ bool IPlugin::initialize(const QStringList &arguments, QString *errorString) } /*! + \internal +*/ +void IPlugin::tryCreateObjects() +{ + d->tryCreateObjects(); +} + +/*! Registers a function object that creates a test object. The created objects are meant to be passed on to \l QTest::qExec(). diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h index 5a8fceb3d6..3e477e42e8 100644 --- a/src/libs/extensionsystem/iplugin.h +++ b/src/libs/extensionsystem/iplugin.h @@ -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(); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index d18f410e81..62b3c0096f 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -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; } /*! |