|
Defines an interface for registering plugins. More...
#include <registry.h>
Public Types | |
typedef PlugRegistry | This |
typedef std::vector< TfType > | TypeVector |
Public Member Functions | |
PLUG_API PlugPluginPtrVector | RegisterPlugins (const std::string &pathToPlugInfo) |
Registers all plug-ins discovered at pathToPlugInfo. | |
PLUG_API PlugPluginPtrVector | RegisterPlugins (const std::vector< std::string > &pathsToPlugInfo) |
Registers all plug-ins discovered in any of pathsToPlugInfo. | |
PLUG_API PlugPluginPtr | GetPluginForType (TfType t) const |
Returns the plug-in for the given type, or a null pointer if there is no registered plug-in. | |
PLUG_API PlugPluginPtrVector | GetAllPlugins () const |
Returns all registered plug-ins. | |
PLUG_API PlugPluginPtr | GetPluginWithName (const std::string &name) const |
Returns a plugin with the specified library name. | |
PLUG_API std::string | GetStringFromPluginMetaData (TfType type, const std::string &key) const |
Looks for a string associated with type and key and returns it, or an empty string if type or key are not found. | |
PLUG_API JsValue | GetDataFromPluginMetaData (TfType type, const std::string &key) const |
Looks for a JsValue associated with type and key and returns it, or a null JsValue if type or key are not found. | |
Public Member Functions inherited from TfWeakBase | |
TfWeakBase (const TfWeakBase &) | |
const TfWeakBase & | __GetTfWeakBase__ () const |
const TfWeakBase & | operator= (const TfWeakBase &) |
void | EnableNotification2 () const |
TF_API void const * | GetUniqueIdentifier () const |
Static Public Member Functions | |
static PLUG_API PlugRegistry & | GetInstance () |
Returns the singleton PlugRegistry instance. | |
static PLUG_API TfType | FindTypeByName (std::string const &typeName) |
Retrieve the TfType corresponding to the given name . | |
static PLUG_API TfType | FindDerivedTypeByName (TfType base, std::string const &typeName) |
Retrieve the TfType that derives from base and has the given alias or type name typeName . | |
template<class Base > | |
static TfType | FindDerivedTypeByName (std::string const &typeName) |
Retrieve the TfType that derives from Base and has the given alias or type name typeName . | |
static PLUG_API std::vector< TfType > | GetDirectlyDerivedTypes (TfType base) |
Return a vector of types derived directly from base. | |
static PLUG_API void | GetAllDerivedTypes (TfType base, std::set< TfType > *result) |
Return the set of all types derived (directly or indirectly) from base. | |
template<class Base > | |
static void | GetAllDerivedTypes (std::set< TfType > *result) |
Return the set of all types derived (directly or indirectly) from Base. | |
Friends | |
class | TfSingleton< PlugRegistry > |
class | PlugPlugin |
Additional Inherited Members | |
Protected Member Functions inherited from TfWeakBase | |
TfRefPtr< Tf_Remnant > | _Register () const |
template<class T > | |
TfRefPtr< Tf_Remnant > | _Register (T *tempRmnt) const |
bool | _HasRemnant () const |
Defines an interface for registering plugins.
PlugRegistry maintains a registry of plug-ins known to the system and provides an interface for base classes to load any plug-ins required to instantiate a subclass of a given type.
In order to use this facility you will generally provide a library which defines the API for a plug-in base class. This API will be sufficient for the application or framework to make use of custom subclasses that will be written by plug-in developers.
For example, if you have an image processing application, you might want to support plug-ins that implement image filters. You can define an abstract base class for image filters that declares the API your application will require image filters to implement; perhaps something simple like C++ Code Example 1 (Doxygen only).
People writing custom filters would write a subclass of ImageFilter that overrides the two methods, implementing their own special filtering behavior.
In order for ImageFilter to be able to load plug-ins that implement these custom subclasses, it must be registered with the TfType system.
The ImageFilter base class, as was mentioned earlier, should be made available in a library that the application links with. This is done so that plug-ins that want to provide ImageFilters can also link with the library allowing them to subclass ImageFilter.
A plug-in developer can now write plug-ins with ImageFilter subclasses. Plug-ins can be implemented either as native dynamic libraries (either regular dynamic libraries or framework bundles) or as Python modules.
Plug-ins must be registered with the registry. All plugins are registered via RegisterPlugins(). Plug-in Python modules must be directly importable (in other words they must be able to be found in Python's module path.) Plugins are registered by providing a path or paths to JSON files that describe the location, structure and contents of the plugin. The standard name for these files in plugInfo.json.
Typically, the application that hosts plug-ins will locate and register plug-ins at startup.
The plug-in facility is lazy. It does not dynamically load code from plug-in bundles until that code is required.
A plugInfo.json file has the following structure:
As a special case, if a plugInfo.json contains an object that doesn't have either the "Includes" or "Plugins" keys then it's as if the object was in a "Plugins" array.
Once the plug-ins are registered, the plug-in facility must also be able to tell what they contain. Specifically, it must be able to find out what subclasses of what plug-in base classes each plug-in contains. Plug-ins must advertise this information through their plugInfo.json file in the "Info" key. In the "Info" object there should be a key "Types" holding an object.
This "Types" object's keys are names of subclasses and its values are yet more objects (the subclass meta-data objects). The meta-data objects can contain arbitrary key-value pairs. The plug-in mechanism will look for a meta-data key called "displayName" whose value should be the display name of the subclass. The plug-in mechanism will look for a meta-data key called "bases" whose value should be an array of base class type names.
For example, a bundle that contains a subclass of ImageFilter might have a plugInfo.json that looks like the following example.
What this says is that the plug-in contains a type called MyCustomCoolFilter which has a base class ImageFilter and that this subclass should be called "Add Coolness to Image" in user-visible contexts.
In addition to the "displayName" meta-data key which is actually known to the plug-in facility, you may put whatever other information you want into a class' meta-data dictionary. If your plug-in base class wants to define custom keys that it requires all subclasses to provide, you can do that. Or, if a plug-in writer wants to define their own keys that their code will look for at runtime, that is OK as well.
Most code with uses types defined in plug-ins doesn't deal with the Plug API directly. Instead, the TfType interface is used to lookup types and to manufacture instances. The TfType interface will take care to load any required plugins.
To wrap up our example, the application that wants to actually use ImageFilter plug-ins would probably do a couple of things. First, it would get a list of available ImageFilters to present to the user. This could be accomplished as shown in Python Code Example 2 (Doxygen only).
Then, when the user picks a filter from the list, it would manufacture and instance of the filter as shown in Python Code Example 3 (Doxygen only).
As was mentioned earlier, this plug-in facility tries to be as lazy as possible about loading the code associated with plug-ins. To that end, loading of a plugin will be deferred until an instance of a type is manufactured which requires the plugin.
It is possible for a bundle to implement multiple subclasses for a plug-in base class if desired. If you want to package half a dozen ImageFilter subclasses in one bundle, that will work fine. All must be declared in the plugInfo.json.
It is possible for there to be multiple classes in your application or framework that are plug-in base classes. Plug-ins that implement subclasses of any of these base classes can all coexist. And, it is possible to have subclasses of multiple plug-in base classes in the same bundle.
When putting multiple subclasses (of the same or different base classes) in a bundle, keep in mind that dynamic loading happens for the whole bundle the first time any subclass is needed, the whole bundle will be loaded. But this is generally not a big concern.
For example, say the example application also has a plug-in base class "ImageCodec" that allows people to add support for reading and writing other image formats. Imagine that you want to supply a plug-in that has two codecs and a filter all in a single plug-in. Your plugInfo.json "Info" object might look something like this example.
If you write a plug-in that has dependencies on another plug-in that you cannot (or do not want to) link against statically, you can declare the dependencies in your plug-in's plugInfo.json . A plug-in declares dependencies on other classes with a PluginDependencies key whose value is a dictionary. The keys of the dictionary are plug-in base class names and the values are arrays of subclass names.
The following example contains an example of a plug-in that depends on two classes from the plug-in in the previous example.
The ImageFilter provided by the plug-in in this example depends on the other ImageFilter MyCoolImageFilter and the ImageCodec MyTIFFCodec. Before loading this plug-in, the plug-in facility will ensure that those two classes are present, loading the plug-in that contains them if needed.
Definition at line 319 of file registry.h.
typedef PlugRegistry This |
Definition at line 323 of file registry.h.
typedef std::vector<TfType> TypeVector |
Definition at line 324 of file registry.h.
|
inlinestatic |
Retrieve the TfType
that derives from Base
and has the given alias or type name typeName
.
See the documentation for TfType::FindDerivedByName
for more information. Use this function if you expect that the derived type may be provided by a plugin. Calling this function will incur plugin discovery (but not loading) if plugin discovery has not yet occurred.
Note that additional plugins may be registered during program runtime.
Definition at line 376 of file registry.h.
Retrieve the TfType
that derives from base
and has the given alias or type name typeName
.
See the documentation for TfType::FindDerivedByName
for more information. Use this function if you expect that the derived type may be provided by a plugin. Calling this function will incur plugin discovery (but not loading) if plugin discovery has not yet occurred.
Note that additional plugins may be registered during program runtime.
|
static |
Retrieve the TfType
corresponding to the given name
.
See the documentation for TfType::FindByName
for more information. Use this function if you expect that name
may name a type provided by a plugin. Calling this function will incur plugin discovery (but not loading) if plugin discovery has not yet occurred.
Note that additional plugins may be registered during program runtime.
|
inlinestatic |
Return the set of all types derived (directly or indirectly) from Base.
Use this function if you expect that plugins may provide types derived from base. Otherwise, use TfType::GetAllDerivedTypes.
Note that additional plugins may be registered during program runtime.
Definition at line 406 of file registry.h.
Return the set of all types derived (directly or indirectly) from base.
Use this function if you expect that plugins may provide types derived from base. Otherwise, use TfType::GetAllDerivedTypes.
Note that additional plugins may be registered during program runtime.
PLUG_API PlugPluginPtrVector GetAllPlugins | ( | ) | const |
Returns all registered plug-ins.
Note that additional plugins may be registered during program runtime.
Return a vector of types derived directly from base.
Use this function if you expect that plugins may provide types derived from base. Otherwise, use TfType::GetDirectlyDerivedTypes.
|
static |
Returns the singleton PlugRegistry
instance.
PLUG_API PlugPluginPtr GetPluginForType | ( | TfType | t | ) | const |
Returns the plug-in for the given type, or a null pointer if there is no registered plug-in.
PLUG_API PlugPluginPtr GetPluginWithName | ( | const std::string & | name | ) | const |
Returns a plugin with the specified library name.
Note that additional plugins may be registered during program runtime.
PLUG_API std::string GetStringFromPluginMetaData | ( | TfType | type, |
const std::string & | key | ||
) | const |
Looks for a string associated with type and key and returns it, or an empty string if type or key are not found.
PLUG_API PlugPluginPtrVector RegisterPlugins | ( | const std::string & | pathToPlugInfo | ) |
Registers all plug-ins discovered at pathToPlugInfo.
Sends PlugNotice::DidRegisterPlugins with any newly registered plugins.
PLUG_API PlugPluginPtrVector RegisterPlugins | ( | const std::vector< std::string > & | pathsToPlugInfo | ) |
Registers all plug-ins discovered in any of pathsToPlugInfo.
Sends PlugNotice::DidRegisterPlugins with any newly registered plugins.
|
friend |
Definition at line 459 of file registry.h.
|
friend |
Definition at line 456 of file registry.h.