File indexing completed on 2025-01-18 10:12:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef ROOT_TPluginManager
0013 #define ROOT_TPluginManager
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 #include "TObject.h"
0088 #include "TString.h"
0089 #include "TMethodCall.h"
0090 #include "TVirtualMutex.h"
0091 #include "TInterpreter.h"
0092 #include "TClass.h"
0093
0094 class TEnv;
0095 class TList;
0096 class THashTable;
0097 class TFunction;
0098 class TPluginManager;
0099
0100 #include <atomic>
0101 #include <mutex>
0102
0103 class TPluginHandler : public TObject {
0104
0105 friend class TPluginManager;
0106
0107 private:
0108 using AtomicInt_t = std::atomic<Int_t>;
0109
0110 TString fBase;
0111 TString fRegexp;
0112 TString fClass;
0113 TString fPlugin;
0114 TString fCtor;
0115 TString fOrigin;
0116 TMethodCall *fCallEnv;
0117 TFunction *fMethod;
0118 std::vector<std::string> fArgTupleTypeInfo;
0119 AtomicInt_t fCanCall;
0120 Bool_t fIsMacro;
0121 Bool_t fIsGlobal;
0122 std::once_flag fLoadStatusFlag;
0123 Int_t fLoadStatus;
0124
0125 TPluginHandler() :
0126 fBase(), fRegexp(), fClass(), fPlugin(), fCtor(), fOrigin(),
0127 fCallEnv(nullptr), fMethod(nullptr), fCanCall(0), fIsMacro(kTRUE), fIsGlobal(kTRUE) { }
0128 TPluginHandler(const char *base, const char *regexp,
0129 const char *className, const char *pluginName,
0130 const char *ctor, const char *origin);
0131 TPluginHandler(const TPluginHandler &) = delete;
0132 TPluginHandler& operator=(const TPluginHandler &) = delete;
0133
0134 ~TPluginHandler();
0135
0136 const char *GetBase() const { return fBase; }
0137 const char *GetRegexp() const { return fRegexp; }
0138 const char *GetPlugin() const { return fPlugin; }
0139 const char *GetCtor() const { return fCtor; }
0140 const char *GetOrigin() const { return fOrigin; }
0141
0142 Bool_t CanHandle(const char *base, const char *uri);
0143 void SetupCallEnv();
0144
0145 Bool_t CheckForExecPlugin(Int_t nargs);
0146 void LoadPluginImpl();
0147
0148 bool CheckNameMatch(int iarg, const std::type_info &ti);
0149
0150 template <typename T0>
0151 bool CheckExactMatch(int iarg, const T0&)
0152 {
0153 return CheckNameMatch(iarg, typeid(T0));
0154 }
0155
0156 template <typename T0, typename... T>
0157 bool CheckExactMatch(int iarg, const T0&, const T&... params)
0158 {
0159 if (CheckNameMatch(iarg, typeid(T0)))
0160 return CheckExactMatch(iarg + 1, params...);
0161 else
0162 return false;
0163 }
0164
0165 template <typename... T>
0166 bool ExactArgMatch(const T&... params)
0167 {
0168 constexpr auto nargs = sizeof...(T);
0169 auto name = typeid(std::tuple<T...>).name();
0170 if (!fArgTupleTypeInfo[nargs - 1].empty())
0171 return name == fArgTupleTypeInfo[nargs - 1];
0172
0173 R__LOCKGUARD(gInterpreterMutex);
0174 if (!CheckExactMatch<T...>(0, params...))
0175 return false;
0176 fArgTupleTypeInfo[nargs - 1] = name;
0177 return true;
0178 }
0179
0180 template <typename... T> Longptr_t ExecPluginImpl(const T&... params)
0181 {
0182 constexpr auto nargs = sizeof...(params);
0183 if (!CheckForExecPlugin((Int_t)nargs)) return 0;
0184
0185 Longptr_t ret;
0186
0187
0188 if (ExactArgMatch<T...>(params...)) {
0189 const void *args[nargs] = {¶ms...};
0190
0191
0192 fCallEnv->Execute(nullptr, args, nargs, &ret);
0193
0194 return ret;
0195 }
0196
0197
0198
0199
0200
0201
0202
0203 R__LOCKGUARD(gInterpreterMutex);
0204 fCallEnv->SetParams(params...);
0205
0206 fCallEnv->Execute(ret);
0207
0208 return ret;
0209 }
0210
0211 public:
0212 const char *GetClass() const { return fClass; }
0213 Int_t CheckPlugin() const;
0214 Int_t LoadPlugin();
0215
0216
0217 Longptr_t ExecPluginImpl()
0218 {
0219 if (!CheckForExecPlugin(0))
0220 return 0;
0221
0222 Longptr_t ret;
0223
0224
0225 fCallEnv->Execute(nullptr, nullptr, 0, &ret);
0226
0227 return ret;
0228 }
0229
0230
0231 Longptr_t ExecPlugin(int nargs)
0232 {
0233
0234 if ((gDebug > 1) && (nargs != 0)) {
0235 Warning("ExecPlugin", "Announced number of args different from the real number of argument passed %d vs 0",
0236 nargs);
0237 }
0238
0239 return ExecPluginImpl();
0240 }
0241
0242 template <typename... T> Longptr_t ExecPlugin(int nargs, const T&... params)
0243 {
0244
0245 if ((gDebug > 1) && (nargs != (int)sizeof...(params))) {
0246 Warning("ExecPlugin","Announced number of args different from the real number of argument passed %d vs %lu",
0247 nargs, (unsigned long)sizeof...(params) );
0248 }
0249 return ExecPluginImpl<T...>(params...);
0250 }
0251
0252 void Print(Option_t *opt = "") const override;
0253
0254 ClassDefOverride(TPluginHandler,3)
0255 };
0256
0257
0258 class TPluginManager : public TObject {
0259
0260 private:
0261 TList *fHandlers;
0262 THashTable *fBasesLoaded;
0263 Bool_t fReadingDirs;
0264
0265 TPluginManager(const TPluginManager &) = delete;
0266 TPluginManager& operator=(const TPluginManager &) = delete;
0267 void LoadHandlerMacros(const char *path);
0268
0269 public:
0270 TPluginManager();
0271 ~TPluginManager();
0272
0273 void LoadHandlersFromEnv(TEnv *env);
0274 void LoadHandlersFromPluginDirs(const char *base = nullptr);
0275 void AddHandler(const char *base, const char *regexp,
0276 const char *className, const char *pluginName,
0277 const char *ctor = nullptr, const char *origin = nullptr);
0278 void RemoveHandler(const char *base, const char *regexp = nullptr);
0279
0280 TPluginHandler *FindHandler(const char *base, const char *uri = nullptr);
0281
0282 void Print(Option_t *opt = "") const override;
0283 Int_t WritePluginMacros(const char *dir, const char *plugin = nullptr) const;
0284 Int_t WritePluginRecords(const char *envFile, const char *plugin = nullptr) const;
0285
0286 ClassDefOverride(TPluginManager,1)
0287 };
0288
0289 R__EXTERN TPluginManager *gPluginMgr;
0290
0291 #endif