summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhjk <hjk@qt.io>2023-03-02 15:29:50 +0100
committerhjk <hjk@qt.io>2023-05-16 10:51:14 +0000
commitb91f234c7daf03b116ac5bd882cac286d520ee7f (patch)
treea2c6e5cdc29209b4dda73a3817944d53f4307381 /src
parent7869c4e8103d1ba6e71b683e94ed7ae8dd04b8c0 (diff)
downloadqt-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.cpp53
-rw-r--r--src/libs/extensionsystem/iplugin.h25
-rw-r--r--src/libs/extensionsystem/pluginspec.cpp6
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;
}
/*!