File indexing completed on 2025-01-18 10:06:28
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef Pythia8_Plugins_H
0009 #define Pythia8_Plugins_H
0010
0011 #include "Pythia8/Pythia.h"
0012
0013
0014 #if defined (__GNUC__) && ((__GNUC__ + 0) < 5)
0015 #pragma GCC system_header
0016 #endif
0017
0018 namespace Pythia8 {
0019
0020
0021
0022
0023
0024 string demangle(string name);
0025
0026
0027
0028
0029
0030 string type_plugin(string libName, string className,
0031 Logger* loggerPtr = nullptr);
0032
0033
0034
0035
0036
0037 shared_ptr<void> dlopen_plugin(string libName, Logger* loggerPtr);
0038
0039
0040
0041
0042
0043 template <typename T> function<T> dlsym_plugin(void* libPtr, string symbol) {
0044 return (T*)dlsym(libPtr, symbol.c_str());}
0045
0046 template <typename T> function<T> dlsym_plugin(shared_ptr<void> libPtr,
0047 string symbol) {
0048 return (T*)dlsym( static_cast<void*>(libPtr.get()), symbol.c_str());}
0049
0050
0051
0052
0053
0054 template <typename T> shared_ptr<T> make_plugin(
0055 string libName, string className, Pythia* pythiaPtr,
0056 Settings* settingsPtr, Logger* loggerPtr) {
0057
0058
0059 if (loggerPtr == nullptr && pythiaPtr != nullptr)
0060 loggerPtr = &pythiaPtr->logger;
0061 if (settingsPtr == nullptr && pythiaPtr != nullptr)
0062 settingsPtr = &pythiaPtr->settings;
0063
0064
0065 shared_ptr<void> libPtr = dlopen_plugin(libName, loggerPtr);
0066 if (libPtr == nullptr) return shared_ptr<T>(nullptr);
0067
0068
0069 string objType = type_plugin(libName, className, loggerPtr);
0070 if (objType != typeid(T).name()) {
0071 string msg = "class " + className + " from library " + libName +
0072 " must be loaded as type " + demangle(objType);
0073 if (loggerPtr != nullptr) loggerPtr->errorMsg("make_plugin", msg);
0074 else cout << msg << "\n";
0075 return shared_ptr<T>(nullptr);
0076 }
0077
0078
0079 for (string ptr : {"PYTHIA", "SETTINGS", "LOGGER"}) {
0080 auto ptrsObject =
0081 dlsym_plugin<bool()>(libPtr, "REQUIRE_" + ptr + "_" + className);
0082 if (dlerror() != nullptr) continue;
0083 if (!ptrsObject()) continue;
0084 if (ptr == "PYTHIA" && pythiaPtr != nullptr) continue;
0085 if (ptr == "SETTINGS" && settingsPtr != nullptr) continue;
0086 if (ptr == "LOGGER" && loggerPtr != nullptr) continue;
0087 string msg = "class " + className + " requires a " + ptr + " pointer";
0088 if (loggerPtr != nullptr) loggerPtr->errorMsg("make_plugin", msg);
0089 else cout << msg << "\n";
0090 return shared_ptr<T>(nullptr);
0091 }
0092
0093
0094 auto newObject =
0095 dlsym_plugin<T*(Pythia*, Settings*, Logger*)>(libPtr, "NEW_" + className);
0096 const char* error = dlerror();
0097 if (error != nullptr) {
0098 string msg = "class " + className + " not available from library " +
0099 libName;
0100 if (loggerPtr != nullptr) loggerPtr->errorMsg("make_plugin", msg);
0101 else cout << msg << "\n";
0102 return shared_ptr<T>(nullptr);
0103 }
0104
0105
0106 return shared_ptr<T>(
0107 newObject(pythiaPtr, settingsPtr, loggerPtr),
0108
0109 [libPtr, className](T* objectPtr) {
0110
0111
0112 auto deleteObject =
0113 dlsym_plugin<void(T*)>(libPtr, "DELETE_" + className);
0114 if (dlerror() == nullptr && deleteObject != nullptr)
0115 deleteObject(objectPtr);});
0116
0117 }
0118
0119
0120
0121
0122
0123 template <typename T> shared_ptr<T> make_plugin(
0124 string libName, string className) {return make_plugin<T>(
0125 libName, className, nullptr, nullptr, nullptr);}
0126
0127
0128
0129
0130 template <typename T> shared_ptr<T> make_plugin(
0131 string libName, string className, Pythia* pythiaPtr) {
0132 return make_plugin<T>(
0133 libName, className, pythiaPtr, nullptr, nullptr);}
0134
0135
0136
0137
0138
0139 template <typename T> shared_ptr<T> make_plugin(
0140 string libName, string className, Pythia* pythiaPtr,
0141 const vector<string>& cmnds) {
0142 pythiaPtr->settings.registerPluginLibrary(libName);
0143 for (string cmnd : cmnds) pythiaPtr->readString(cmnd);
0144 return make_plugin<T>(libName, className, pythiaPtr);
0145 }
0146
0147
0148
0149
0150
0151 template <typename T> shared_ptr<T> make_plugin(
0152 string libName, string className, Pythia* pythiaPtr,
0153 string fileName, int subrun = SUBRUNDEFAULT) {
0154 pythiaPtr->settings.registerPluginLibrary(libName);
0155 if (fileName != "") pythiaPtr->readFile(fileName, subrun);
0156 return make_plugin<T>(libName, className, pythiaPtr);
0157 }
0158
0159
0160
0161
0162
0163 #define PYTHIA8_PLUGIN_CLASS(BASE, CLASS, PYTHIA, SETTINGS, LOGGER) \
0164 extern "C" { \
0165 bool REQUIRE_PYTHIA_##CLASS() {return PYTHIA;} \
0166 bool REQUIRE_SETTINGS_##CLASS() {return SETTINGS;} \
0167 bool REQUIRE_LOGGER_##CLASS() {return LOGGER;} \
0168 const char* TYPE_##CLASS() {return typeid(BASE).name();} \
0169 CLASS* NEW_##CLASS(Pythia* pythiaPtr, Settings* settingsPtr, \
0170 Logger* loggerPtr) { \
0171 return new CLASS(pythiaPtr, settingsPtr, loggerPtr);} \
0172 void DELETE_##CLASS(CLASS* ptr) {delete ptr;}}
0173
0174
0175
0176
0177
0178 #define PYTHIA8_PLUGIN_SETTINGS(METHOD) \
0179 extern "C" { \
0180 void REGISTER_SETTINGS(Settings* settingsPtr) {METHOD(settingsPtr);}}
0181
0182
0183
0184
0185
0186 #define PYTHIA8_PLUGIN_XML(INDEX) \
0187 extern "C" {const char* RETURN_XML() {return INDEX;}}
0188
0189
0190
0191
0192
0193 #define PYTHIA8_PLUGIN_VERSIONS(...) \
0194 extern "C" { \
0195 bool CHECK_COMPATIBLE_VERSION(int ver) {set<int> vers = {__VA_ARGS__}; \
0196 return vers.find(ver) != vers.end();} \
0197 bool CHECK_COMPILED_VERSION(int ver) { \
0198 return ver == PYTHIA_VERSION_INTEGER;}}
0199
0200
0201
0202 }
0203
0204 #endif