OverviewQtilities provides an extension management library which has the following goals and responsibilities:
The Qtilities::ExtensionSystem::ExtensionSystemCore singleton provides the interface through which these tasks can be achieved. This article will provide details of how the extension system achieves these goals and give an overview of the different features provided. Table of contents: |
|
The Qtilities::ExtensionSystem::Interfaces::IPlugin interface defines the interface between the extension system and plugins it can load. The interface provides status information about the state of a plugin as well as information about the plugin itself and was made as lightweight as possible. Therefore it does not inherit from anything and any object can implement it.
Lets look at a simplified version of the PluginTemplate
example in the QtilitiesPlugins
project which is a ready to use template implementing this interface. First lets look at the header file:
Next we look at the .cpp implementation file:
The implementation above shows that it is very easy to implement the interface and the best place to start is to use Qtilities::Plugins::Template.
The Qtilities::ExtensionSystem::ExtensionSystemCore::initialize() function loads plugins from path(s) defined in Qtilities::ExtensionSystem::ExtensionSystemCore::pluginPaths(). By default all plugins in the EXECUTABLE_PATH/plugin
directory are loaded and new paths can be added using the Qtilities::ExtensionSystem::ExtensionSystemCore::addPluginPath() function.
During the loading process, the extension system core class emits the newProcessMessage()
signal with progress messages which can be connected to a splash window if necessary (see the Qtilities::Examples::MainWindow example which demonstrates this for more information).
The example below shows how to use the extension system to load plugins in your application's main() function.
The above example registers the Qtilities::ExtensionSystem::PluginInfoWidget widget in the global object pool which is discussed in the Goal 3: Provide plugin information at runtime section.
The diagram below shows the sequence in which plugins are initialized during the plugin loading process.
Plugins should register any objects in which other plugins or the main application might be interested in (configuration pages, contexts) etc. in the Qtilities::ExtensionSystem::Interfaces::IPlugin::initialize() function implementation. After all plugin instances were created and added to the global object pool, this function is called on all plugins. That is, all plugins are loaded first before any of them are initialized. To make things clear, lets look at simplified version of the initialize()
function implementation in the Qtilities::Plugins::SessionLog plugin:
This is followed by calling the Qtilities::ExtensionSystem::Interfaces::IPlugin::initializeDependencies() function on all plugins. In this function plugins can inspect the global object pool to for interfaces they are interested in using the Qtilities::Core::Interfaces::IObjectManager::registeredInterfaces() function. Again, to make things clear lets write an implementation of the initializeDependencies()
function which looks for all projects parts registered in the global object pool:
The main access point to information about loaded plugins is the extension system configuration widget class (Qtilities::ExtensionSystem::ExtensionSystemConfig). The configuration widget is shown below:
The "Plugin Paths" tab in the configuration widget provides details about the paths searched for plugins, thus it shows the paths returned by Qtilities::ExtensionSystem::ExtensionSystemCore::pluginPaths(). For each plugin we can get detailed information by double clicking its name, or by clicking the "Details" button. The image below shows the detailed information of one of the provided Qtilities plugins.
In advanced applications it is often desirable to specify a set of plugins which should be loaded for different scenarios. In Qtilities we call a set of plugins that must be loaded for a specific scenario a plugin configuration set.
The extension system allow management of different configuration sets which groups plugins into the following groups:
A configuration set gives the names of the plugins which falls into the inactive and filtered plugin groups. When a plugin is found during the Qtilities::ExtensionSystem::ExtensionSystemCore::initialize() function call, the plugin is checked agains the information provided by the configuration set and handled accordingly. When a plugin is found which is not categorized in the configuration set, it automatically falls under the Active Plugins category. In the same way, if a plugin occurs under more than one category in the configuration set, it automatically falls under the Active Plugins set.
The Qtilities::ExtensionSystem::ExtensionSystemCore class provides different functions to get information about the plugins that fell into the different categories during initialization.
Creating configuration sets is easy and flexible. The important thing to remember is: The plugin configuration set that will be used is the one that is active at the time that the extension system's initialize()
function is called. There are different ways to set it up:
.pconfig by default). The configuration setup can be saved to a XML file at any stage. The debug plugin allows you to create custom sets, for more information see Creating Custom Plugin Configuration Sets.Below is an example plugin configuration set file:
The developer will have a specific way in mind that he or she wants to manage configuration sets their of application. To accomodate different scenarios the way that sets are handled can be customized through the ExtensionSystemCore
class. It is for example possible to define some core plugins and then let the user decide which plugins they want to be active and incative.
The plugin details widget can either show the current active and inactive plugins without allowing the user to change it, or it can give full control to the user. To show the activity of plugins and to allow the users to control the activity of plugins, use the following functions on the extension system:
Below is an example of the plugin configuration widget with the above two activity options enabled and with the "Session Log Plugin" specified to be a core plugin (thus it is greyed out to indicate this and a proper message is displayed when an attempt is made to deactivate it). The image shows the state of the widget just after the user disabled the "Project Management Plugin".
When the user is given control over plugin configuration sets, changing the current set will automatically save the new configuration to the file name of the loaded set. By default this is App_Path/session/default.pconfig
. However if a valid plugin configuration has been loaded using the Qtilities::ExtensionSystem::ExtensionSystemCore::loadPluginConfiguration() function, this loaded configuration file will be updated to reflect the changes the user made. The Qtilities::ExtensionSystem::ExtensionSystemCore::setActivePluginConfigurationFile() function can be specified. It is important to note that the extension system's initialize()
function loads the active plugin configuration file automatically if it exists. Thus is does not make sense to load the configuration before calling initialize()
unless you want to modify it.
Qtilities : Reference Documentation | Back to top |
Copyright © 2009-2013, Jaco Naudé
|