00001 #ifndef FWCore_PluginManager_PluginFactory_h
00002 #define FWCore_PluginManager_PluginFactory_h
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022
00023 #include <map>
00024 #include <vector>
00025
00026
00027 #include "FWCore/PluginManager/interface/PluginFactoryBase.h"
00028 #include "FWCore/Utilities/interface/Exception.h"
00029 #include "FWCore/PluginManager/interface/PluginManager.h"
00030
00031
00032 namespace edmplugin {
00033 template< class T> class PluginFactory;
00034 class DummyFriend;
00035
00036 template<class R>
00037 class PluginFactory<R * (void)> : public PluginFactoryBase
00038 {
00039 friend class DummyFriend;
00040 public:
00041 struct PMakerBase {
00042 virtual R* create(void) const = 0;
00043 virtual ~PMakerBase() {}
00044 };
00045 template<class TPlug>
00046 struct PMaker : public PMakerBase {
00047 PMaker(const std::string& iName) {
00048 PluginFactory<R*(void)>::get()->registerPMaker(this,iName);
00049 }
00050 virtual R* create() const {
00051 return new TPlug();
00052 }
00053 };
00054 typedef std::vector<std::pair<PMakerBase*, std::string> > PMakers;
00055 typedef std::map<std::string, PMakers > Plugins;
00056
00057
00058 virtual std::vector<PluginInfo> available() const {
00059 std::vector<PluginInfo> returnValue;
00060 returnValue.reserve(m_plugins.size());
00061 fillAvailable(m_plugins.begin(),
00062 m_plugins.end(),
00063 returnValue);
00064 return returnValue;
00065 }
00066 virtual const std::string& category() const ;
00067
00068 R* create(const std::string& iName) const {
00069 return PluginFactoryBase::findPMaker(iName,m_plugins)->second.front().first->create();
00070 }
00071
00073 R* tryToCreate(const std::string& iName) const {
00074 typename Plugins::const_iterator itFound = PluginFactoryBase::tryToFindPMaker(iName,m_plugins);
00075 if(itFound ==m_plugins.end() ) {
00076 return 0;
00077 }
00078 return itFound->second.front().first->create();
00079 }
00080
00081
00082 static PluginFactory<R*(void)>* get();
00083
00084 void registerPMaker(PMakerBase* iPMaker, const std::string& iName) {
00085 m_plugins[iName].push_back(std::pair<PMakerBase*,std::string>(iPMaker,PluginManager::loadingFile()));
00086 newPlugin(iName);
00087 }
00088
00089 private:
00090 PluginFactory() {
00091 finishedConstruction();
00092 }
00093 PluginFactory(const PluginFactory&);
00094
00095 const PluginFactory& operator=(const PluginFactory&);
00096
00097
00098 Plugins m_plugins;
00099
00100 };
00101
00102 template<class R, class Arg>
00103 class PluginFactory<R * (Arg)> : public PluginFactoryBase
00104 {
00105 friend class DummyFriend;
00106 public:
00107 struct PMakerBase {
00108 virtual R* create(Arg) const = 0;
00109 virtual ~PMakerBase() {}
00110 };
00111 template<class TPlug>
00112 struct PMaker : public PMakerBase {
00113 PMaker(const std::string& iName) {
00114 PluginFactory<R*(Arg)>::get()->registerPMaker(this,iName);
00115 }
00116 virtual R* create(Arg iArg) const {
00117 return new TPlug(iArg);
00118 }
00119 };
00120 typedef std::vector<std::pair<PMakerBase*, std::string> > PMakers;
00121 typedef std::map<std::string, PMakers > Plugins;
00122
00123
00124 virtual std::vector<PluginInfo> available() const {
00125 std::vector<PluginInfo> returnValue;
00126 returnValue.reserve(m_plugins.size());
00127 fillAvailable(m_plugins.begin(),
00128 m_plugins.end(),
00129 returnValue);
00130 return returnValue;
00131 }
00132 virtual const std::string& category() const ;
00133
00134 R* create(const std::string& iName, Arg iArg) const {
00135 return PluginFactoryBase::findPMaker(iName,m_plugins)->second.front().first->create(iArg);
00136 }
00138 R* tryToCreate(const std::string& iName, Arg iArg) const {
00139 typename Plugins::const_iterator itFound = PluginFactoryBase::tryToFindPMaker(iName,m_plugins);
00140 if(itFound ==m_plugins.end() ) {
00141 return 0;
00142 }
00143 return itFound->second.front().first->create(iArg);
00144 }
00145
00146
00147 static PluginFactory<R*(Arg)>* get();
00148
00149 void registerPMaker(PMakerBase* iPMaker, const std::string& iName) {
00150 m_plugins[iName].push_back(std::pair<PMakerBase*,std::string>(iPMaker,PluginManager::loadingFile()));
00151 newPlugin(iName);
00152 }
00153
00154 private:
00155 PluginFactory() {
00156 finishedConstruction();
00157 }
00158 PluginFactory(const PluginFactory&);
00159
00160 const PluginFactory& operator=(const PluginFactory&);
00161
00162
00163 Plugins m_plugins;
00164
00165 };
00166
00167 template<class R, class Arg1, class Arg2>
00168 class PluginFactory<R * (Arg1, Arg2)> : public PluginFactoryBase
00169 {
00170 friend class DummyFriend;
00171 public:
00172 struct PMakerBase {
00173 virtual R* create(Arg1, Arg2) const = 0;
00174 virtual ~PMakerBase() {}
00175 };
00176 template<class TPlug>
00177 struct PMaker : public PMakerBase {
00178 PMaker(const std::string& iName) {
00179 PluginFactory<R*(Arg1,Arg2)>::get()->registerPMaker(this,iName);
00180 }
00181 virtual R* create(Arg1 iArg1, Arg2 iArg2) const {
00182 return new TPlug(iArg1, iArg2);
00183 }
00184 };
00185 typedef std::vector<std::pair<PMakerBase*, std::string> > PMakers;
00186 typedef std::map<std::string, PMakers > Plugins;
00187
00188
00189 virtual std::vector<PluginInfo> available() const {
00190 std::vector<PluginInfo> returnValue;
00191 returnValue.reserve(m_plugins.size());
00192 fillAvailable(m_plugins.begin(),
00193 m_plugins.end(),
00194 returnValue);
00195 return returnValue;
00196 }
00197 virtual const std::string& category() const ;
00198
00199 R* create(const std::string& iName, Arg1 iArg1, Arg2 iArg2) const {
00200 return PluginFactoryBase::findPMaker(iName,m_plugins)->second.front().first->create(iArg1, iArg2);
00201 }
00203 R* tryToCreate(const std::string& iName, Arg1 iArg1, Arg2 iArg2) const {
00204 typename Plugins::const_iterator itFound = PluginFactoryBase::tryToFindPMaker(iName,m_plugins);
00205 if(itFound ==m_plugins.end() ) {
00206 return 0;
00207 }
00208 return itFound->second.front().first->create(iArg1,iArg2);
00209 }
00210
00211
00212
00213 static PluginFactory<R*(Arg1,Arg2)>* get();
00214
00215 void registerPMaker(PMakerBase* iPMaker, const std::string& iName) {
00216 m_plugins[iName].push_back(std::pair<PMakerBase*,std::string>(iPMaker,PluginManager::loadingFile()));
00217 newPlugin(iName);
00218 }
00219
00220 private:
00221 PluginFactory() {
00222 finishedConstruction();
00223 }
00224 PluginFactory(const PluginFactory&);
00225
00226 const PluginFactory& operator=(const PluginFactory&);
00227
00228
00229 Plugins m_plugins;
00230 };
00231
00232 }
00233 #define CONCATENATE_HIDDEN(a,b) a ## b
00234 #define CONCATENATE(a,b) CONCATENATE_HIDDEN(a,b)
00235 #define EDM_REGISTER_PLUGINFACTORY(_factory_,_category_) \
00236 namespace edmplugin {\
00237 template<> _factory_* _factory_::get() { static _factory_ s_instance; return &s_instance;}\
00238 template<> const std::string& _factory_::category() const { static std::string s_cat(_category_); return s_cat;}\
00239 } enum {CONCATENATE(dummy_edm_register_pluginfactory_, __LINE__)}
00240
00241 #endif
00242
00243 #define EDM_PLUGIN_SYM(x,y) EDM_PLUGIN_SYM2(x,y)
00244 #define EDM_PLUGIN_SYM2(x,y) x ## y
00245
00246 #define DEFINE_EDM_PLUGIN(factory,type,name) \
00247 static factory::PMaker<type> EDM_PLUGIN_SYM(s_maker , __LINE__ ) (name)
00248
00249
00250 #include "FWCore/PluginManager/interface/ModuleDef.h"