Tulip  5.2.1
Large graphs analysis and drawing
PluginLister.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef TULIP_PLUGINLISTER_H
21 #define TULIP_PLUGINLISTER_H
22 
23 #include <list>
24 #include <string>
25 #include <map>
26 
27 #include <tulip/Plugin.h>
28 #include <tulip/PluginLoader.h>
29 #include <tulip/Observable.h>
30 
31 namespace tlp {
32 class PluginContext;
33 
34 ///@cond DOXYGEN_HIDDEN
35 /**
36  * @ingroup Plugins
37  * @brief The base class for plugin factories.
38  *
39  * A plugin factory handles the creation process of a tlp::Plugin subclass. This class should never
40  *be used directly. See the PLUGIN macro for additional information.
41  * @see PLUGIN
42  **/
43 class FactoryInterface {
44 public:
45  virtual tlp::Plugin *createPluginObject(tlp::PluginContext *context) = 0;
46 };
47 ///@endcond
48 
49 /**
50  * @ingroup Plugins
51  *
52  * @brief The PluginLister class is a singleton used to list plugins currently loaded into Tulip and
53  * retrieve information about them.
54  *
55  * This class holds various methods to check information about plugins currently loaded into Tulip.
56  * You can use it to list plugins, get dependencies information or create an instance of a plugin.
57  *
58  * @note Since a plugin name is unique, Plugins are mainly identified by their name
59  * (tlp::Plugin::name()) when interfaced with the plugin lister.
60  *
61  * @see tlp::Plugin
62  * @see tlp::PluginLoader
63  * @see tlp::PluginLibraryLoader
64  */
65 class TLP_SCOPE PluginLister : public Observable {
66 private:
67  struct PluginDescription {
68  FactoryInterface *factory;
69  std::string library;
70  Plugin *info;
71 
72  PluginDescription() : factory(nullptr), info(nullptr) {}
73  ~PluginDescription() {
74  delete info;
75  }
76  };
77 
78 public:
79  static PluginLoader *currentLoader;
80 
81  /**
82  * @brief Checks if all registered plug-ins have their dependencies met.
83  *
84  * @param loader If there are errors, the loader is informed about them so they can be displayed.
85  * @return void
86  **/
87  static void checkLoadedPluginsDependencies(tlp::PluginLoader *loader);
88 
89  /**
90  * @brief Gets the static instance of this class. If not already done, creates it beforehand.
91  *
92  * @return PluginLister< ObjectType, Context >* The only instance of this object that exists in
93  *the whole program.
94  **/
95  static tlp::PluginLister *instance();
96 
97  /**
98  * @brief Constructs a plug-in.
99  *
100  * @param name The name of the plug-in to instantiate.
101  * @param p The context to give to the plug-in.
102  * @return ObjectType* The newly constructed plug-in.
103  **/
104  static tlp::Plugin *getPluginObject(const std::string &name, tlp::PluginContext *context);
105 
106  /**
107  * @brief Checks if a plugin of a given type is loaded
108  * This method checks the plugin "pluginName" is currently loaded into Tulip and if it's of type
109  * PluginType.
110  * @param PluginType the class type of the plugin
111  * @param pluginName the name of the plugin
112  * @return true if a matching plugin is currently loaded into Tulip.
113  */
114  template <typename PluginType>
115  bool pluginExists(const std::string &pluginName) {
116  auto it = _plugins.find(pluginName);
117  return (it != _plugins.end() && (dynamic_cast<const PluginType *>(it->second.info) != nullptr));
118  }
119 
120  /**
121  * @brief Similar to tlp::PluginLister::getPluginObject() but returns a typed instance
122  *
123  * This method instantiate a plugin from its name and returns it casted into the given type.
124  *
125  * @param name The plugin's name
126  * @param context The context to give to the plugin
127  *
128  * @return The plugin instance. If there is no such plugin or if the plugin does not match the
129  * required type, this method returns nullptr
130  */
131  template <typename PluginType>
132  PluginType *getPluginObject(const std::string &name, tlp::PluginContext *context) {
133  auto it = _plugins.find(name);
134  if (it != _plugins.end() && (dynamic_cast<const PluginType *>(it->second.info) != nullptr)) {
135  std::string pluginName = it->second.info->name();
136  if (name != pluginName)
137  tlp::warning() << "Warning: '" << name << "' is a deprecated plugin name. Use '"
138  << pluginName << "' instead." << std::endl;
139 
140  return static_cast<PluginType *>(it->second.factory->createPluginObject(context));
141  }
142  return nullptr;
143  }
144 
145  /**
146  * @brief Gets the list of plugins of a given type (template parameter).
147  * @return A std::list<std::string> containing plugin names.
148  **/
149  static std::list<std::string> availablePlugins();
150 
151  template <typename PluginType>
152  std::list<std::string> availablePlugins() {
153  std::list<std::string> keys;
154 
155  for (auto it = _plugins.begin(); it != _plugins.end(); ++it) {
156  PluginType *plugin = dynamic_cast<PluginType *>(it->second.info);
157 
158  if (plugin != nullptr &&
159  // deprecated names are not listed
160  it->first == it->second.info->name()) {
161  keys.push_back(it->first);
162  }
163  }
164 
165  return keys;
166  }
167 
168  /**
169  * @brief Gets more detailed information about one specific plug-in.
170  *
171  * @param name The name of the plugin to retrieve information for.
172  * @return :const Plugin& The information on the plugin.
173  **/
174  static const Plugin &pluginInformation(const std::string &name);
175 
176  /**
177  * @brief Checks if a given name is registered in this factory.
178  *
179  * @param pluginName The name of the plug-in to look for.
180  * @return bool Whether there is a plug-in with the given name registered in this factory.
181  **/
182  static bool pluginExists(const std::string &pluginName);
183 
184  /**
185  * @brief Gets the list of parameters for the given plug-in.
186  *
187  * @param name The name of the plug-in to retrieve the parameters of.
188  * @return :ParameterDescriptionList The parameters of the plug-in.
189  **/
190  static const ParameterDescriptionList &getPluginParameters(const std::string &name);
191 
192  /**
193  * @brief Gets the dependencies of a plug-in.
194  *
195  * @param name The name of the plug-in to retrieve the dependencies of.
196  * @return :list< tlp::Dependency, std::allocator< tlp::Dependency > > The list of dependencies of
197  *the plug-in.
198  **/
199  static const std::list<tlp::Dependency> &getPluginDependencies(const std::string &name);
200 
201  /**
202  * @brief Gets the library from which a plug-in has been loaded.
203  *
204  * @param name The name of the plug-in to retrieve the library of.
205  * @return std::string The library from which the plug-in was loaded.
206  **/
207  static std::string getPluginLibrary(const std::string &name);
208 
209  /**
210  * @brief Removes a plug-in from this factory.
211  * This is usefull when a plug-in has unmet dependencies, or appears more than once.
212  *
213  * @param name The name of the plug-in to remove.
214  * @return void
215  **/
216  static void removePlugin(const std::string &name);
217 
218  /**
219  * @brief Registers a plugin into Tulip
220  *
221  * @warning This method should only be called by tlp::FactoryInterface subclasses
222  * @see PLUGIN
223  */
224  static void registerPlugin(FactoryInterface *objectFactory);
225 
226  ///@cond DOXYGEN_HIDDEN
227 protected:
228  void sendPluginAddedEvent(const std::string &pluginName);
229  void sendPluginRemovedEvent(const std::string &pluginName);
230 
231  static PluginLister *_instance;
232 
233  /**
234  * @brief Stores the factory, dependencies, and parameters of all the plugins that register into
235  *this factory.
236  **/
237  std::map<std::string, PluginDescription> _plugins;
238 
239  /**
240  * @brief Gets the release number of the given plug-in.
241  *
242  * @param name The name of the plug-in to retrieve the version number of.
243  * @return :string The version number, ussually formatted as X[.Y], where X is the major, and Y
244  *the minor.
245  **/
246  static std::string getPluginRelease(const std::string &name);
247  ///@endcond
248 };
249 
250 ///@cond DOXYGEN_HIDDEN
251 class TLP_SCOPE PluginEvent : public Event {
252 public:
253  enum PluginEventType { TLP_ADD_PLUGIN = 0, TLP_REMOVE_PLUGIN = 1 };
254 
255  // constructor for node/edge events
256  PluginEvent(PluginEventType pluginEvtType, const std::string &pluginName)
257  : Event(*(tlp::PluginLister::instance()), Event::TLP_MODIFICATION), evtType(pluginEvtType),
258  pluginName(pluginName) {}
259 
260  PluginEventType getType() const {
261  return evtType;
262  }
263 
264  std::string getPluginName() const {
265  return pluginName;
266  }
267 
268 protected:
269  PluginEventType evtType;
270  std::string pluginName;
271 };
272 ///@endcond
273 } // namespace tlp
274 
275 #endif // TULIP_PLUGINLISTER_H
The PluginLister class is a singleton used to list plugins currently loaded into Tulip and retrieve i...
Definition: PluginLister.h:65
Event is the base class for all events used in the Observation mechanism.
Definition: Observable.h:51
Contains runtime parameters for a plugin.
Definition: PluginContext.h:42
Top-level interface for plug-ins.
Definition: Plugin.h:85
PluginType * getPluginObject(const std::string &name, tlp::PluginContext *context)
Similar to tlp::PluginLister::getPluginObject() but returns a typed instance.
Definition: PluginLister.h:132
The Observable class is the base of Tulip&#39;s observation system.
Definition: Observable.h:141
This class describes parameters taken by a plugin.
bool pluginExists(const std::string &pluginName)
Checks if a plugin of a given type is loaded This method checks the plugin "pluginName" is currently ...
Definition: PluginLister.h:115
A callback class when loading plugins into Tulip.
Definition: PluginLoader.h:41
static tlp::PluginLister * instance()
Gets the static instance of this class. If not already done, creates it beforehand.