PluginService.h

Go to the documentation of this file.
00001 // @(#)root/reflex:$Id: PluginService.h 29288 2009-07-01 13:03:35Z axel $
00002 // Author: Pere Mato 2006
00003 
00004 // Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
00005 //
00006 // Permission to use, copy, modify, and distribute this software for any
00007 // purpose is hereby granted without fee, provided that this copyright and
00008 // permissions notice appear in all copies and derivatives.
00009 //
00010 // This software is provided "as is" without express or implied warranty.
00011 
00012 #ifndef Reflex_PluginService
00013 #define Reflex_PluginService
00014 
00015 #include "Reflex/Builder/NamespaceBuilder.h"
00016 #include "Reflex/Builder/FunctionBuilder.h"
00017 #include "Reflex/ValueObject.h"
00018 #include "Reflex/Tools.h"
00019 
00020 #include <string>
00021 #include <sstream>
00022 
00023 #define PLUGINSVC_FACTORY_NS "__pf__"
00024 
00025 namespace Reflex {
00026 class PluginFactoryMap;
00027 
00028 /**
00029  * @class PluginService PluginService.h PluginService/PluginService.h
00030  * @author Pere Mato
00031  * @date 01/09/2006
00032  * @ingroup Ref
00033  */
00034 class RFLX_API PluginService {
00035 public:
00036    template <typename R>
00037    static R
00038    Create(const std::string& name) {
00039       return (R) Create(name, GetType<R>(), std::vector<ValueObject>());
00040    }
00041 
00042 
00043    template <typename R, typename A0>
00044    static R
00045    Create(const std::string& name,
00046           const A0& a0) {
00047       return (R) Create(name, GetType<R>(),
00048                         Tools::MakeVector(ValueObject::Create(a0)));
00049    }
00050 
00051 
00052    template <typename R, typename A0, typename A1>
00053    static R
00054    Create(const std::string& name,
00055           const A0& a0,
00056           const A1& a1) {
00057       return (R) Create(name, GetType<R>(),
00058                         Tools::MakeVector(ValueObject::Create(a0),
00059                                           ValueObject::Create(a1)));
00060    }
00061 
00062 
00063    template <typename R, typename A0, typename A1, typename A2>
00064    static R
00065    Create(const std::string& name,
00066           const A0& a0,
00067           const A1& a1,
00068           const A2& a2) {
00069       return (R) Create(name, GetType<R>(),
00070                         Tools::MakeVector(ValueObject::Create(a0),
00071                                           ValueObject::Create(a1),
00072                                           ValueObject::Create(a2)));
00073    }
00074 
00075 
00076    template <typename R, typename A0, typename A1, typename A2, typename A3>
00077    static R
00078    Create(const std::string& name,
00079           const A0& a0,
00080           const A1& a1,
00081           const A2& a2,
00082           const A3& a3) {
00083       return (R) Create(name, GetType<R>(),
00084                         Tools::MakeVector(ValueObject::Create(a0),
00085                                           ValueObject::Create(a1),
00086                                           ValueObject::Create(a2),
00087                                           ValueObject::Create(a3)));
00088    }
00089 
00090 
00091    template <typename R, typename A0, typename A1, typename A2, typename A3,
00092              typename A4>
00093    static R
00094    Create(const std::string& name,
00095           const A0& a0,
00096           const A1& a1,
00097           const A2& a2,
00098           const A3& a3,
00099           const A4& a4) {
00100       return (R) Create(name, GetType<R>(),
00101                         Tools::MakeVector(ValueObject::Create(a0),
00102                                           ValueObject::Create(a1),
00103                                           ValueObject::Create(a2),
00104                                           ValueObject::Create(a3),
00105                                           ValueObject::Create(a4)));
00106    }
00107 
00108 
00109    template <typename R, typename A0, typename A1, typename A2, typename A3,
00110              typename A4, typename A5>
00111    static R
00112    Create(const std::string& name,
00113           const A0& a0,
00114           const A1& a1,
00115           const A2& a2,
00116           const A3& a3,
00117           const A4& a4,
00118           const A5& a5) {
00119       return (R) Create(name, GetType<R>(),
00120                         Tools::MakeVector(ValueObject::Create(a0),
00121                                           ValueObject::Create(a1),
00122                                           ValueObject::Create(a2),
00123                                           ValueObject::Create(a3),
00124                                           ValueObject::Create(a4),
00125                                           ValueObject::Create(a5)));
00126    }
00127 
00128 
00129    template <typename R, typename A0, typename A1, typename A2, typename A3,
00130              typename A4, typename A5, typename A6>
00131    static R
00132    Create(const std::string& name,
00133           const A0& a0,
00134           const A1& a1,
00135           const A2& a2,
00136           const A3& a3,
00137           const A4& a4,
00138           const A5& a5,
00139           const A6& a6) {
00140       return (R) Create(name, GetType<R>(),
00141                         Tools::MakeVector(ValueObject::Create(a0),
00142                                           ValueObject::Create(a1),
00143                                           ValueObject::Create(a2),
00144                                           ValueObject::Create(a3),
00145                                           ValueObject::Create(a4),
00146                                           ValueObject::Create(a5),
00147                                           ValueObject::Create(a6)));
00148    }
00149 
00150 
00151    template <typename R, typename A0, typename A1, typename A2, typename A3,
00152              typename A4, typename A5, typename A6, typename A7>
00153    static R
00154    Create(const std::string& name,
00155           const A0& a0,
00156           const A1& a1,
00157           const A2& a2,
00158           const A3& a3,
00159           const A4& a4,
00160           const A5& a5,
00161           const A6& a6,
00162           const A7& a7) {
00163       return (R) Create(name, GetType<R>(),
00164                         Tools::MakeVector(ValueObject::Create(a0),
00165                                           ValueObject::Create(a1),
00166                                           ValueObject::Create(a2),
00167                                           ValueObject::Create(a3),
00168                                           ValueObject::Create(a4),
00169                                           ValueObject::Create(a5),
00170                                           ValueObject::Create(a6),
00171                                           ValueObject::Create(a7)));
00172    }
00173 
00174 
00175    static void* Create(const std::string& name,
00176                        const Type& ret,
00177                        const std::vector<ValueObject>& arg);
00178 
00179 
00180    template <typename T>
00181    static bool
00182    CompareId(const Any& id1,
00183              const Any& id2) {
00184       try { return id1.TypeInfo() == id2.TypeInfo() &&
00185                    any_cast<T>(id1) == any_cast<T>(id2); }
00186       catch (const BadAnyCast&) { return false; }
00187    }
00188 
00189 
00190    template <typename T> static std::string
00191    StringId(const Any& id) {
00192       std::stringstream s;
00193       try { s << any_cast<T>(id); }
00194       catch (const BadAnyCast&) {}
00195       return s.str();
00196    }
00197 
00198 
00199    template <typename R, typename T>
00200    static R
00201    CreateWithId(const T& id) {
00202       return (R) CreateWithId(id, StringId<T>, CompareId<T>, GetType<R>(),
00203                               std::vector<ValueObject>());
00204    }
00205 
00206 
00207    template <typename R, typename T, typename A0>
00208    static R
00209    CreateWithId(const T& id,
00210                 const A0& a0) {
00211       return (R) CreateWithId(id, StringId<T>, CompareId<T>, GetType<R>(),
00212                               Tools::MakeVector(ValueObject::Create(a0)));
00213    }
00214 
00215 
00216    template <typename R, typename T, typename A0, typename A1>
00217    static R
00218    CreateWithId(const T& id,
00219                 const A0& a0,
00220                 const A1& a1) {
00221       return (R) CreateWithId(id, StringId<T>, CompareId<T>, GetType<R>(),
00222                               Tools::MakeVector(ValueObject::Create(a0), ValueObject::Create(a1)));
00223    }
00224 
00225 
00226    template <typename R, typename T, typename A0, typename A1, typename A2>
00227    static R
00228    CreateWithId(const T& id,
00229                 const A0& a0,
00230                 const A1& a1,
00231                 const A2& a2) {
00232       return (R) CreateWithId(id, StringId<T>, CompareId<T>, GetType<R>(),
00233                               Tools::MakeVector(ValueObject::Create(a0), ValueObject::Create(a1),
00234                                                 ValueObject::Create(a2)));
00235    }
00236 
00237 
00238    template <typename R, typename T, typename A0, typename A1, typename A2, typename A3>
00239    static R
00240    CreateWithId(const T& id,
00241                 const A0& a0,
00242                 const A1& a1,
00243                 const A2& a2,
00244                 const A3& a3) {
00245       return (R) CreateWithId(id, StringId<T>, CompareId<T>, GetType<R>(),
00246                               Tools::MakeVector(ValueObject::Create(a0), ValueObject::Create(a1),
00247                                                 ValueObject::Create(a2), ValueObject::Create(a3)));
00248    }
00249 
00250 
00251    static void* CreateWithId(const Any &id,
00252                              std::string (* str)(const Any&),
00253                              bool (* cmp)(const Any&,
00254                                           const Any&),
00255                              const Type &ret,
00256                              const std::vector<ValueObject> &arg);
00257 
00258 
00259    static std::string FactoryName(const std::string& n);
00260 
00261    static int Debug();
00262 
00263    static void SetDebug(int);
00264 
00265 private:
00266    /** Constructor */
00267    PluginService();
00268 
00269    /** Destructor */
00270    ~PluginService();
00271 
00272    /** Get single instance of PluginService */
00273    static PluginService& Instance();
00274 
00275    int LoadFactoryLib(const std::string& name);
00276 
00277    int ReadMaps();
00278 
00279    int fDebugLevel;
00280 
00281    Scope fFactories;
00282 
00283    PluginFactoryMap* fFactoryMap;
00284 
00285 };    // class PluginService
00286 
00287 }  // namespace Reflex
00288 
00289 //--- Factory stub functions for the different number of parameters
00290 namespace {
00291 template <typename T> struct Arg {
00292    static T
00293    Cast(void* a) { return *(T*) a; }
00294 
00295 };
00296 
00297 template <typename T> struct Arg<T*> {
00298    static T*
00299    Cast(void* a) { return (T*) a; }
00300 
00301 };
00302 
00303 template <typename P, typename S> class Factory;
00304 
00305 template <typename P, typename R> class Factory<P, R(void)> {
00306 public:
00307    static void
00308    Func(void* retaddr,
00309         void*,
00310         const std::vector<void*>& /* arg */,
00311         void*) {
00312       *(R*) retaddr = (R) ::new P;
00313    }
00314 
00315 
00316 };
00317 
00318 template <typename P, typename R, typename A0> class Factory<P, R(A0)> {
00319 public:
00320    static void
00321    Func(void* retaddr,
00322         void*,
00323         const std::vector<void*>& arg,
00324         void*) {
00325       *(R*) retaddr = (R) ::new P(Arg<A0>::Cast(arg[0]));
00326    }
00327 
00328 
00329 };
00330 
00331 template <typename P, typename R, typename A0, typename A1> class Factory<P, R(A0, A1)> {
00332 public:
00333    static void
00334    Func(void* retaddr,
00335         void*,
00336         const std::vector<void*>& arg,
00337         void*) {
00338       *(R*) retaddr = (R) ::new P(Arg<A0>::Cast(arg[0]), Arg<A1>::Cast(arg[1]));
00339    }
00340 
00341 
00342 };
00343 
00344 template <typename P, typename R, typename A0, typename A1, typename A2> class Factory<P, R(A0, A1, A2)> {
00345 public:
00346    static void
00347    Func(void* retaddr,
00348         void*,
00349         const std::vector<void*>& arg,
00350         void*) {
00351       *(R*) retaddr = (R) ::new P(Arg<A0>::Cast(arg[0]), Arg<A1>::Cast(arg[1]), Arg<A2>::Cast(arg[2]));
00352    }
00353 
00354 
00355 };
00356 
00357 template <typename P, typename R, typename A0, typename A1, typename A2, typename A3> class Factory<P, R(A0, A1, A2, A3)> {
00358 public:
00359    static void
00360    Func(void* retaddr,
00361         void*,
00362         const std::vector<void*>& arg,
00363         void*) {
00364       *(R*) retaddr = (R) ::new P(Arg<A0>::Cast(arg[0]), Arg<A1>::Cast(arg[1]), Arg<A2>::Cast(arg[2]), Arg<A3>::Cast(arg[3]));
00365    }
00366 
00367 
00368 };
00369 
00370 } // unnamed namespace
00371 
00372 
00373 #define PLUGINSVC_CNAME(name, serial) name ## _dict ## serial
00374 #define PLUGINSVC_FACTORY(type, signature) _PLUGINSVC_FACTORY(type, signature, __LINE__)
00375 #define PLUGINSVC_FACTORY_WITH_ID(type, id, signature) _PLUGINSVC_FACTORY_WITH_ID(type, id, signature, __LINE__)
00376 
00377 #define _PLUGINSVC_FACTORY(type, signature, serial) \
00378    namespace { \
00379    struct PLUGINSVC_CNAME (type, serial) { \
00380       PLUGINSVC_CNAME(type, serial) () { \
00381          std::string name = Reflex::GetType < type > ().Name(Reflex::SCOPED); \
00382          Reflex::Type sig = Reflex::FunctionDistiller < signature > ::Get(); \
00383          std::string fname = (std::string(PLUGINSVC_FACTORY_NS "::") + Reflex::PluginService::FactoryName(name)); \
00384          Reflex::FunctionBuilder(sig, fname.c_str(), \
00385                                  Factory < type, signature > ::Func, 0, "", Reflex::PUBLIC) \
00386          .AddProperty("name", name); \
00387          if (Reflex::PluginService::Debug()) { std::cout << "PluginService: Declared factory for class " << name << " with signature " << sig.Name() << std::endl; } \
00388       } \
00389    }; \
00390    PLUGINSVC_CNAME(type, serial) PLUGINSVC_CNAME(s_ ## type, serial); \
00391    }
00392 
00393 #define _PLUGINSVC_FACTORY_WITH_ID(type, id, signature, serial) \
00394    namespace { \
00395    struct PLUGINSVC_CNAME (type, serial) { \
00396       PLUGINSVC_CNAME(type, serial) () { \
00397          std::string name = Reflex::GetType < type > ().Name(Reflex::SCOPED); \
00398          Reflex::Type sig = Reflex::FunctionDistiller < signature > ::Get(); \
00399          std::stringstream s; s << id; \
00400          std::string fname = (std::string(PLUGINSVC_FACTORY_NS "::") + Reflex::PluginService::FactoryName(s.str())); \
00401          Reflex::FunctionBuilder(sig, fname.c_str(), \
00402                                  Factory < type, signature > ::Func, 0, "", Reflex::PUBLIC) \
00403          .AddProperty("name", name) \
00404          .AddProperty("id", id); \
00405          if (Reflex::PluginService::Debug()) { std::cout << "PluginService: Declared factory for id " << fname << " with signature " << sig.Name() << std::endl; } \
00406       } \
00407    }; \
00408    PLUGINSVC_CNAME(type, serial) PLUGINSVC_CNAME(s_ ## type, serial); \
00409    }
00410 
00411 #endif // Reflex_PluginService

Generated on Tue Jul 5 14:25:54 2011 for ROOT_528-00b_version by  doxygen 1.5.1