Ignition Plugin

API Reference

1.1.0
ignition::plugin Namespace Reference

Namespaces

 v1
 

Classes

class  EnablePluginFromThis
 EnablePluginFromThis is an optional base class which can be inherited by Plugin classes. When a Plugin class inherits it and that Plugin class is instantiated using the Loader class, its instance will be able to access the PluginPtr that manages its lifecycle. This interface will also be available by calling instance->QueryInterface<EnablePluginFromThis>() More...
 
class  Factory
 The Factory class defines a plugin factory that can be used by the Loader class to produce products that implement an interface. More...
 
class  Loader
 Class for loading plugins. More...
 
class  Plugin
 
class  ProductDeleter
 This class provides a unary operator for safely deleting pointers to plugin factory products with the type Interface. If it gets passed an Interface pointer that is not pointing to a factory plugin product, then this just performs a normal delete. More...
 
class  SpecializedPlugin
 
class  SpecializedPlugin< SpecInterface >
 This class allows Plugin instances to have high-speed access to interfaces that can be anticipated at compile time. The plugin does not have to actually offer the specialized interface in order to get this performance improvement. This template is variadic, so it can support arbitrarily many interfaces. More...
 
class  TemplatePluginPtr
 This class manages the lifecycle of a plugin instance. It can receive a plugin instance from the Loader class or by copy-construction or assignment from another PluginPtr instance. More...
 
class  WeakPluginPtr
 WeakPluginPtr is a non-reference-holding smart pointer for a Plugin. WeakPluginPtr is analogous to std::weak_ptr where PluginPtr is analogous to std::shared_ptr. More...
 

Typedefs

template<typename To , typename From >
using ConstCompatible = detail::ConstCompatible< To, From >
 Contains a static constexpr field named value which will be true if the type From has a const-quality less than or equal to the type To. More...
 
using ConstInfoPtr = std::shared_ptr< const Info >
 
using ConstPluginPtr = TemplatePluginPtr< const Plugin >
 This produces a PluginPtr whose Plugin wrapper only grants access to const-qualified interfaces of the plugin instance. More...
 
template<typename... SpecInterfaces>
using ConstSpecializedPluginPtr = TemplatePluginPtr< const SpecializedPlugin< SpecInterfaces... > >
 This alias creates a specialized PluginPtr whose interfaces are all const-qualified. More...
 
using InfoMap = std::unordered_map< std::string, Info >
 
using PluginPtr = TemplatePluginPtr< Plugin >
 Typical usage for TemplatePluginPtr is to just hold a generic Plugin type. More...
 
template<typename Interface >
using ProductPtr = std::unique_ptr< Interface, ProductDeleter< Interface > >
 ProductPtr is a derivative of std::unique_ptr that can safely manage the products that come out of a plugin factory. It is strongly recommended that factory products use a ProductPtr to manage the lifecycle of a factory product. More...
 
template<typename... SpecInterfaces>
using SpecializedPluginPtr = TemplatePluginPtr< SpecializedPlugin< SpecInterfaces... > >
 This alias allows PluginPtr instances to have high-speed access to interfaces that can be anticipated at compile time. The plugin does not have to actually offer the specialized interface in order to get this performance improvement. This template is variadic, so it can support arbitrarily many interfaces. More...
 

Functions

void CleanupLostProducts (const std::chrono::nanoseconds &_safetyWait=std::chrono::nanoseconds(5))
 Call this function to cleanup the Factories of any Products which were not managed by a ProductPtr or deleted by a ProductDeleter (in other words, the Product was released from its ProductPtr and then its lifecycle was managed by a framework that does not know it has special deletion requirements). More...
 
std::string DemangleSymbol (const std::string &_symbol)
 Demangle the ABI typeinfo name of a symbol into a human-readable version. More...
 
std::size_t LostProductCount ()
 Get the number of lost products that have currently accumulated since the last time CleanupLostProducts() was called (or since the program began, if CleanupLostProducts() has not been called yet). More...
 

Variables

const int INFO_API_VERSION = 1
 sentinel value to check if a plugin was built with the same version of the Info struct More...
 

Typedef Documentation

◆ ConstCompatible

using ConstCompatible = detail::ConstCompatible<To, From>

Contains a static constexpr field named value which will be true if the type From has a const-quality less than or equal to the type To.

The following expressions will return true:

ConstCompatible<T, T>::value
ConstCompatible<const T, T>::value

The following expression will return false:

ConstCompatible<T, const T>::value

◆ ConstInfoPtr

using ConstInfoPtr = std::shared_ptr<const Info>

◆ ConstPluginPtr

This produces a PluginPtr whose Plugin wrapper only grants access to const-qualified interfaces of the plugin instance.

◆ ConstSpecializedPluginPtr

using ConstSpecializedPluginPtr = TemplatePluginPtr< const SpecializedPlugin<SpecInterfaces...> >

This alias creates a specialized PluginPtr whose interfaces are all const-qualified.

◆ InfoMap

This typedef is used simultaneously by detail/Register.hh and Loader.cc, so we store it in a location that is visible to both of them.

◆ PluginPtr

Typical usage for TemplatePluginPtr is to just hold a generic Plugin type.

◆ ProductPtr

using ProductPtr = std::unique_ptr<Interface, ProductDeleter<Interface> >

ProductPtr is a derivative of std::unique_ptr that can safely manage the products that come out of a plugin factory. It is strongly recommended that factory products use a ProductPtr to manage the lifecycle of a factory product.

If you MUST release a factory product pointer, then it should at least be passed to a ProductDeleter to be deleted at the end of its lifecycle. If it is not possible to delete the product with a ProductDeleter, then you will need to periodically call CleanupLostProducts() or else you will experience memory leaks, and your factory plugin libraries will never get unloaded.

◆ SpecializedPluginPtr

This alias allows PluginPtr instances to have high-speed access to interfaces that can be anticipated at compile time. The plugin does not have to actually offer the specialized interface in order to get this performance improvement. This template is variadic, so it can support arbitrarily many interfaces.

Usage example:

Suppose you want to instantiate a plugin that might (or might not) have some combination of four interfaces which are known at compile time: MyInterface1, FooInterface, MyInterface2, and BarInterface. You can use SpecializedPluginPtr as shown here:

using MySpecialPluginPtr = SpecializedPluginPtr<
MyInterface1, FooInterface, MyInterface2, BarInterface>;
MySpecialPluginPtr plugin = loader->Instantiate(pluginName);

Then, calling the function

plugin->QueryInterface<FooInterface>();

will have extremely high speed associated with it. It will provide direct access to the the FooInterface* of plugin. If plugin does not actually offer FooInterface, then it will return a nullptr, still at extremely high speed.

This same rule also applies to MyInterface1, MyInterface2, and BarInterface, because those interfaces were also provided to SpecializedPluginPtr<...> at compile time.

Function Documentation

◆ CleanupLostProducts()

void ignition::plugin::CleanupLostProducts ( const std::chrono::nanoseconds _safetyWait = std::chrono::nanoseconds(5))

Call this function to cleanup the Factories of any Products which were not managed by a ProductPtr or deleted by a ProductDeleter (in other words, the Product was released from its ProductPtr and then its lifecycle was managed by a framework that does not know it has special deletion requirements).

If you never call the .release() function on a ProductPtr, then you will never need to call this function.

Warning
Note that this function should be called ONLY while there are no Products that are actively destructing, or else there is a miniscule probability of causing a segmentation fault. This is never an issue in a single-threaded application.
If you have a multi-threaded application where you have absolutely no control over the lifecycle of the products, and you cannot reliably predict a safe window in which you know that no products are being actively deleted, then you can specify a short safety wait to the cleanup call. If any products were being deleted while this function is called, this wait can give them time to fully exit their destructors before we unload their libraries.
Note
For some applications, it might not be important if there are tiny memory leaks or if plugin libraries remain loaded until the application exits. For those applications, it is okay to not bother calling this function at all.
Parameters
[in]_safetyWaitFor multi-threaded applications, this short waiting window gives time for products that are currently being deleted to exit their destructors before we unload their libraries. If you can reliably predict a window of time in which no products are actively being destructed (or if you have a single-threaded application), then it is okay to set this waiting time to 0. Note that any threads which are about to destruct a product will be blocked until this wait is over.

◆ DemangleSymbol()

std::string ignition::plugin::DemangleSymbol ( const std::string _symbol)

Demangle the ABI typeinfo name of a symbol into a human-readable version.

Parameters
[in]_symbolPass in the result of typeid(T).name()
Returns
The demangled (human-readable) version of the symbol name

◆ LostProductCount()

std::size_t ignition::plugin::LostProductCount ( )

Get the number of lost products that have currently accumulated since the last time CleanupLostProducts() was called (or since the program began, if CleanupLostProducts() has not been called yet).

Variable Documentation

◆ INFO_API_VERSION

const int INFO_API_VERSION = 1

sentinel value to check if a plugin was built with the same version of the Info struct

This must be incremented when the Info struct changes