00001 #ifndef __ARC_PLUGIN_H__
00002
00003 #define __ARC_PLUGIN_H__
00004
00005 #include <string>
00006 #include <map>
00007 #include <typeinfo>
00008 #include <inttypes.h>
00009 #include <sys/types.h>
00010 #ifdef HAVE_STDINT_H
00011 #include <stdint.h>
00012 #endif
00013
00014 #include <arc/Thread.h>
00015 #include <arc/Logger.h>
00016 #include <arc/XMLNode.h>
00017 #include <arc/loader/ModuleManager.h>
00018
00019 namespace Arc {
00020
00021 class PluginsFactory;
00022
00024
00027 class PluginArgument {
00028 friend class PluginsFactory;
00029 private:
00030 PluginsFactory* factory_;
00031 Glib::Module* module_;
00032 void set_factory(PluginsFactory* factory);
00033 void set_module(Glib::Module* module);
00034 protected:
00035 PluginArgument(void);
00036 public:
00037 virtual ~PluginArgument(void);
00039
00042 PluginsFactory* get_factory(void);
00044
00049 Glib::Module* get_module(void);
00050 };
00051
00053
00055 class Plugin {
00056 private:
00057 Plugin(void) {};
00058 Plugin& operator=(const Plugin&) { return *this; };
00059 protected:
00060 PluginsFactory* factory_;
00061 Glib::Module* module_;
00063 Plugin(PluginArgument* arg);
00065 Plugin(const Plugin& obj);
00066 public:
00067 virtual ~Plugin(void);
00068 };
00069
00071
00075 extern const char* plugins_table_name;
00076
00077 #define PLUGINS_TABLE_NAME __arc_plugins_table__
00078 #define PLUGINS_TABLE_SYMB "__arc_plugins_table__"
00079
00081
00086 typedef Plugin* (*get_plugin_instance)(PluginArgument* arg);
00087
00089 typedef struct {
00090 const char* name;
00091 const char* kind;
00092 const char* description;
00093 uint32_t version;
00094 get_plugin_instance instance;
00095 } PluginDescriptor;
00096
00097
00099
00100 class PluginDesc {
00101 public:
00102 std::string name;
00103 std::string kind;
00104 std::string description;
00105 uint32_t version;
00106 };
00107
00109
00110 class ModuleDesc {
00111 public:
00112 std::string name;
00113 std::list<PluginDesc> plugins;
00114 };
00115
00117
00125 class PluginsFactory: public ModuleManager {
00126 friend class PluginArgument;
00127 private:
00128 Glib::Mutex lock_;
00129 typedef std::map<std::string,PluginDescriptor*> descriptors_t_;
00130 typedef std::map<std::string,Glib::Module*> modules_t_;
00131 descriptors_t_ descriptors_;
00132 modules_t_ modules_;
00133 bool try_load_;
00134 static Logger logger;
00135 bool load(const std::string& name,const std::list<std::string>& kinds,const std::list<std::string>& pnames);
00136 public:
00139 PluginsFactory(XMLNode cfg);
00156 void TryLoad(bool v) { try_load_ = v; };
00157 bool TryLoad(void) { return try_load_; };
00158 Plugin* get_instance(const std::string& kind,PluginArgument* arg,bool search = true);
00159 Plugin* get_instance(const std::string& kind,int version,PluginArgument* arg,bool search = true);
00160 Plugin* get_instance(const std::string& kind,int min_version,int max_version,PluginArgument* arg,bool search = true);
00161 Plugin* get_instance(const std::string& kind,const std::string& name,PluginArgument* arg,bool search = true);
00162 Plugin* get_instance(const std::string& kind,const std::string& name,int version,PluginArgument* arg,bool search = true);
00163 Plugin* get_instance(const std::string& kind,const std::string& name,int min_version,int max_version,PluginArgument* arg,bool search = true);
00171 bool load(const std::string& name);
00172 bool load(const std::string& name,const std::string& kind);
00173 bool load(const std::string& name,const std::string& kind,const std::string& pname);
00174 bool load(const std::string& name,const std::list<std::string>& kinds);
00175 bool load(const std::list<std::string>& names,const std::string& kind);
00176 bool load(const std::list<std::string>& names,const std::string& kind,const std::string& pname);
00177 bool load(const std::list<std::string>& names,const std::list<std::string>& kinds);
00178
00182 bool scan(const std::string& name, ModuleDesc& desc);
00183 bool scan(const std::list<std::string>& names, std::list<ModuleDesc>& descs);
00185 void report(std::list<ModuleDesc>& descs);
00187 static void FilterByKind(const std::string& kind, std::list<ModuleDesc>& descs);
00188
00189 template<class P>
00190 P* GetInstance(const std::string& kind,PluginArgument* arg,bool search = true) {
00191 Plugin* plugin = get_instance(kind,arg,search);
00192 if(!plugin) return NULL;
00193 P* p = dynamic_cast<P*>(plugin);
00194 if(!p) delete plugin;
00195 return p;
00196 }
00197 template<class P>
00198 P* GetInstance(const std::string& kind,const std::string& name,PluginArgument* arg,bool search = true) {
00199 Plugin* plugin = get_instance(kind,name,arg,search);
00200 if(!plugin) return NULL;
00201 P* p = dynamic_cast<P*>(plugin);
00202 if(!p) delete plugin;
00203 return p;
00204 }
00205 };
00206
00207 template<class P>
00208 P* PluginCast(PluginArgument* p) {
00209 if(p == NULL) return NULL;
00210 P* pp = dynamic_cast<P*>(p);
00211 if(pp != NULL) return pp;
00212
00213 if(strcmp(typeid(P).name(),typeid(*p).name()) != 0) return NULL;
00214 return static_cast<P*>(p);
00215 }
00216
00217 template<class P>
00218 P* PluginCast(Plugin* p) {
00219 if(p == NULL) return NULL;
00220 P* pp = dynamic_cast<P*>(p);
00221 if(pp != NULL) return pp;
00222
00223 if(strcmp(typeid(P).name(),typeid(*p).name()) != 0) return NULL;
00224 return static_cast<P*>(p);
00225 }
00226
00227 }
00228
00229 #endif
00230