Robowflex  v0.1
Making MoveIt Easy
plugin.h
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #ifndef ROBOWFLEX_IO_PLUGIN_
4 #define ROBOWFLEX_IO_PLUGIN_
5 
6 #include <mutex>
7 #include <memory>
8 #include <typeinfo>
9 
10 #include <ros/package.h>
11 
12 #include <robowflex_library/log.h>
14 
15 #include <pluginlib/class_loader.hpp>
16 
17 namespace robowflex
18 {
19  namespace IO
20  {
21  /** \brief A singleton class for dynamic loading classes through pluginlib.
22  */
24  {
25  public:
26  // non-copyable
27  PluginManager(PluginManager const &) = delete;
28  void operator=(PluginManager const &) = delete;
29 
30  /** \brief Get the singleton instance of PluginManager
31  * \return The singleton PluginManager.
32  */
34  {
35  static PluginManager instance;
36  return instance;
37  }
38 
39  /** \brief Load a plugin named \a plugin of type T using the singleton instance.
40  * \param[in] package ROS package that exports plugin's base class \a T.
41  * \param[in] plugin Name of the plugin to load.
42  * \tparam T The type of the plugin to load.
43  * \return A shared pointer to the loaded plugin on success, nullptr on failure.
44  */
45  template <typename T>
46  static std::shared_ptr<T> load(const std::string &package, const std::string &plugin)
47  {
48  return getInstance().loadPlugin<T>(package, plugin);
49  }
50 
51  /** \brief Load a plugin named \a plugin of type T.
52  * \param[in] package ROS package that exports plugin's base class \a T.
53  * \param[in] plugin Name of the plugin to load.
54  * \tparam T The type of the plugin to load.
55  * \return A shared pointer to the loaded plugin on success, nullptr on failure.
56  */
57  template <typename T>
58  std::shared_ptr<T> loadPlugin(const std::string &package, const std::string &plugin)
59  {
60  if (ros::package::getPath(package).empty())
61  {
62  RBX_ERROR("Package `%s` does not exist.", package);
63  return nullptr;
64  }
65 
66  auto loader = getLoader<T>(package);
67 
68  try
69  {
70  std::shared_ptr<T> loaded(loader->createUnmanagedInstance(plugin));
71  return loaded;
72  }
73  catch (pluginlib::LibraryLoadException &e)
74  {
75  RBX_ERROR("Failed to library: %s", e.what());
76  return nullptr;
77  }
78  }
79 
80  private:
81  /** \brief A typed class loader.
82  * \tparam T The type of class to load via the plugin loader.
83  */
84  template <typename T>
85  using Loader = pluginlib::ClassLoader<T>;
86 
87  /** \brief A shared pointer to a typed class loader.
88  * \tparam T The type of class to load via the plugin loader.
89  */
90  template <typename T>
92 
93  /** \brief The base class of the class loader.
94  */
95  using BaseLoader = pluginlib::ClassLoaderBase;
96 
97  /** \brief A shared pointer to the base class of the class loader.
98  */
100 
101  /** \brief Constructor
102  */
104  {
105  }
106 
107  /** \brief Gets the plugin loader for a plugin type \a T.
108  * Grabs the loader from cached loaders if available, otherwise creates the plugin loader and
109  * caches it.
110  * \param[in] package ROS package that exports class \a T.
111  * \tparam T The type of plugin loader to get.
112  * \return A plugin loader that loads plugins of type \a T.
113  */
114  template <typename T>
116  {
118 
119  // Need to possibly demangle type name...
120  const std::string &type = ROBOWFLEX_DEMANGLE(typeid(T).name());
121  auto key = std::make_pair(package, type);
122 
123  LoaderPtr<T> loader;
124 
125  auto cached = loaders_.find(key);
126  if (cached != loaders_.end())
127  loader = std::dynamic_pointer_cast<Loader<T>>(cached->second);
128  else
129  {
130  RBX_INFO("Creating Class Loader for type `%s` from package `%s`!", type, package);
131 
132  loader.reset(new pluginlib::ClassLoader<T>(package, type));
133  loaders_[key] = std::static_pointer_cast<BaseLoader>(loader);
134  }
135 
136  return loader;
137  }
138 
139  std::mutex mutex_; ///< Class loading mutex
141  };
142  } // namespace IO
143 } // namespace robowflex
144 
145 #endif
A singleton class for dynamic loading classes through pluginlib.
Definition: plugin.h:24
PluginManager(PluginManager const &)=delete
static std::shared_ptr< T > load(const std::string &package, const std::string &plugin)
Load a plugin named plugin of type T using the singleton instance.
Definition: plugin.h:46
std::map< std::pair< std::string, std::string >, BaseLoaderPtr > loaders_
Cached loaders.
Definition: plugin.h:140
PluginManager()
Constructor.
Definition: plugin.h:103
pluginlib::ClassLoader< T > Loader
A typed class loader.
Definition: plugin.h:85
std::shared_ptr< T > loadPlugin(const std::string &package, const std::string &plugin)
Load a plugin named plugin of type T.
Definition: plugin.h:58
std::mutex mutex_
Class loading mutex.
Definition: plugin.h:139
LoaderPtr< T > getLoader(const std::string &package)
Gets the plugin loader for a plugin type T. Grabs the loader from cached loaders if available,...
Definition: plugin.h:115
static PluginManager & getInstance()
Get the singleton instance of PluginManager.
Definition: plugin.h:33
void operator=(PluginManager const &)=delete
pluginlib::ClassLoaderBase BaseLoader
The base class of the class loader.
Definition: plugin.h:95
#define RBX_ERROR(fmt,...)
Output a error logging message.
Definition: log.h:102
#define RBX_INFO(fmt,...)
Output a info logging message.
Definition: log.h:118
#define ROBOWFLEX_DEMANGLE(x)
Definition: macros.h:114
T make_pair(T... args)
Main namespace. Contains all library classes and functions.
Definition: scene.cpp:25
T reset(T... args)