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