您现在的位置是:主页 > news > 做网站甘特图 内容/域名查询ip网站

做网站甘特图 内容/域名查询ip网站

admin2025/6/6 2:19:08news

简介做网站甘特图 内容,域名查询ip网站,网站如何做信息表,wordpress 在线更新PluginManager ExtensionSystem命名空间提供了属于核心插件系统的类。 基本扩展系统包含插件管理器及其支持类,以及必须由插件提供程序实现的IPlugin接口。 ExtensionSystem::PluginManager类实现了管理插件,插件的生命周期及其注册对象的核心插件系统。…

做网站甘特图 内容,域名查询ip网站,网站如何做信息表,wordpress 在线更新PluginManager ExtensionSystem命名空间提供了属于核心插件系统的类。 基本扩展系统包含插件管理器及其支持类,以及必须由插件提供程序实现的IPlugin接口。 ExtensionSystem::PluginManager类实现了管理插件,插件的生命周期及其注册对象的核心插件系统。…

在这里插入图片描述

PluginManager

ExtensionSystem命名空间提供了属于核心插件系统的类。 基本扩展系统包含插件管理器及其支持类,以及必须由插件提供程序实现的IPlugin接口。
ExtensionSystem::PluginManager类实现了管理插件,插件的生命周期及其注册对象的核心插件系统。
插件管理器用于以下任务:管理插件及其状态和操纵“公共对象池”。

管理插件

插件由XML描述符文件和包含Qt插件的库组成,该Qt插件必须从IPlugin类派生,并且IID为“ org.qt-project.Qt.QtCreatorPlugin”。插件管理器用于设置文件系统目录列表,以搜索插件,检索有关这些插件状态的信息并加载它们。 通常,应用程序创建一个PluginManager实例并启动加载。
'plugins’和subdirs将在插件中搜索,loadPlugins尝试加载所有的插件。

PluginManager::setPluginPaths(QStringList("plugins"));
PluginManager::loadPlugins();

此外,可以直接访问插件规范(描述符文件中的信息),插件实例(通过PluginSpec)及其状态。

操纵“公共对象池”

插件(以及其他所有人)可以将对象添加到位于插件管理器中的公共“池”中。池中的对象必须派生自QObject,没有其他先决条件。 可以通过getObject和getObjectByName函数从对象池中检索对象。
每当对象池的状态更改时,插件管理器都会发出相应的信号。 对象池的常见用例是插件(或应用程序)为其他插件提供“扩展点”,这是可以实现并添加到对象池的类/接口。 提供扩展点的插件在对象池中查找类/接口的实现。

// Plugin A provides a "MimeTypeHandler" extension point
// in plugin B:
MyMimeTypeHandler *handler = new MyMimeTypeHandler();
PluginManager::instance()->addObject(handler);
// In plugin A:
MimeTypeHandler *mimeHandler = PluginManager::getObject<MimeTypeHandler>();

ExtensionSystem :: Invoker类模板为使用“软”扩展点提供了“语法糖”,这些扩展点可能由池中的对象提供,也可能不由池中的对象提供。 这种方法既不需要将“用户”插件链接到“提供者”插件,也不需要公共共享头文件。 公开的接口由对象池中“提供者”对象的可调用函数隐式给出。
ExtensionSystem :: invoke函数模板封装了ExtensionSystem :: Invoker构造,用于不检查调用成功的常见情况。

// In the "provide" plugin A:
namespace PluginA {class SomeProvider : public QObject{Q_OBJECTpublic:Q_INVOKABLE QString doit(const QString &msg, int n) {{qDebug() << "I AM DOING IT " << msg;return QString::number(n);}};
} // namespace PluginA// In the "user" plugin B:
int someFuntionUsingPluginA()
{using namespace ExtensionSystem;QObject *target = PluginManager::getObjectByClassName("PluginA::SomeProvider");if (target) {// Some random argument.QString msg = "REALLY.";// Plain function call, no return value.invoke<void>(target, "doit", msg, 2);// Plain function with no return value.qDebug() << "Result: " << invoke<QString>(target, "doit", msg, 21);// Record success of function call with return value.Invoker<QString> in1(target, "doit", msg, 21);qDebug() << "Success: (expected)" << in1.wasSuccessful();// Try to invoke a non-existing function.Invoker<QString> in2(target, "doitWrong", msg, 22);qDebug() << "Success (not expected):" << in2.wasSuccessful();} else {// We have to cope with plugin A's absence.}
};

传递给invoke调用的参数类型由参数本身推导得出,并且必须与被调用函数exactly的参数类型相匹配。 没有转换甚至整数提升都不适用,因此要使用long参数显式地使用long(43)等调用函数。对象池操作函数是线程安全的。

class EXTENSIONSYSTEM_EXPORT PluginManager : public QObject
{Q_OBJECT
public:static PluginManager *instance();PluginManager();~PluginManager() override;// Object pool operations 对象池操作// 将对象obj添加到对象池static void addObject(QObject *obj) { d->addObject(obj); }// 从对象池中删除对象static void removeObject(QObject *obj) { d->removeObject(obj); }// 检索池中所有对象的列表static QVector<QObject *> allObjects() { return d->allObjects; }static QReadWriteLock *listLock() { return &d->m_lock; }// This is useful for soft dependencies using pure interfaces.template <typename T> static T *getObject(){QReadLocker lock(listLock());QVector<QObject *> all = allObjects();foreach (QObject *obj, all) {if (T *result = qobject_cast<T *>(obj))return result;}return nullptr;}template <typename T, typename Predicate> static T *getObject(Predicate predicate){QReadLocker lock(listLock());QVector<QObject *> all = allObjects();foreach (QObject *obj, all) {if (T *result = qobject_cast<T *>(obj))if (predicate(result))return result;}return 0;}// 从对象池中检索一个具有名称的对象。static QObject *getObjectByName(const QString &name) {QReadLocker lock(&d->m_lock);return Utils::findOrDefault(allObjects(), [&name](const QObject *obj) {return obj->objectName() == name;});}// Plugin operations 插件操作// 返回加载顺序的插件列表。static QVector<PluginSpec *> loadQueue() { return d->loadQueue(); }// 尝试加载在设置插件搜索路径时先前找到的所有插件static void loadPlugins() { d->loadPlugins(); }// 路径列表是插件管理器搜索插件的路径static QStringList pluginPaths() { return d->pluginPaths; }// 设置插件搜索路径,即插件管理器在其中查找插件说明的文件系统路径。 在所有给定的路径及其子目录树中搜索插件xml描述文件。static void setPluginPaths(const QStringList &paths) { d->setPluginPaths(paths); }// 有效插件必须具有的IID。static QString pluginIID() { return d->pluginIID; }// 设置有效插件必须具有的IID。 仅加载具有此IID的插件,而其他插件则被忽略。static void setPluginIID(const QString &iid) { d->pluginIID = iid; }// 在插件搜索路径中找到的所有插件规范的列表。 此列表在setPluginPaths调用之后直接有效。 插件规范包含来自插件的xml描述文件的信息以及插件的当前状态。 如果插件库已经成功加载,则插件规范也将引用创建的插件实例。static const QVector<PluginSpec *> plugins() { return d->pluginSpecs; }static QHash<QString, QVector<PluginSpec *>> pluginCollections() { return d->pluginCategories; }// 如果任何插件即使启用也有错误,则返回true。static bool hasError(){return Utils::anyOf(plugins(), [](PluginSpec *spec) {// only show errors on startup if plugin is enabled.return spec->hasError() && spec->isEffectivelyEnabled();});}static const QStringList allErrors(){return Utils::transform<QStringList>(Utils::filtered(plugins(), [](const PluginSpec *spec) {return spec->hasError() && spec->isEffectivelyEnabled();}), [](const PluginSpec *spec) {return spec->name().append(": ").append(spec->errorString());});}static QSet<PluginSpec *> pluginsRequiringPlugin(PluginSpec *spec);static QSet<PluginSpec *> pluginsRequiredByPlugin(PluginSpec *spec);static void checkForProblematicPlugins(){d->checkForProblematicPlugins();}// Settings// 定义用户特定的设置以用于有关已启用和已禁用插件的信息。 需要在使用setPluginPaths设置插件搜索路径之前进行设置。static void setSettings(QSettings *settings) { d->setSettings(settings); }// 返回特定于用户的设置,以用于有关已启用的禁用插件的信息。static QSettings *settings() { return d->settings; }// 定义全局(独立于用户)设置,以用于有关默认禁用的插件的信息。 需要在使用setPluginPaths设置插件搜索路径之前进行设置。static void setGlobalSettings(QSettings *settings) { d->setGlobalSettings(settings); }// 返回用于与默认禁用插件有关的信息的全局(独立于用户)设置。static QSettings *globalSettings() { return d->globalSettings; }static void writeSettings() { d->writeSettings(); }// command line arguments// 解析后剩下的参数(既不是启动参数也不是插件参数)。 通常,这是要打开的文件列表。static QStringList arguments() { return d->arguments; }// 自动重新启动应用程序时应使用的参数。 这包括用于启用或禁用插件的插件管理器相关选项,但不包括其他选项,例如arguments返回的参数和传递给parseOptions方法的appOptions。static QStringList argumentsForRestart() { return d->argumentsForRestart; }static bool parseOptions(const QStringList &args, const QMap<QString, bool> &appOptions,QMap<QString, QString> *foundAppOptions, QString *errorString);static void formatOptions(QTextStream &str, int optionIndentation, int descriptionIndentation);static void formatPluginOptions(QTextStream &str, int optionIndentation, int descriptionIndentation);// 格式化用于命令行帮助的插件规范的版本。static void formatPluginVersions(QTextStream &str){	foreach (PluginSpec *ps, d->pluginSpecs)str << "  " << ps->name() << ' ' << ps->version() << ' ' << ps->description() <<  '\n'; }static QString serializedArguments();static bool testRunRequested() { return !d->testSpecs.empty(); }// 创建一个分析条目,如果激活了分析,则显示经过的时间。static void profilingReport(const char *what, const PluginSpec *spec = nullptr) { d->profilingReport(what, spec); }static QString platformName(){static const QString result = getPlatformName() + " (" + QSysInfo::prettyProductName() + ')';return result;}static bool isInitializationDone() { return d->m_isInitializationDone; }void remoteArguments(const QString &serializedArguments, QObject *socket);// 关闭并删除所有插件。void shutdown() { d->shutdown(); }QString systemInformation() const;
signals:void objectAdded(QObject *obj);void aboutToRemoveObject(QObject *obj);void pluginsChanged();void initializationDone();void testsFinished(int failedTests);friend class Internal::PluginManagerPrivate;
};
static Internal::PluginManagerPrivate *d = nullptr;
static PluginManager *m_instance = nullptr;

从PluginManager类的实现文件中可以看出插件管理依赖上述定义的PluginManagerPrivate和PluginManager两个静态指针。

// 创建一个插件管理器, 每个应用程序只能执行一次
PluginManager::PluginManager()
{m_instance = this;d = new PluginManagerPrivate(this);
}
// 获取唯一的插件管理器实例
PluginManager *PluginManager::instance()
{return m_instance;
}

void PluginManager::addObject(QObject *obj)将对象obj添加到对象池,以便可以按类型再次从池中检索它。 插件管理器不执行任何内存管理-添加的对象必须从池中删除,并由负责该对象的任何人手动删除。 发出objectAdded()信号。
将obj添加到对象池发送信号的函数void PluginManager::objectAdded(QObject *obj)

void PluginManager::removeObject(QObject *obj)发出aboutToRemoveObject()并从对象池中删除对象obj。

QVector<QObject *> PluginManager::allObjects()检索池中所有对象的列表,未过滤。 通常,客户端不需要调用此函数。

void PluginManager::loadPlugins()尝试加载在设置插件搜索路径时先前找到的所有插件。 插件的插件规格可用于检索有关单个插件的错误和状态信息。

QSet<PluginSpec *> PluginManager::pluginsRequiringPlugin(PluginSpec *spec)返回所有需要加载规范的插件。 递归为依赖项。

QSet<PluginSpec *> PluginManager::pluginsRequiringPlugin(PluginSpec *spec)
{QSet<PluginSpec *> dependingPlugins({spec});// recursively add plugins that depend on plugins that.... that depend on specforeach (PluginSpec *spec, d->loadQueue()) {if (spec->requiresAny(dependingPlugins))dependingPlugins.insert(spec);}dependingPlugins.remove(spec);return dependingPlugins;
}

返回所有需要加载spec的插件。 递归为依赖项。 //广度遍历

QSet<PluginSpec *> PluginManager::pluginsRequiredByPlugin(PluginSpec *spec)
{QSet<PluginSpec *> recursiveDependencies;recursiveDependencies.insert(spec);std::queue<PluginSpec *> queue;queue.push(spec);while (!queue.empty()) {PluginSpec *checkSpec = queue.front();queue.pop();const QHash<PluginDependency, PluginSpec *> deps = checkSpec->dependencySpecs();for (auto depIt = deps.cbegin(), end = deps.cend(); depIt != end; ++depIt) {if (depIt.key().type != PluginDependency::Required)continue;PluginSpec *depSpec = depIt.value();if (!recursiveDependencies.contains(depSpec)) {recursiveDependencies.insert(depSpec);queue.push(depSpec);}}}recursiveDependencies.remove(spec);return recursiveDependencies;
}

序列化插件选项和参数以通过QtSingleApplication发送单个字符串:":myplugin|-option1|-option2|:arguments|argument1|argument2"。作为由带有冒号的关键字开头的列表的列表,参数是最后的。

QString PluginManager::serializedArguments()
{const QChar separator = QLatin1Char('|');QString rc;foreach (const PluginSpec *ps, plugins()) {if (!ps->arguments().isEmpty()) {if (!rc.isEmpty())rc += separator;rc += QLatin1Char(':');rc += ps->name();rc += separator;rc +=  ps->arguments().join(separator);}}if (!rc.isEmpty())rc += separator;rc += QLatin1String(pwdKeywordC) + separator + QDir::currentPath();if (!d->arguments.isEmpty()) {if (!rc.isEmpty())rc += separator;rc += QLatin1String(argumentKeywordC);foreach (const QString &argument, d->arguments)rc += separator + argument;}return rc;
}

在\ a args中获取命令行选项的列表并进行解析。 插件管理器本身可能会直接自行处理一些选项(-noload ),并将插件注册的选项添加到其插件规格中。 调用者(应用程序)可以通过\ a appOptions列表为选项注册自己,其中包含成对的“选项字符串”和一个布尔值,用于指示选项是否需要参数。 应用程序选项始终会覆盖任何插件的选项。
对于找到的任何应用程序选项,\ a foundAppOptions都设置为成对的(“选项字符串”,“参数”)。 可以通过arguments()函数来检索未处理的命令行选项。 如果发生错误(例如缺少要求一个选项的参数),则\ a errorString包含该错误的描述性消息。 如果有错误,则返回。

bool PluginManager::parseOptions(const QStringList &args,const QMap<QString, bool> &appOptions,QMap<QString, QString> *foundAppOptions,QString *errorString)
{OptionsParser options(args, appOptions, foundAppOptions, errorString, d);return options.parse();
}

格式化插件管理器的启动选项以获取命令行帮助

void PluginManager::formatOptions(QTextStream &str, int optionIndentation, int descriptionIndentation)
{formatOption(str, QLatin1String(OptionsParser::LOAD_OPTION),QLatin1String("plugin"), QLatin1String("Load <plugin> and all plugins that it requires"),optionIndentation, descriptionIndentation);formatOption(str, QLatin1String(OptionsParser::LOAD_OPTION) + QLatin1String(" all"),QString(), QLatin1String("Load all available plugins"),optionIndentation, descriptionIndentation);formatOption(str, QLatin1String(OptionsParser::NO_LOAD_OPTION),QLatin1String("plugin"), QLatin1String("Do not load <plugin> and all plugins that require it"),optionIndentation, descriptionIndentation);formatOption(str, QLatin1String(OptionsParser::NO_LOAD_OPTION) + QLatin1String(" all"),QString(), QString::fromLatin1("Do not load any plugin (useful when ""followed by one or more \"%1\" arguments)").arg(QLatin1String(OptionsParser::LOAD_OPTION)),optionIndentation, descriptionIndentation);formatOption(str, QLatin1String(OptionsParser::PROFILE_OPTION),QString(), QLatin1String("Profile plugin loading"),optionIndentation, descriptionIndentation);
#ifdef WITH_TESTSformatOption(str, QString::fromLatin1(OptionsParser::TEST_OPTION)+ QLatin1String(" <plugin>[,testfunction[:testdata]]..."), QString(),QLatin1String("Run plugin's tests (by default a separate settings path is used)"),optionIndentation, descriptionIndentation);formatOption(str, QString::fromLatin1(OptionsParser::TEST_OPTION) + QLatin1String(" all"),QString(), QLatin1String("Run tests from all plugins"),optionIndentation, descriptionIndentation);formatOption(str, QString::fromLatin1(OptionsParser::NOTEST_OPTION),QLatin1String("plugin"), QLatin1String("Exclude all of the plugin's tests from the test run"),optionIndentation, descriptionIndentation);
#endif
}

格式化插件规范的插件选项以获取命令行帮助。

void PluginManager::formatPluginOptions(QTextStream &str, int optionIndentation, int descriptionIndentation)
{// Check plugins for optionsforeach (PluginSpec *ps, d->pluginSpecs) {const PluginSpec::PluginArgumentDescriptions pargs = ps->argumentDescriptions();if (!pargs.empty()) {str << "\nPlugin: " <<  ps->name() << '\n';foreach (PluginArgumentDescription pad, pargs)formatOption(str, pad.name, pad.parameter, pad.description, optionIndentation, descriptionIndentation);}}
}

格式化用于命令行帮助的插件规范的版本。

void PluginManager::formatPluginVersions(QTextStream &str)
{foreach (PluginSpec *ps, d->pluginSpecs)str << "  " << ps->name() << ' ' << ps->version() << ' ' << ps->description() <<  '\n';
}

解析由serializedArguments()const编码的选项,并将它们与参数一起传递给相应的插件。完成操作(例如,文档已关闭)以支持-block标志时,将传递套接字以断开对等方。

void PluginManager::remoteArguments(const QString &serializedArgument, QObject *socket)
{if (serializedArgument.isEmpty())return;QStringList serializedArguments = serializedArgument.split(QLatin1Char('|'));const QStringList pwdValue = subList(serializedArguments, QLatin1String(pwdKeywordC));const QString workingDirectory = pwdValue.isEmpty() ? QString() : pwdValue.first();const QStringList arguments = subList(serializedArguments, QLatin1String(argumentKeywordC));foreach (const PluginSpec *ps, plugins()) {if (ps->state() == PluginSpec::Running) {const QStringList pluginOptions = subList(serializedArguments, QLatin1Char(':') + ps->name());QObject *socketParent = ps->plugin()->remoteCommand(pluginOptions, workingDirectory,arguments);if (socketParent && socket) {socket->setParent(socketParent);socket = nullptr;}}}if (socket)delete socket;
}

PluginManagerPrivate

class EXTENSIONSYSTEM_EXPORT PluginManagerPrivate : public QObject
{Q_OBJECT
public:PluginManagerPrivate(PluginManager *pluginManager) : q(pluginManager) {}~PluginManagerPrivate() override;// Object pool operations 对象池操作void addObject(QObject *obj);void removeObject(QObject *obj);// Plugin operations 插件操作void checkForProblematicPlugins();void loadPlugins();void shutdown();void setPluginPaths(const QStringList &paths);QVector<ExtensionSystem::PluginSpec *> loadQueue();void loadPlugin(PluginSpec *spec, PluginSpec::State destState);void resolveDependencies();void enableDependenciesIndirectly();void initProfiling();void profilingSummary() const;void profilingReport(const char *what, const PluginSpec *spec = nullptr);void setSettings(QSettings *settings);void setGlobalSettings(QSettings *settings);void readSettings();void writeSettings();class TestSpec {public:TestSpec(PluginSpec *pluginSpec, const QStringList &testFunctionsOrObjects = QStringList()): pluginSpec(pluginSpec), testFunctionsOrObjects(testFunctionsOrObjects){}PluginSpec *pluginSpec = nullptr;QStringList testFunctionsOrObjects;};bool containsTestSpec(PluginSpec *pluginSpec) const{return Utils::contains(testSpecs, [pluginSpec](const TestSpec &s) { return s.pluginSpec == pluginSpec; });}void removeTestSpec(PluginSpec *pluginSpec){testSpecs = Utils::filtered(testSpecs, [pluginSpec](const TestSpec &s) { return s.pluginSpec != pluginSpec; });}QHash<QString, QVector<PluginSpec *>> pluginCategories;QVector<PluginSpec *> pluginSpecs;std::vector<TestSpec> testSpecs;QStringList pluginPaths;QString pluginIID;QVector<QObject *> allObjects;      // ### make this a QVector<QPointer<QObject> > > ?QStringList defaultDisabledPlugins; // Plugins/Ignored from install settingsQStringList defaultEnabledPlugins; // Plugins/ForceEnabled from install settingsQStringList disabledPlugins;QStringList forceEnabledPlugins;// delayed initializationQTimer *delayedInitializeTimer = nullptr;std::queue<PluginSpec *> delayedInitializeQueue;// ansynchronous shutdownQSet<PluginSpec *> asynchronousPlugins;  // plugins that have requested async shutdownQEventLoop *shutdownEventLoop = nullptr; // used for async shutdownQStringList arguments;QStringList argumentsForRestart;QScopedPointer<QElapsedTimer> m_profileTimer;QHash<const PluginSpec *, int> m_profileTotal;int m_profileElapsedMS = 0;unsigned m_profilingVerbosity = 0;QSettings *settings = nullptr;QSettings *globalSettings = nullptr;// Look in argument descriptions of the specs for the option.PluginSpec *pluginForOption(const QString &option, bool *requiresArgument) const;PluginSpec *pluginByName(const QString &name) const;// used by testsstatic PluginSpec *createSpec() { return new PluginSpec(); }static PluginSpecPrivate *privateSpec(PluginSpec *spec) { return spec->d; }mutable QReadWriteLock m_lock;bool m_isInitializationDone = false;
private:PluginManager *q;void nextDelayedInitialize();void asyncShutdownFinished();void readPluginPaths();bool loadQueue(PluginSpec *spec,QVector<ExtensionSystem::PluginSpec *> &queue,QVector<ExtensionSystem::PluginSpec *> &circularityCheckQueue);void stopAll();void deleteAll();
#ifdef WITH_TESTSvoid startTests();
#endif
};

对象池操作

QScopedPointer<QElapsedTimer> m_profileTimer
QElapsedTimer类提供了一种计算经过时间的快速方法。QElapsedTimer类通常用于快速计算两个事件之间经过了多少时间。 它的API与QTime相似,因此可以将正在使用的代码快速移植到新类中。但是,与QTime不同,QElapsedTimer在可能的情况下尝试使用单调时钟。 这意味着不可能将QElapsedTimer对象转换为人类可读的时间。该类的典型用例是确定在缓慢的操作上花费了多少时间。 这种情况的最简单示例是出于调试目的,如以下示例所示:

QElapsedTimer timer;
timer.start();
slowOperation1();
qDebug() << "The slow operation took" << timer.elapsed() << "milliseconds";

在此示例中,计时器是通过调用start来启动的,而经过的计时器是由elapsed函数计算的。

void PluginManagerPrivate::addObject(QObject *obj)
{QWriteLocker lock(&m_lock);if (obj == nullptr) {qWarning() << "PluginManagerPrivate::addObject(): trying to add null object";return; }if (allObjects.contains(obj)) {qWarning() << "PluginManagerPrivate::addObject(): trying to add duplicate object";return; }if (debugLeaks)qDebug() << "PluginManagerPrivate::addObject" << obj << obj->objectName();if (m_profilingVerbosity && !m_profileTimer.isNull()) {// Report a timestamp when adding an object. Useful for profiling// its initialization time.const int absoluteElapsedMS = int(m_profileTimer->elapsed());qDebug("  %-43s %8dms", obj->metaObject()->className(), absoluteElapsedMS); }allObjects.append(obj);emit q->objectAdded(obj);
}
void PluginManagerPrivate::removeObject(QObject *obj)
{if (obj == nullptr) {qWarning() << "PluginManagerPrivate::removeObject(): trying to remove null object";return; }if (!allObjects.contains(obj)) {qWarning() << "PluginManagerPrivate::removeObject(): object not in list:" << obj << obj->objectName();return; }if (debugLeaks)qDebug() << "PluginManagerPrivate::removeObject" << obj << obj->objectName();emit q->aboutToRemoveObject(obj);QWriteLocker lock(&m_lock);allObjects.removeAll(obj);
}

插件操作

// 设置插件settings和globalSettings的QSettings
void PluginManagerPrivate::setSettings(QSettings *s)
{if (settings)delete settings;settings = s;if (settings)settings->setParent(this);
}
void PluginManagerPrivate::setGlobalSettings(QSettings *s)
{if (globalSettings)delete globalSettings;globalSettings = s;if (globalSettings)globalSettings->setParent(this);
}
// 根据settings和globalSettings读配置
void PluginManagerPrivate::readSettings()
{if (globalSettings) {defaultDisabledPlugins = globalSettings->value(QLatin1String(C_IGNORED_PLUGINS)).toStringList();defaultEnabledPlugins = globalSettings->value(QLatin1String(C_FORCEENABLED_PLUGINS)).toStringList();}if (settings) {disabledPlugins = settings->value(QLatin1String(C_IGNORED_PLUGINS)).toStringList();forceEnabledPlugins = settings->value(QLatin1String(C_FORCEENABLED_PLUGINS)).toStringList();}
}
// 根据插件的enabledByDefault和EnabledBySettings写配置
void PluginManagerPrivate::writeSettings()
{if (!settings)return;QStringList tempDisabledPlugins;QStringList tempForceEnabledPlugins;foreach (PluginSpec *spec, pluginSpecs) {if (spec->isEnabledByDefault() && !spec->isEnabledBySettings())tempDisabledPlugins.append(spec->name());if (!spec->isEnabledByDefault() && spec->isEnabledBySettings())tempForceEnabledPlugins.append(spec->name());}settings->setValue(QLatin1String(C_IGNORED_PLUGINS), tempDisabledPlugins);settings->setValue(QLatin1String(C_FORCEENABLED_PLUGINS), tempForceEnabledPlugins);
}
// 设置需加载的插件路劲
void PluginManagerPrivate::setPluginPaths(const QStringList &paths)
{qCDebug(pluginLog) << "Plugin search paths:" << paths;qCDebug(pluginLog) << "Required IID:" << pluginIID;pluginPaths = paths;readSettings();readPluginPaths();
}
bool PluginManagerPrivate::loadQueue(PluginSpec *spec,QVector<PluginSpec *> &queue,QVector<PluginSpec *> &circularityCheckQueue)
{if (queue.contains(spec))return true;// check for circular dependenciesif (circularityCheckQueue.contains(spec)) {spec->d->hasError = true;spec->d->errorString = PluginManager::tr("Circular dependency detected:");spec->d->errorString += QLatin1Char('\n');int index = circularityCheckQueue.indexOf(spec);for (int i = index; i < circularityCheckQueue.size(); ++i) {spec->d->errorString.append(PluginManager::tr("%1 (%2) depends on").arg(circularityCheckQueue.at(i)->name()).arg(circularityCheckQueue.at(i)->version()));spec->d->errorString += QLatin1Char('\n');}spec->d->errorString.append(PluginManager::tr("%1 (%2)").arg(spec->name()).arg(spec->version()));return false;}circularityCheckQueue.append(spec);// check if we have the dependenciesif (spec->state() == PluginSpec::Invalid || spec->state() == PluginSpec::Read) {queue.append(spec);return false;}// add dependenciesconst QHash<PluginDependency, PluginSpec *> deps = spec->dependencySpecs();for (auto it = deps.cbegin(), end = deps.cend(); it != end; ++it) {// Skip test dependencies since they are not real dependencies but just force-loaded// plugins when running testsif (it.key().type == PluginDependency::Test)continue;PluginSpec *depSpec = it.value();if (!loadQueue(depSpec, queue, circularityCheckQueue)) {spec->d->hasError = true;spec->d->errorString =PluginManager::tr("Cannot load plugin because dependency failed to load: %1 (%2)\nReason: %3").arg(depSpec->name()).arg(depSpec->version()).arg(depSpec->errorString());return false;}}// add selfqueue.append(spec);return true;
}
QVector<PluginSpec *> PluginManagerPrivate::loadQueue()
{QVector<PluginSpec *> queue;foreach (PluginSpec *spec, pluginSpecs) {QVector<PluginSpec *> circularityCheckQueue;loadQueue(spec, queue, circularityCheckQueue);}return queue;
}
void PluginManagerPrivate::loadPlugins()
{QVector<PluginSpec *> queue = loadQueue();Utils::setMimeStartupPhase(MimeStartupPhase::PluginsLoading);foreach (PluginSpec *spec, queue) {loadPlugin(spec, PluginSpec::Loaded);}Utils::setMimeStartupPhase(MimeStartupPhase::PluginsInitializing);foreach (PluginSpec *spec, queue) {loadPlugin(spec, PluginSpec::Initialized);}Utils::setMimeStartupPhase(MimeStartupPhase::PluginsDelayedInitializing);Utils::reverseForeach(queue, [this](PluginSpec *spec) {loadPlugin(spec, PluginSpec::Running);if (spec->state() == PluginSpec::Running) {delayedInitializeQueue.push(spec);} else {// Plugin initialization failed, so cleanup after itspec->d->kill();}});emit q->pluginsChanged();Utils::setMimeStartupPhase(MimeStartupPhase::UpAndRunning);//延时初始化delayedInitializeTimer = new QTimer;delayedInitializeTimer->setInterval(DELAYED_INITIALIZE_INTERVAL);delayedInitializeTimer->setSingleShot(true);connect(delayedInitializeTimer, &QTimer::timeout,this, &PluginManagerPrivate::nextDelayedInitialize);delayedInitializeTimer->start();
}
void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destState)
{if (spec->hasError() || spec->state() != destState-1)return;// don't load disabled plugins.if (!spec->isEffectivelyEnabled() && destState == PluginSpec::Loaded)return;LockFile f(this, spec);switch (destState) {case PluginSpec::Running:profilingReport(">initializeExtensions", spec);spec->d->initializeExtensions();profilingReport("<initializeExtensions", spec);return;case PluginSpec::Deleted:profilingReport(">delete", spec);spec->d->kill();profilingReport("<delete", spec);return;default:break;}// check if dependencies have loaded without errorconst QHash<PluginDependency, PluginSpec *> deps = spec->dependencySpecs();for (auto it = deps.cbegin(), end = deps.cend(); it != end; ++it) {if (it.key().type != PluginDependency::Required)continue;PluginSpec *depSpec = it.value();if (depSpec->state() != destState) {spec->d->hasError = true;spec->d->errorString =PluginManager::tr("Cannot load plugin because dependency failed to load: %1(%2)\nReason: %3").arg(depSpec->name()).arg(depSpec->version()).arg(depSpec->errorString());return;}}switch (destState) {case PluginSpec::Loaded:profilingReport(">loadLibrary", spec);spec->d->loadLibrary();profilingReport("<loadLibrary", spec);break;case PluginSpec::Initialized:profilingReport(">initializePlugin", spec);spec->d->initializePlugin();profilingReport("<initializePlugin", spec);break;case PluginSpec::Stopped:profilingReport(">stop", spec);if (spec->d->stop() == IPlugin::AsynchronousShutdown) {asynchronousPlugins << spec;connect(spec->plugin(), &IPlugin::asynchronousShutdownFinished,this, &PluginManagerPrivate::asyncShutdownFinished);}profilingReport("<stop", spec);break;default:break;}
}

查看该选项规格的参数描述。

PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *requiresArgument) const
{// Look in the plugins for an option*requiresArgument = false;foreach (PluginSpec *spec, pluginSpecs) {PluginArgumentDescription match = Utils::findOrDefault(spec->argumentDescriptions(),[option](PluginArgumentDescription pad) {return pad.name == option;});if (!match.name.isEmpty()) {*requiresArgument = !match.parameter.isEmpty();return spec;}}return nullptr;
}

main函数中的使用

const QStringList pluginArguments = app.arguments();
QSettings *settings = userSettings();
QSettings *globalSettings = new QSettings(QSettings::IniFormat, QSettings::SystemScope, QLatin1String(Core::Constants::IDE_SETTINGSVARIANT_STR), QLatin1String(Core::Constants::IDE_CASED_ID));
PluginManager pluginManager;
PluginManager::setPluginIID(QLatin1String("org.qt-project.Qt.QtCreatorPlugin")); // 设置PluginIID的值为org.qt-project.Qt.QtCreatorPlugin
PluginManager::setGlobalSettings(globalSettings);
PluginManager::setSettings(settings); // Load
const QStringList pluginPaths = getPluginPaths() + options.customPluginPaths;
PluginManager::setPluginPaths(pluginPaths);
QMap<QString, QString> foundAppOptions;
if (pluginArguments.size() > 1) { // 如果pluginArguments参数QString数量大于1QMap<QString, bool> appOptions;appOptions.insert(QLatin1String(HELP_OPTION1), false);appOptions.insert(QLatin1String(HELP_OPTION2), false);appOptions.insert(QLatin1String(HELP_OPTION3), false);appOptions.insert(QLatin1String(HELP_OPTION4), false);appOptions.insert(QLatin1String(VERSION_OPTION), false);appOptions.insert(QLatin1String(CLIENT_OPTION), false);appOptions.insert(QLatin1String(PID_OPTION), true);appOptions.insert(QLatin1String(BLOCK_OPTION), false);QString errorMessage;if (!PluginManager::parseOptions(pluginArguments, appOptions, &foundAppOptions, &errorMessage)) {displayError(errorMessage);printHelp(QFileInfo(app.applicationFilePath()).baseName());return -1;}
}  
restarter.setArguments(options.preAppArguments + PluginManager::argumentsForRestart() + lastSessionArgument());const PluginSpecSet plugins = PluginManager::plugins();
PluginSpec *coreplugin = nullptr;
foreach (PluginSpec *spec, plugins) {if (spec->name() == QLatin1String(corePluginNameC)) {coreplugin = spec;break;}
}
if (!coreplugin) {QString nativePaths = QDir::toNativeSeparators(pluginPaths.join(QLatin1Char(',')));const QString reason = QCoreApplication::translate("Application", "Could not find Core plugin in %1").arg(nativePaths);displayError(msgCoreLoadFailure(reason));return 1;
}
if (!coreplugin->isEffectivelyEnabled()) {const QString reason = QCoreApplication::translate("Application", "Core plugin is disabled.");displayError(msgCoreLoadFailure(reason));return 1;
}
if (coreplugin->hasError()) {displayError(msgCoreLoadFailure(coreplugin->errorString()));return 1;
}  PluginManager::checkForProblematicPlugins();
PluginManager::loadPlugins();
if (coreplugin->hasError()) {displayError(msgCoreLoadFailure(coreplugin->errorString()));return 1;
}// Set up remote arguments.
QObject::connect(&app, &SharedTools::QtSingleApplication::messageReceived,&pluginManager, &PluginManager::remoteArguments);QObject::connect(&app, SIGNAL(fileOpenRequest(QString)), coreplugin->plugin(),SLOT(fileOpenRequest(QString)));// shutdown plugin manager on the exit
QObject::connect(&app, &QCoreApplication::aboutToQuit, &pluginManager, &PluginManager::shutdown);

Qt Creator源码分析系列——extensionsystem::IPlugin
Qt Creator源码分析系列——extensionsystem::PluginSpec