Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #ifndef RVE_PLUGINLOADER_PLUGIN_H
00031 #define RVE_PLUGINLOADER_PLUGIN_H
00032 
00033 #include "class_entry.h"
00034 
00035 #include <string>
00036 #include <list>
00037 #include <stdexcept>
00038 
00039 #include <boost/shared_ptr.hpp>
00040 #include <boost/signals.hpp>
00041 
00042 #include <rve_dynlib/dynlib.h>
00043 
00044 namespace YAML
00045 {
00046 class Node;
00047 }
00048 
00049 namespace rve_pluginloader
00050 {
00051 
00052 typedef std::map<std::string, std::string> M_string;
00053 
00054 class Plugin;
00055 struct PluginStatus
00056 {
00057   PluginStatus(Plugin* p)
00058   : plugin(p)
00059   {}
00060   Plugin* plugin;
00061 };
00062 typedef boost::signal<void(const PluginStatus&)> PluginStatusSignal;
00063 
00064 class Exception : public std::runtime_error
00065 {
00066 public:
00067   Exception(const std::string& str)
00068   : std::runtime_error(str)
00069   {}
00070 };
00071 
00072 class PluginParseException : public Exception
00073 {
00074 public:
00075   PluginParseException(const std::string& file, const std::string& error)
00076   : Exception("Unable to parse plugin description file [" + file + "]: " + error)
00077   {}
00078 };
00079 
00080 class LibraryLoadException : public Exception
00081 {
00082 public:
00083   LibraryLoadException(const std::string& library_name, const std::string& error)
00084   : Exception("Unable to load library [" + library_name + "]: " + error)
00085   {}
00086 };
00087 
00088 class LibraryDoesNotExistException : public Exception
00089 {
00090 public:
00091   LibraryDoesNotExistException(const std::string& library_name)
00092   : Exception("Library [" + library_name + "] does not exist on disk")
00093   {}
00094 };
00095 
00096 class NoPluginRegisterFunctionException : public Exception
00097 {
00098 public:
00099   NoPluginRegisterFunctionException(const std::string& library_name)
00100   : Exception("Library [" + library_name + "] does not have an rvePluginRegister(rve_pluginloader::TypeRegistry*) function!")
00101   {}
00102 };
00103 
00104 class PluginDoesNotContainClassException : public Exception
00105 {
00106 public:
00107   PluginDoesNotContainClassException(const std::string& package, const std::string& derived_class)
00108   : Exception("Plugin from package [" + package + "] does not contain class [" + derived_class + "]")
00109   {}
00110 };
00111 
00112 class OutstandingAllocationException : public Exception
00113 {
00114 public:
00115   OutstandingAllocationException(const std::string& str)
00116   : Exception(str)
00117   {}
00118 };
00119 
00120 class Plugin
00121 {
00122 public:
00123   Plugin();
00124   ~Plugin();
00125 
00126   void loadDescription(const std::string& description_path);
00127   void load();
00128   void unload();
00129   bool isLoaded();
00130 
00131   const std::string& getPackageName() const { return package_name_; }
00132   const std::string& getDescriptionPath() const { return description_path_; }
00133   const std::string& getName() { return name_; }
00134 
00135   PluginStatusSignal& getLoadingSignal() { return loading_signal_; }
00136   PluginStatusSignal& getLoadedSignal() { return loaded_signal_; }
00137   PluginStatusSignal& getUnloadingSignal() { return unloading_signal_; }
00138   PluginStatusSignal& getUnloadedSignal() { return unloaded_signal_; }
00139 
00140   YAML::Node& getDescription() { return *doc_; }
00141 
00142   const V_ClassEntry* getClassEntries(const std::string& base_class) const;
00143   const ClassEntryPtr& getClassEntry(const std::string& base_class, const std::string& derived_class) const;
00144 
00145   bool hasClass(const std::string& base_class, const std::string& derived_class) const;
00146 
00147   template<typename T>
00148   T* create(const std::string& base_class, const std::string& derived_class)
00149   {
00150     T* t = static_cast<T*>(create(base_class, derived_class));
00151     return t;
00152   }
00153 
00154   void* create(const std::string& base_class, const std::string& derived_class);
00155 
00156   template<typename T>
00157   boost::shared_ptr<T> createShared(const std::string& base_class, const std::string& derived_class)
00158   {
00159     return boost::static_pointer_cast<T>(createShared(base_class, derived_class));
00160   }
00161 
00162   boost::shared_ptr<void> createShared(const std::string& base_class, const std::string& derived_class);
00163 
00164   void destroy(void* mem);
00165   bool ownsAllocation(void* mem);
00166 
00167 private:
00168   void unload(bool allow_throw);
00169 
00170   std::string description_path_;
00171   std::string package_name_;
00172   std::string package_path_;
00173   std::string library_path_;
00174   std::string name_;
00175 
00176   M_ClassEntry class_entries_;
00177 
00178   bool loaded_;
00179 
00180   rve_dynlib::Handle library_;
00181 
00182   PluginStatusSignal loading_signal_;
00183   PluginStatusSignal loaded_signal_;
00184   PluginStatusSignal unloading_signal_;
00185   PluginStatusSignal unloaded_signal_;
00186 
00187   YAML::Node* doc_;
00188 
00189   struct AllocationInfo
00190   {
00191     void* pointer;
00192     std::vector<void*> backtrace;
00193     std::string base_class;
00194     std::string derived_class;
00195   };
00196   typedef std::map<void*, AllocationInfo> M_AllocationInfo;
00197   M_AllocationInfo allocations_;
00198 };
00199 typedef boost::shared_ptr<Plugin> PluginPtr;
00200 typedef std::list<PluginPtr> L_Plugin;
00201 
00202 }
00203 
00204 #endif // RVE_PLUGINLOADER_PLUGIN_MANAGER_H
00205