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

ExtensionSystem::IPlugin类

IPlugin类是所有插件的基类。IPlugin类是一个抽象类,必须为每个插件实现一次。 插件由两部分组成:一个描述文件和一个至少包含IPlugin实现的库。
插件规格Specification:插件除了实际的插件库外,还需要提供插件规范文件,以便插件管理器可以找到插件,解决其依赖关系并加载它。
插件实现Implementation:插件必须提供IPlugin类的一种实现,该实现位于与XML描述中给出的name属性匹配的库中。 必须使用I_ID设置为“ org.qt-project.Qt.QtCreatorPlugin”的Q_PLUGIN_METADATA宏将IPlugin实现导出并告知Qt的插件系统。
读取插件的XML文件并找到依赖项之后,插件加载分为三个阶段:
所有插件库均以依赖树的root-to-leaf顺序加载。所有插件的initialize初始化函数都以依赖树的root-to-leaf顺序调用。现在是创建其他插件所需的对象并通过适当的核心功能注册它们的好时机,或者,如果需要实现较弱的依赖性,则可以将它们放入全局对象池中。所有插件的extensionsInitialized扩展名初始化函数均以依赖树的leaf-to-roo}顺序调用。 此时,插件可以确保依赖于此插件的所有插件都已完全初始化,并且这些插件希望共享的对象已注册或在全局对象池中可用。如果库加载或插件初始化失败,则依赖于该插件的所有插件也会失败。

class IPluginPrivate
{
public:
    PluginSpec *pluginSpec;
};

IPlugin类的构造函数主要工作是初始化IPluginPrivate指针成员。根据上面IPluginPrivate类定义,其定义了PluginSpec的指针(插件规格Specification)。

class EXTENSIONSYSTEM_EXPORT IPlugin : public QObject
{
    Q_OBJECT
public:
    enum ShutdownFlag { SynchronousShutdown, AsynchronousShutdown };
    IPlugin() : d(new Internal::IPluginPrivate()) {};
    ~IPlugin() override;
    virtual bool initialize(const QStringList &arguments, QString *errorString) = 0;
    virtual void extensionsInitialized() = 0;
    virtual bool delayedInitialize() { return false; }
    virtual ShutdownFlag aboutToShutdown() { return SynchronousShutdown; }
    virtual QObject *remoteCommand(const QStringList & /* options */, const QString & /* workingDirectory */, const QStringList & /* arguments */) { return nullptr; }
    virtual QVector<QObject *> createTestObjects() const;
    PluginSpec *pluginSpec() const;
signals:
    void asynchronousShutdownFinished();
private:
    Internal::IPluginPrivate *d;
    friend class Internal::PluginSpecPrivate;
};

初始化

bool IPlugin::initialize(const QStringList &arguments, QString *errorString)在加载插件并创建IPlugin实例后调用。在调用此插件的初始化函数之后,将调用依赖于此插件的插件的初始化函数。插件应在此函数中初始化其内部状态。 如果初始化成功,则返回。 如果不成功,则应将errorString设置为用户可读的描述原因的消息。
void IPlugin::extensionsInitialized()在调用IPlugin :: initialize函数之后,并且在依赖于此插件的插件的IPlugin:: initialize和IPlugin:: extensionsInitialized函数都被调用之后,调用此方法。在此功能中,插件可以假定依赖于此插件的插件已完全“启动并正在运行”。 在全局对象池中查找弱依赖插件提供的对象的好地方。
bool IPlugin::delayedInitialize()在所有插件的IPlugin :: extensionsInitialized函数被调用之后,以及在依赖于此插件的插件的IPlugin :: delayedInitialize函数被调用之后调用。
插件的delayInitialize函数在应用程序已经运行之后被调用,延迟了几毫秒到应用程序启动,并且在各个delayInitialize函数调用之间。 为了避免不必要的延迟,如果插件实际实现了该功能,则该插件应从该函数返回true,以指示下一个插件的delayInitialize()调用应延迟几毫秒,以使输入和绘画事件有机会被处理。
如果插件需要执行非平凡的设置non-trivial setup(不一定需要在启动时直接完成,但仍应在短时间内完成),则可以使用此功能。 这可以非常轻松地减少很多毡插件/应用程序的启动时间。
IPlugin::ShutdownFlag IPlugin::aboutToShutdown()在关闭序列期间按与初始化相同的顺序调用,然后以相反的顺序删除插件。通常,此功能应用于与其他插件断开连接,隐藏所有UI并优化关机。 如果插件需要延迟实际关闭一段时间,例如,如果需要等待外部进程完成干净关闭,则插件可以从此函数返回IPlugin :: AsynchronousShutdown。 在aboutToShutdown()序列完成之后,这将使主事件循环保持运行状态,直到所有请求AsynchronousShutdown的插件都发送了asynchronousShutdownFinished()信号为止。该函数的默认实现不执行任何操作,并返回IPlugin :: SynchronousShutdown。如果插件需要在执行关闭操作之前执行异步操作,则返回IPlugin :: AsynchronousShutdown。
QObject *IPlugin::remoteCommand(const QStringList &options, const QStringList &arguments)如果已经在另一个\ QC实例正在运行时使用-client参数执行\ QC,则在正在运行的实例中调用此插件功能。特定于插件的参数在\ a选项中传递,而其余参数在\ a参数中传递。返回一个QObject,如果使用-block,它将阻塞命令直到销毁为止。
void IPlugin::asynchronousShutdownFinished()在异步关闭准备好继续执行关闭序列之后,由插件实现发送。

QVector<QObject *> IPlugin::createTestObjects() const
{
    return {};
}

返回打算传递给QTest :: qExec()的对象。
如果用户以’-test PluginName’或’-test all’开始\ QC,则将调用此函数。
返回对象的所有权转移给调用者。

PluginSpec *IPlugin::pluginSpec() const
{
    return d->pluginSpec;
}

返回与此插件相对应的PluginSpec。
这在构造函数中不可用。

发布了134 篇原创文章 · 获赞 141 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/asmartkiller/article/details/104444362
今日推荐