10 #ifndef __PION_PLUGINMANAGER_HEADER__
11 #define __PION_PLUGINMANAGER_HEADER__
15 #include <boost/cstdint.hpp>
16 #include <boost/function.hpp>
17 #include <boost/function/function1.hpp>
18 #include <boost/thread/mutex.hpp>
19 #include <pion/PionConfig.hpp>
20 #include <pion/PionException.hpp>
21 #include <pion/PionPlugin.hpp>
29 template <
typename PLUGIN_TYPE>
38 :
PionException(
"No plug-ins found for identifier: ", plugin_id) {}
45 :
PionException(
"A plug-in already exists for identifier: ", plugin_id) {}
79 inline void add(
const std::string& plugin_id, PLUGIN_TYPE *plugin_object_ptr);
86 inline void remove(
const std::string& plugin_id);
94 inline void replace(
const std::string& plugin_id, PLUGIN_TYPE *plugin_ptr);
102 inline PLUGIN_TYPE *
clone(
const std::string& plugin_id);
112 inline PLUGIN_TYPE *
load(
const std::string& plugin_id,
const std::string& plugin_type);
120 inline PLUGIN_TYPE *
get(
const std::string& plugin_id);
128 inline const PLUGIN_TYPE *
get(
const std::string& plugin_id)
const;
144 inline PLUGIN_TYPE *
find(
const std::string& resource);
174 inline boost::uint64_t
getStatistic(
const std::string& plugin_id,
182 :
public std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >
185 inline void clear(
void);
186 virtual ~
PluginMap() { PluginMap::clear(); }
200 template <
typename PLUGIN_TYPE>
202 PLUGIN_TYPE *plugin_object_ptr)
205 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
206 m_plugin_map.insert(std::make_pair(plugin_id,
207 std::make_pair(plugin_object_ptr, plugin_ptr)));
210 template <
typename PLUGIN_TYPE>
213 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
215 if (i == m_plugin_map.end())
217 if (i->second.second.is_open()) {
218 i->second.second.destroy(i->second.first);
220 delete i->second.first;
222 m_plugin_map.erase(i);
225 template <
typename PLUGIN_TYPE>
228 PION_ASSERT(plugin_ptr);
229 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
231 if (i == m_plugin_map.end())
233 if (i->second.second.is_open()) {
234 i->second.second.destroy(i->second.first);
236 delete i->second.first;
238 i->second.first = plugin_ptr;
241 template <
typename PLUGIN_TYPE>
244 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
246 if (i == m_plugin_map.end())
248 return i->second.second.create();
251 template <
typename PLUGIN_TYPE>
253 const std::string& plugin_type)
260 if (m_plugin_map.find(plugin_id) != m_plugin_map.end())
271 plugin_ptr.
open(plugin_type);
275 PLUGIN_TYPE *plugin_object_ptr(plugin_ptr.
create());
278 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
279 m_plugin_map.insert(std::make_pair(plugin_id,
280 std::make_pair(plugin_object_ptr, plugin_ptr)));
282 return plugin_object_ptr;
285 template <
typename PLUGIN_TYPE>
288 PLUGIN_TYPE *plugin_object_ptr = NULL;
289 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
291 if (i != m_plugin_map.end())
292 plugin_object_ptr = i->second.first;
293 return plugin_object_ptr;
296 template <
typename PLUGIN_TYPE>
299 const PLUGIN_TYPE *plugin_object_ptr = NULL;
300 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
302 if (i != m_plugin_map.end())
303 plugin_object_ptr = i->second.first;
304 return plugin_object_ptr;
307 template <
typename PLUGIN_TYPE>
311 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
313 if (i != m_plugin_map.end())
314 plugin_ptr = i->second.second;
318 template <
typename PLUGIN_TYPE>
322 PLUGIN_TYPE *plugin_object_ptr = NULL;
325 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
328 if (m_plugin_map.empty())
return plugin_object_ptr;
332 while (i != m_plugin_map.begin()) {
336 if (resource.compare(0, i->first.size(), i->first) != 0) {
338 if (i != m_plugin_map.begin()) {
342 if (j->first.size() < i->first.size())
351 if (resource.size() == i->first.size() || resource[i->first.size()]==
'/') {
352 plugin_object_ptr = i->second.first;
357 return plugin_object_ptr;
360 template <
typename PLUGIN_TYPE>
363 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
365 i != m_plugin_map.end(); ++i)
367 run_func(i->second.first);
371 template <
typename PLUGIN_TYPE>
376 PLUGIN_TYPE *plugin_object_ptr =
get(plugin_id);
377 if (plugin_object_ptr == NULL)
379 run_func(plugin_object_ptr);
382 template <
typename PLUGIN_TYPE>
385 boost::uint64_t stat_value = 0;
386 boost::mutex::scoped_lock plugins_lock(m_plugin_mutex);
388 i != m_plugin_map.end(); ++i)
390 stat_value += stat_func(i->second.first);
395 template <
typename PLUGIN_TYPE>
401 if (plugin_object_ptr == NULL)
403 return stat_func(plugin_object_ptr);
409 template <
typename PLUGIN_TYPE>
415 i != std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::end(); ++i)
417 if (i->second.second.is_open()) {
418 i->second.second.destroy(i->second.first);
420 delete i->second.first;
423 this->erase(std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::begin(),
424 std::map<std::string, std::pair<PLUGIN_TYPE *, PionPluginPtr<PLUGIN_TYPE> > >::end());
void add(const std::string &plugin_id, PLUGIN_TYPE *plugin_object_ptr)
void run(PluginRunFunction run_func)
exception thrown if a plug-in cannot be found
PLUGIN_TYPE * find(const std::string &resource)
PluginManager(void)
default constructor
static bool findStaticEntryPoint(const std::string &plugin_name, void **create_func, void **destroy_func)
boost::uint64_t getStatistic(PluginStatFunction stat_func) const
PionPluginPtr< PLUGIN_TYPE > getLibPtr(const std::string &plugin_id) const
data type that maps identifiers to plug-in objects
void open(const std::string &plugin_name)
void openStaticLinked(const std::string &plugin_name, void *create_func, void *destroy_func)
boost::function1< void, PLUGIN_TYPE * > PluginRunFunction
data type for a function that may be called by the run() method
bool empty(void) const
returns true if there are no plug-in objects being managed
boost::function1< boost::uint64_t, const PLUGIN_TYPE * > PluginStatFunction
data type for a function that may be called by the getStat() method
void remove(const std::string &plugin_id)
virtual ~PluginManager()
default destructor
PluginMap m_plugin_map
collection of plug-in objects being managed
void replace(const std::string &plugin_id, PLUGIN_TYPE *plugin_ptr)
exception thrown if we try to add or load a duplicate plug-in
InterfaceClassType * create(void)
creates a new instance of the plug-in object
PLUGIN_TYPE * load(const std::string &plugin_id, const std::string &plugin_type)
PLUGIN_TYPE * clone(const std::string &plugin_id)
void clear(void)
clears all the plug-in objects being managed
PLUGIN_TYPE * get(const std::string &plugin_id)
boost::mutex m_plugin_mutex
mutex to make class thread-safe