forked from qt-creator/qt-creator
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:
@@ -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.
|
||||
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
Reference in New Issue
Block a user