00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00030
00031
00032
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
00267 PluginService();
00268
00269
00270 ~PluginService();
00271
00272
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 };
00286
00287 }
00288
00289
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*>& ,
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 }
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