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