00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef PLUGINREGISTRATION_H
00011 #define PLUGINREGISTRATION_H
00012
00013 #include "AppConfig.h"
00014 #include "ConfigurationSettings.h"
00015 #include "External.h"
00016 #include <algorithm>
00017 #include <stdlib.h>
00018 #include <string>
00019 #include <vector>
00020
00021 class PlugIn;
00022
00023 #define MOD_ZERO 0
00024 #define MOD_ONE 1
00025 #define MOD_TWO 2
00026 #define MOD_THREE 3
00027
00028 #if defined(DEPRECATED_MODULE_TYPE)
00029
00030 #define REGISTER_MODULE_BASIC(name__, moduleNamespace__) \
00031 class YouCannotUseThisMacroWith_DEPRECATED_MODULE_TYPE_defined; \
00032 const int iYouCannotUseThisMacroWith_DEPRECATED_MODULE_TYPE_defined = \
00033 sizeof(YouCannotUseThisMacroWith_DEPRECATED_MODULE_TYPE_defined);
00034
00035 #define REGISTER_MODULE(name__) REGISTER_MODULE_BASIC(1, 1)
00036 #define REGISTER_NON_CACHED_MODULE REGISTER_MODULE_BASIC(1, 1)
00037 #define REGISTER_DYNAMIC_MODULE(name__, dynamicFactoryClass__) REGISTER_MODULE_BASIC(1, 1)
00038 #define REGISTER_PLUGIN(moduleNamespace__, pluginname__, className__) REGISTER_MODULE_BASIC(1, 1)
00039 #define REGISTER_PLUGIN_BASIC(moduleNamespace__, name__) REGISTER_MODULE_BASIC(1, 1)
00040 #define GENERATE_FACTORY(moduleNamespace__) REGISTER_MODULE_BASIC(1, 1)
00041 #define GENERATE_DYNAMIC_FACTORY(moduleNamespace__, dynamicFactoryClass__) REGISTER_MODULE_BASIC(1, 1)
00042
00043 #else
00044
00045
00046
00047
00048
00049 struct OpticksModuleDescriptor
00050 {
00051 unsigned int version;
00052 const char* pModuleId;
00053
00054
00055
00056 const char* pInstantiateSymbol;
00057 bool debug;
00058
00059
00060 bool cacheable;
00061
00062 };
00063
00064
00065
00066
00067
00068
00069 typedef struct OpticksModuleDescriptor*(*OpticksGetModuleDescriptorType)(External*);
00070
00071
00072
00073
00074
00075
00076 typedef bool(*OpticksInstantiateType)(External*, unsigned int, PlugIn**);
00077
00078
00079 #ifdef DEBUG
00080 #define DEBUG_BOOL true
00081 #else
00082 #define DEBUG_BOOL false
00083 #endif
00084 #define REGISTER_MODULE_BASIC(name__, moduleNamespace__, canCache__, modVersion__) \
00085 extern "C" \
00086 { \
00087 struct OpticksModuleDescriptor name__##Descriptor = \
00088 { \
00089 modVersion__, \
00090 #name__, \
00091 #name__ "InstantiatePlugIn", \
00092 DEBUG_BOOL, \
00093 canCache__ \
00094 }; \
00095 LINKAGE struct OpticksModuleDescriptor* opticks_get_module_descriptor(External*) \
00096 { \
00097 return &name__##Descriptor; \
00098 } \
00099 LINKAGE bool name__##InstantiatePlugIn(External* pExternal, unsigned int plugInNumber, PlugIn** pPlugIn) \
00100 { \
00101 ModuleManager::instance()->setService(pExternal); \
00102 *pPlugIn = moduleNamespace__::getPlugIn(plugInNumber); \
00103 return *pPlugIn != NULL; \
00104 } \
00105 }; \
00106 const char* ModuleManager::mspName = NULL; \
00107 const char* ModuleManager::mspVersion = NULL; \
00108 const char* ModuleManager::mspDescription = NULL; \
00109 const char* ModuleManager::mspValidationKey = NULL; \
00110 const char* ModuleManager::mspUniqueId = NULL; \
00111 unsigned int ModuleManager::getTotalPlugIns() { return 0; } \
00112 PlugIn* ModuleManager::getPlugIn(unsigned int) { return NULL; }
00113
00114 #define REGISTER_NON_CACHED_MODULE(name__) \
00115 GENERATE_FACTORY(name__) \
00116 REGISTER_MODULE_BASIC(name__, name__, false, MOD_THREE)
00117
00118 #define REGISTER_MODULE(name__) \
00119 GENERATE_FACTORY(name__) \
00120 REGISTER_MODULE_BASIC(name__, name__, true, MOD_THREE)
00121
00122 #define REGISTER_DYNAMIC_MODULE(name__, dynamicFactoryClass__) \
00123 GENERATE_DYNAMIC_FACTORY(name__, dynamicFactoryClass__) \
00124 REGISTER_MODULE_BASIC(name__, name__, false, MOD_THREE)
00125
00126 #define REGISTER_V2_MODULE(name__) \
00127 GENERATE_FACTORY(name__) \
00128 REGISTER_MODULE_BASIC(name__, name__, true, MOD_TWO)
00129
00130 #define REGISTER_V2_DYNAMIC_MODULE(name__, dynamicFactoryClass__) \
00131 GENERATE_DYNAMIC_FACTORY(name__, dynamicFactoryClass__) \
00132 REGISTER_MODULE_BASIC(name__, name__, false, MOD_TWO)
00133
00134 class PlugIn;
00135 class PlugInFactory;
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 class PlugInFactory
00147 {
00148 public:
00149
00150
00151
00152
00153
00154
00155 PlugInFactory() {}
00156
00157 virtual ~PlugInFactory() {}
00158
00159
00160
00161
00162
00163
00164 virtual PlugIn* createPlugIn(const std::string& name) = 0;
00165
00166 virtual std::vector<std::string> getPlugInNames() = 0;
00167 };
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 class BasicPlugInFactory : public PlugInFactory
00180 {
00181 public:
00182
00183
00184
00185
00186
00187
00188 BasicPlugInFactory(const std::string& name) : PlugInFactory()
00189 {
00190 addPlugInName(name);
00191 }
00192 virtual ~BasicPlugInFactory() {}
00193 virtual std::vector<std::string> getPlugInNames()
00194 {
00195 return mPlugInNames;
00196 }
00197
00198 private:
00199 BasicPlugInFactory() {}
00200
00201 void addPlugInName(std::string name)
00202 {
00203 mPlugInNames.push_back(name);
00204 }
00205
00206 std::vector<std::string> mPlugInNames;
00207 };
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 class DynamicPlugInFactory : public PlugInFactory
00220 {
00221 public:
00222
00223
00224
00225
00226
00227
00228 DynamicPlugInFactory() {}
00229 virtual ~DynamicPlugInFactory() {};
00230
00231
00232 void setModuleId(const std::string& moduleId)
00233 {
00234 mModuleId = moduleId;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 virtual void init(bool locate, std::vector<std::string>& dynamicPlugIns) = 0;
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 virtual PlugIn* createPlugIn(const std::string& name) = 0;
00294
00295
00296 std::vector<std::string> getPlugInNames()
00297 {
00298 Service<ConfigurationSettings> pSettings;
00299 std::string plugInsKey = "_" + mModuleId + "DynamicPlugInNames_";
00300 std::vector<std::string> names;
00301 if (pSettings->isTemporarySetting(plugInsKey))
00302 {
00303 const std::vector<std::string>* pNames = NULL;
00304 pNames = dv_cast<std::vector<std::string> >(&pSettings->getSetting(plugInsKey));
00305 if (pNames != NULL)
00306 {
00307 names = *pNames;
00308 }
00309 std::vector<std::string> tempCopy = names;
00310 init(false, tempCopy);
00311 }
00312 else
00313 {
00314 init(true, names);
00315 pSettings->setTemporarySetting(plugInsKey, names);
00316 }
00317 return names;
00318 }
00319
00320 protected:
00321
00322 std::string mModuleId;
00323
00324 };
00325
00326
00327
00328
00329
00330 struct FactoryPtrComparator
00331 {
00332 bool operator()(std::pair<std::string, PlugInFactory*> pLhs, std::pair<std::string, PlugInFactory*> pRhs)
00333 {
00334 if (pLhs.second == NULL || pRhs.second == NULL)
00335 {
00336 return false;
00337 }
00338 size_t leftCount = std::count(pLhs.first.begin(), pLhs.first.end(), '_');
00339 size_t rightCount = std::count(pRhs.first.begin(), pRhs.first.end(), '_');
00340 if (leftCount != rightCount)
00341 {
00342 return leftCount > rightCount;
00343 }
00344 return pLhs.first < pRhs.first;
00345 }
00346 };
00347
00348
00349
00350 #define REGISTER_PLUGIN(moduleNamespace__, pluginname__, className__) \
00351 namespace moduleNamespace__ \
00352 { \
00353 void addFactory(PlugInFactory*); \
00354 class pluginname__##PlugInFactory : public BasicPlugInFactory \
00355 { \
00356 public: \
00357 pluginname__##PlugInFactory(const std::string& name) : BasicPlugInFactory(name) \
00358 { \
00359 moduleNamespace__::addFactory(this); \
00360 } \
00361 virtual ~pluginname__##PlugInFactory() {}; \
00362 PlugIn* createPlugIn(const std::string& name) \
00363 { \
00364 return new className__; \
00365 } \
00366 }; \
00367 static pluginname__##PlugInFactory pluginname__##pluginFactory(#pluginname__); \
00368 }
00369
00370 #define REGISTER_PLUGIN_BASIC(moduleNamespace__, name__) REGISTER_PLUGIN(moduleNamespace__, name__, name__)
00371
00372 #define GENERATE_FACTORY(moduleNamespace__) \
00373 namespace moduleNamespace__ { \
00374 std::vector<std::pair<std::string, PlugInFactory*> >& factories() \
00375 { \
00376 static std::vector<std::pair<std::string, PlugInFactory*> > sFactories; \
00377 return sFactories; \
00378 } \
00379 void addFactory(PlugInFactory* pFactory) \
00380 { \
00381 if (pFactory != NULL) \
00382 { \
00383 std::vector<std::string> names = pFactory->getPlugInNames(); \
00384 for (std::vector<std::string>::iterator nameIter = names.begin(); nameIter != names.end(); ++nameIter) \
00385 { \
00386 factories().push_back(make_pair(*nameIter, pFactory)); \
00387 } \
00388 } \
00389 } \
00390 PlugIn* getPlugIn(unsigned int plugInNumber) \
00391 { \
00392 static bool factoriesSorted = false; \
00393 if (!factoriesSorted) \
00394 { \
00395 factoriesSorted = true; \
00396 FactoryPtrComparator comp; \
00397 std::sort(factories().begin(), factories().end(), comp); \
00398 } \
00399 if (plugInNumber >= factories().size()) \
00400 { \
00401 return NULL; \
00402 } \
00403 const std::pair<std::string, PlugInFactory*>& plugin = factories()[plugInNumber]; \
00404 return plugin.second->createPlugIn(plugin.first); \
00405 } \
00406 }
00407
00408 #define GENERATE_DYNAMIC_FACTORY(moduleNamespace__, dynamicFactoryClass__) \
00409 namespace moduleNamespace__ { \
00410 static dynamicFactoryClass__ sDynamicFactoryInstance__; \
00411 std::vector<std::pair<std::string, PlugInFactory*> >& factories() \
00412 { \
00413 static std::vector<std::pair<std::string, PlugInFactory*> > sFactories; \
00414 return sFactories; \
00415 } \
00416 void addFactory(PlugInFactory* pFactory) \
00417 { \
00418 if (pFactory != NULL) \
00419 { \
00420 std::vector<std::string> names = pFactory->getPlugInNames(); \
00421 for (std::vector<std::string>::iterator nameIter = names.begin(); nameIter != names.end(); ++nameIter) \
00422 { \
00423 factories().push_back(make_pair(*nameIter, pFactory)); \
00424 } \
00425 } \
00426 } \
00427 PlugIn* getPlugIn(unsigned int plugInNumber) \
00428 { \
00429 static bool factoriesSorted = false; \
00430 if (!factoriesSorted) \
00431 { \
00432 factoriesSorted = true; \
00433 DynamicPlugInFactory* pFac = &sDynamicFactoryInstance__; \
00434 addFactory(pFac); \
00435 FactoryPtrComparator comp; \
00436 std::sort(factories().begin(), factories().end(), comp); \
00437 } \
00438 if (plugInNumber >= factories().size()) \
00439 { \
00440 return NULL; \
00441 } \
00442 const std::pair<std::string, PlugInFactory*>& plugin = factories()[plugInNumber]; \
00443 return plugin.second->createPlugIn(plugin.first); \
00444 } \
00445 }
00446
00447 #endif
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 class ModuleManager
00461 {
00462 protected:
00463
00464
00465
00466
00467
00468
00469
00470 ModuleManager();
00471
00472
00473
00474
00475
00476
00477
00478 ~ModuleManager();
00479
00480 public:
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 static ModuleManager* instance();
00493
00494
00495
00496
00497
00498
00499
00500
00501 static char *getName()
00502 {
00503 return (char*)mspName;
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 static char *getVersion()
00515 {
00516 return (char*)mspVersion;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 static char *getDescription()
00528 {
00529 return (char*)mspDescription;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 static unsigned int getTotalPlugIns();
00543
00544 static char *getValidationKey()
00545 {
00546 return (char*)mspValidationKey;
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 void setService( External* address )
00561 {
00562 mpServices = address;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 External* getService()
00579 {
00580 return mpServices;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 PlugIn* getPlugIn( unsigned int plugInNumber );
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 static char *getUniqueId()
00614 {
00615 return const_cast<char*>(mspUniqueId);
00616 }
00617
00618 private:
00619 static const char* mspName;
00620 static const char* mspVersion;
00621 static const char* mspDescription;
00622 static const char* mspValidationKey;
00623 static const char* mspUniqueId;
00624
00625 External* mpServices;
00626
00627 static ModuleManager* mspSingleton;
00628 };
00629
00630
00631 #endif