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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
/*
* Copyright (C) 2017 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef IGNITION_PLUGIN_LOADER_HH_
#define IGNITION_PLUGIN_LOADER_HH_
#include <memory>
#include <set>
#include <string>
#include <typeinfo>
#include <unordered_set>
#include <ignition/utilities/SuppressWarning.hh>
#include <ignition/plugin/loader/Export.hh>
#include <ignition/plugin/PluginPtr.hh>
namespace ignition
{
namespace plugin
{
/// \brief Class for loading plugins
class IGNITION_PLUGIN_LOADER_VISIBLE Loader
{
/// \brief Constructor
public: Loader();
/// \brief Destructor
public: ~Loader();
/// \brief Makes a printable string with info about plugins
///
/// \returns A pretty string
public: std::string PrettyStr() const;
/// \brief Get demangled names of interfaces that the loader has plugins
/// for.
///
/// \returns Demangled names of the interfaces that are implemented
public: std::unordered_set<std::string> InterfacesImplemented() const;
/// \brief Get plugin names that implement the specified interface
///
/// \return names of plugins that implement the interface.
public: template <typename Interface>
std::unordered_set<std::string> PluginsImplementing() const;
/// \brief Get plugin names that implement the specified interface string.
/// Note that the templated version of this function is recommended
/// instead of this version to avoid confusion about whether a mangled or
/// demangled version of a string is being used. Note that the function
/// InterfacesImplemented() returns demangled versions of the interface
/// names.
///
/// If you want to pass in a mangled version of an interface name, e.g.
/// the result that would be produced by typeid(T).name(), then set
/// `demangled` to false.
///
/// \param[in] _interface
/// Name of an interface
///
/// \param[in] _demangled
/// Specify whether the _interface string is demangled (default, true)
/// or mangled (false).
///
/// \returns Names of plugins that implement the interface
public: std::unordered_set<std::string> PluginsImplementing(
const std::string &_interface,
const bool _demangled = true) const;
/// \brief Get a set of the names of all plugins that are currently known
/// to this Loader.
/// \return A set of all plugin names known to this Loader.
public: std::set<std::string> AllPlugins() const;
/// \brief Get plugin names that correspond to the specified alias string.
///
/// If there is more than one entry in this set, then the alias cannot be
/// used to instantiate any of those plugins.
///
/// If the name of a plugin matches the alias string, then that plugin
/// will be instantiated any time the string is used to instantiate a
/// plugin, no matter how many other plugins use the alias.
///
/// \param[in] _alias
/// The std::string of the alias
///
/// \return A set of plugins that correspond to the desired alias
public: std::set<std::string> PluginsWithAlias(
const std::string &_alias) const;
/// \brief Get the aliases of the plugin with the given name
///
/// \param[in] _pluginName
/// The name of the desired plugin
///
/// \return A set of aliases corresponding to the desired plugin
public: std::set<std::string> AliasesOfPlugin(
const std::string &_pluginName) const;
/// \brief Resolve the plugin name or alias into the name of the plugin
/// that it maps to. If this is a name or alias that does not uniquely map
/// to a known plugin, then the return value will be an empty string.
///
/// \param[in] _nameOrAlias
/// The name or alias of the plugin of interest.
///
/// \return The name of the plugin being referred to, or an empty string
/// if no such plugin is known.
public: std::string LookupPlugin(const std::string &_nameOrAlias) const;
/// \brief Load a library at the given path
///
/// \param[in] _pathToLibrary
/// The path to a library
///
/// \returns The set of plugins that have been loaded from the library
public: std::unordered_set<std::string> LoadLib(
const std::string &_pathToLibrary);
/// \brief Instantiates a plugin for the given plugin name
///
/// \param[in] _pluginNameOrAlias
/// Name or alias of the plugin to instantiate.
///
/// \returns Pointer to instantiated plugin
public: PluginPtr Instantiate(
const std::string &_pluginNameOrAlias) const;
/// \brief Instantiates a plugin of PluginType for the given plugin name.
/// This can be used to create a specialized PluginPtr.
///
/// \tparam PluginPtrType
/// The specialized type of PluginPtrPtr that you
/// want to construct.
///
/// \param[in] _pluginNameOrAlias
/// Name or alias of the plugin that you want to instantiate.
///
/// \returns pointer for the instantiated PluginPtr
public: template <typename PluginPtrType>
PluginPtrType Instantiate(const std::string &_pluginNameOrAlias) const;
/// \brief Instantiates a plugin for the given plugin name, and then
/// returns a reference-counting interface corresponding to InterfaceType.
///
/// If you use this function to retrieve a Factory, you can call
/// Construct(...) on the returned interface, as long as the returned
/// interface is not a nullptr.
///
/// \remark This function is identical to:
///
/// \code
/// loader->Instantiate(_pluginNameOrAlias)
/// ->QueryInterfaceSharedPtr<InterfaceType>();
/// \endcode
///
/// \tparam InterfaceType
/// The type of interface to look for. This function is meant for
/// producing Factories, but any type of Interface can be requested.
///
/// \param[in] _pluginNameOrAlias
/// Name or alias of the plugin that you want to use for production.
///
/// \return reference to an InterfaceType if it can be provided by the
/// requested plugin.
public: template <typename InterfaceType>
std::shared_ptr<InterfaceType> Factory(
const std::string &_pluginNameOrAlias) const;
/// \brief This loader will forget about the library at the given path
/// location. If you want to instantiate a plugin from this library using
/// this loader, you will first need to call LoadLib again.
///
/// After this function has been called, once all plugin instances that
/// are tied to the library have been deleted, the library will
/// automatically be unloaded from the executable. Note that when this
/// Loader leaves scope (or gets deleted), it will have the same
/// effect as calling ForgetLibrary on all of the libraries that it
/// loaded, so there is generally no need to call this function. However,
/// it may be useful if you want to reduce clutter in the Loader
/// instance or let go of library resources that are no longer being used.
///
/// Note that even if you have released all references to a library, it is
/// still up to the discretion of your operating system whether (or when)
/// that library will be unloaded. In some cases, the operating system
/// might not choose to unload it until the program exits completely.
///
/// \param[in] _pathToLibrary
/// Path to the library that you want to forget
///
/// \return True if the library was actively loaded and is now
/// successfully forgotten. If the library was not actively loaded, this
/// returns false.
public: bool ForgetLibrary(const std::string &_pathToLibrary);
/// \brief Forget the library that provides the plugin with the given
/// name. Note that this will also forget all other plugin types which
/// are provided by that library.
///
/// \param[in] _pluginNameOrAlias
/// Name or alias of the plugin whose library you want to forget.
///
/// \sa bool ForgetLibrary(const std::string &_pathToLibrary)
public: bool ForgetLibraryOfPlugin(const std::string &_pluginNameOrAlias);
/// \brief Get a pointer to the Info corresponding to _pluginName.
///
/// \param[in] _resolvedName
/// The resolved name, i.e. the demangled class symbol name as returned
/// by LookupPlugin(~), of the plugin that you want to instantiate.
///
/// \return Pointer to the corresponding Info, or nullptr if there
/// is no info for the requested _pluginName.
private: ConstInfoPtr PrivateGetInfo(
const std::string &_resolvedName) const;
/// \brief Get a std::shared_ptr that manages the lifecycle of the shared
/// library handle which provides the specified plugin.
///
/// \param[in] _resolvedName
/// The resolved name, i.e. the demangled class symbol name as returned
/// by LookupPlugin(~), of the plugin that you want to instantiate.
///
/// \return Reference-counting pointer to a library handle, or else a
/// nullptr if the plugin is not available.
private: std::shared_ptr<void> PrivateGetPluginDlHandlePtr(
const std::string &_resolvedName) const;
class Implementation;
IGN_UTILS_WARN_IGNORE__DLL_INTERFACE_MISSING
/// \brief PIMPL pointer to class implementation
private: std::unique_ptr<Implementation> dataPtr;
IGN_UTILS_WARN_RESUME__DLL_INTERFACE_MISSING
};
}
}
#include <ignition/plugin/detail/Loader.hh>
#endif
|