aboutsummaryrefslogtreecommitdiffstats
path: root/doc/api/plugin-lifecycle.qdoc
blob: fa6aef6575620c81b0564a755ef689347d16d0cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
**
****************************************************************************/

/*!
    \page plugin-lifecycle.html
    \title Plugin Life Cycle

    To be able to write \QC plugins, you must understand the steps that the plugin
    manager takes when you start or shut down \QC. This section describes
    the process and the state that plugins go through in detail.

    You can get more information about what happens when you start \QC by running it with the
    environment variable \c QT_LOGGING_RULES set to \c {qtc.extensionsystem*=true} which enables
    logging of plugin-related debug output.

    When you start \QC, the plugin manager does the following:

    \list 1
        \li Looks in its search paths for
            all dynamic libraries, and reads their meta data. All libraries without meta data
            and all libraries without the \c{org.qt-project.Qt.QtCreatorPlugin} IID are ignored.
            This is the first point where loading a plugin can fail in the worst case of malformed
            meta data.

        \li Creates an instance of the \l{ExtensionSystem::PluginSpec} class for
            each plugin. This class is a container for
            all the information from the plugin specification, and additionally
            tracks the state of the plugin.
            You can get the \l{ExtensionSystem::PluginSpec} instances via the
            plugin manager's \l{ExtensionSystem::PluginManager::plugins()}{plugins()}
            function, or, after a plugin is loaded, through the plugin's
            \l{ExtensionSystem::IPlugin::pluginSpec()}{pluginSpec()} function.

        \li Sets the plugins to \c Read state.

        \li Verifies that the dependencies of each plugin
            exist and are compatible. For more information about plugin dependencies,
            see \l{Plugin Specifications}.

        \li Sets the plugins to \c Resolved state.

        \li Sorts all plugins into a list that we call the \e{load queue}, where the
            dependencies of a plugin are positioned after the plugin
            (but not necessarily \e directly after the plugin).
            It will make sure that we load
            and initialize the plugins in proper order.

        \li Loads the plugins' libraries, and creates their IPlugin instances
            in the order of the load queue. At this point the
            plugin constructors are called. Plugins that other plugins depend on
            are created first.

        \li Sets the plugins to \c Loaded state.

        \li Calls the \l{ExtensionSystem::IPlugin::initialize()}{initialize()} functions of
            all plugins in the order of the load queue. In the \c initialize function,
            a plugin should make sure that all exported interfaces are set up and available
            to other plugins. A plugin can assume that plugins they depend on have set up
            their exported interfaces. For example, the \c Core plugin sets up the
            \l{Core::ActionManager}, \l{Core::EditorManager} and all other publicly available
            interfaces, so other plugins can request and use them.

            The \l{ExtensionSystem::IPlugin::initialize()}{initialize()} function of a plugin
            is a good place for
            \list
               \li registering objects in the plugin manager's object pool
                   (see \l{The Plugin Manager, the Object Pool, and Registered Objects})
               \li loading settings
               \li adding new menus, and new actions to menus
               \li connecting to other plugin's signals.
           \endlist

        \li Sets the plugins to \c Initialized state.

        \li Calls the \l{ExtensionSystem::IPlugin::extensionsInitialized()}{extensionsInitialized()}
            functions of all plugins in \e reverse order of the load queue. After
            the \c extensionsInitialized function, a plugin should be fully initialized, set up
            and running. A plugin can assume that plugins that depend on it are fully set up,
            and can finish the initialization of parts that can be extended by other plugins.
            For example, the \c Core plugin assumes that all plugins have registered
            their actions, and finishes initialization of the action manager.

        \li Sets the plugins to \c Running state.
    \endlist

    At the end of startup, the \c Core plugin's \l{Core::ICore} sends two signals.
    Before the \QC UI is shown it sends \l{Core::ICore::coreAboutToOpen()}{coreAboutToOpen()},
    and afterwards \l{Core::ICore::coreOpened()}{coreOpened()}.

    After startup, when the event loop of \QC is running, the plugin manager calls
    the \l{ExtensionSystem::IPlugin::delayedInitialize()}{delayedInitialize()} functions of all
    plugins in \e reverse order of the load queue. The calls are done on the main thread, but
    separated by a delay of a few milliseconds to ensure responsiveness of \QC.
    In the \c delayedInitialize function, a plugin can perform non-critical initialization
    that could unnecessarily delay showing the \QC UI if done during startup.

    After all delayed initializations are done the \l{ExtensionSystem::PluginManager}{PluginManager}
    sends the \l{ExtensionSystem::PluginManager::initializationDone()}{initializationDone()} signal.

    Before shutdown, the \c Core plugin \l{Core::ICore} sends the
    \l{Core::ICore::coreAboutToClose()}{coreAboutToClose()} signal. After that, the
    plugin manager starts its shutdown sequence:

    \list 1
        \li Calls the \l{ExtensionSystem::IPlugin::aboutToShutdown()}{aboutToShutdown()} functions of
            all plugins in the order of the load queue. Plugins should perform measures
            for speeding up the actual shutdown here, like disconnecting signals that
            would otherwise needlessly be called.
            If a plugin needs to delay the real shutdown for a while, for example if
            it needs to wait for external processes to finish for a clean shutdown,
            the plugin can return \l{ExtensionSystem::IPlugin::AsynchronousShutdown} from this
            function. This will make the plugin manager wait with the next step, and keep the main
            event loop running, until all plugins requesting AsynchronousShutdown have sent
            the asynchronousShutdownFinished() signal.

        \li Destroys all plugins by deleting their \l{ExtensionSystem::IPlugin}
            instances in \e reverse order of the load queue. At this point the plugin destructors
            are called. Plugins should clean up after themselves by freeing memory and other resources.
    \endlist
*/