The CTK Plugin Framework can shortly be described as a dynamic component system for C++.
CTK 插件框架可以简要的描述为一个c++动态组件系统。
Contents[hide]
|
The design of the CTK Plugin Framework (see also the Design Document) is heavily inspired by OSGi (a dynamic component system for Java) and enablesa development model where applications are (dynamically) composed of many different (reusable) components. This modelallows to communicate throughservices, which are objects that are specifically shared between components.
The framework's layered model is illustrated in Figure 1, containing:
A more detailed explanation of these concepts can be found below.
A CTK Plugin is, at it's core, a shared library based on the Qt Plugin system.Additionally, symbols in CTK libraries are by default hidden across all platforms. This is the first step towardsmodularity,which is about keeping things local and not shared. The less things you share, the less wrong assumptions can be made. However, withoutsharing there can be no collaboration. CTK Plugins usually only share symbols (classes and functions) to support the CTK services model.
A collaborative model in C++ is usually realized with the use of factory patterns. Different toolkits use different patterns and APIto access such a factory. Very often, influencing the decision about which implementation is used by the factory is non-trivial. Further, theimplementation code can usually not advertise its availability, nor can the user list the possible implementations and pick the most suitableone. Factories are also in general not dynamic, once an instance of an implementation is registered, it can not be withdrawn. Finally, ifmany different factories are in use, there is no centralized overview of the implementations to which your code is bound.
One solution to these issues is the CTK service registry. A plugin can create an object and register it with the CTK service registry underone or moreinterfaces (an interface is a C++ class with usually only pure virtual methods). Other plugins can ask the registry to list all services (objects)that are registered under a specific interface. A plugin may even wait for a specific service to appear and then get a call back.
A plugin can therefore register a service, it can get a service, and it canlisten for a service to appear or disappear.An arbitrary number of plugins can register services under the same interface, and any number of plugins can get the same service, see Figure 2.
If multiple plugins register objects under the same interface, they can be distinguished by theirproperties. Each service registration has a set ofstandard and custom properties. You can use an expressive filter language to select only the services in which you are interested. Properties canalso be used for other roles at the application level.
Since services are dynamic, a plugin can decide to withdraw its service from the registry while other plugins are still using it. Plugins using sucha service must then ensure that they no longer use the service object and drop any pointers to it. This may sound like a significantadditional complexity at first, but using helper classes likectkServiceTracker and aframework like Declarative Services (to be developed) can make this process straight-forward and the gained advantages are quite large.The dynamic nature of services allows to install and uninstall plugins on the fly while other plugins stay functional. It also models real worldproblems closer because most often, such problems are not static. For example in a distributed environment a service could model a connection end-pointand if the connection to the remote machine is gone, the service can be withdrawn. Further, the dynamics solve the initialization problem. Applicationsusing CTK Plugins do not require a specific start ordering in their plugins.
Though the service registry accepts any QObject-based object as a service, the best way to achieve reuse is to register these objects under (standard)interfaces to decouple the implementation from the client code. Hence the CTK Plugin Framework provides a number of standard interfaces which aredesigned closely to the service specifications published in theOSGi Service Platform Release 4 Compendium Specification.These standard services are described in detail in the specification and on this Wiki.
The CTK Plugin Framework can be used as the main container for all your application logic, but it can also be embedded in your existing framework.The management of the framework is standardized by providing a simple API allowing plugins to install, start, stop, and update other plugins,as well as enumerating the plugins and their service usage. This APIcan be used by so-calledmanagement agents to control the Plugin Framework. Management agents can be as diverse as command shells, richgraphical desktop applications, or an AJAX-application.
The CTK Plugin Framework is based on OSGi principles and APIs. As such, it inherits a very mature and thoroughly designed component system thatis used in the Java world to build highly complex applications. It brings those benefits to native (Qt based) C++ applications. The following listis taken from Benefits of Using OSGi and adapted to the CTK context.