DD4hep - The AIDA detector description toolkit for high energy physics experiments
DD4hep  Rev:Unversioneddirectory
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Plugins.cpp
Go to the documentation of this file.
1 // $Id: $
2 //==========================================================================
3 // AIDA Detector description implementation for LCD
4 //--------------------------------------------------------------------------
5 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
6 // All rights reserved.
7 //
8 // For the licensing terms see $DD4hepINSTALL/LICENSE.
9 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
10 //
11 // Author : M.Frank
12 //
13 //==========================================================================
14 
15 // Framework include files
16 #include "DD4hep/Plugins.h"
17 #if defined(DD4HEP_ROOT_VERSION_5)
18 #include "DD4hep/Plugins.inl"
19 #endif
20 #include <cstdlib>
21 
22 using namespace std;
23 using namespace DD4hep;
24 
25 namespace {
26  inline int* s_debug_value() {
27  static int s_debug_value = ::getenv("DD4HEP_TRACE") == 0 ? 0 : 1;
28  return &s_debug_value;
29  }
30 }
31 
32 bool PluginService::debug() {
33  return *s_debug_value() ? true : false;
34 }
35 
36 bool PluginService::setDebug(bool new_value) {
37  int *ptr = s_debug_value();
38  bool old_value = *ptr;
39  *ptr = new_value ? 1 : 0;
40  return old_value;
41 }
42 
43 #if !defined(DD4HEP_PARSERS_NO_ROOT) && DD4HEP_ROOT_VERSION_5
44 
46 PluginDebug::PluginDebug(int dbg)
47  : m_debug(0) {
48  m_debug = ROOT::Reflex::PluginService::Debug();
49  ROOT::Reflex::PluginService::SetDebug(dbg);
50 }
51 
54  ROOT::Reflex::PluginService::SetDebug (m_debug);
55 }
56 
58 string PluginDebug::missingFactory(const string& name) const {
59  ROOT::Reflex::Scope factories = ROOT::Reflex::Scope::ByName(PLUGINSVC_FACTORY_NS);
60  string factoryname = ROOT::Reflex::PluginService::FactoryName(name);
61  string msg = "\t\tNo factory with name " + factoryname + " for type " + name + " found.\n"
62  "\t\tPlease check library load path and/or plugin factory name.";
63  return msg;
64 }
65 
67 void* PluginService::getCreator(const std::string&, const std::type_info&) { return 0; }
68 void PluginService::addFactory(const std::string&, void*, const std::type_info&, const std::type_info&) {}
69 
70 #else // ROOT 6 or no ROOT at all
71 #include "DD4hep/Printout.h"
72 #if !defined(DD4HEP_PARSERS_NO_ROOT)
73 #include "TSystem.h"
74 #else
75 #include <dlfcn.h>
76 #endif
77 #include <cstring>
78 
79 namespace {
80  struct PluginInterface {
81  int (*getDebug)();
82  int (*setDebug)(int new_value);
83  void* (*create)(const char* identifier, const char* signature);
84  void (*add)(const char* identifier,
85  void* creator_stub,
86  const char* signature,
87  const char* return_type);
88  PluginInterface();
89  static PluginInterface& instance() {
90  static PluginInterface s_instance;
91  return s_instance;
92  }
93  };
94 
95  template <typename T>
96  static inline T get_func(void* handle, const char* plugin, const char* entry) {
97 #if !defined(DD4HEP_PARSERS_NO_ROOT)
98  PluginService::FuncPointer<Func_t> fun(gSystem->DynFindSymbol(plugin,entry));
99  PluginService::FuncPointer<T> fp(fun.fptr.ptr);
100  if ( handle ) {}
101 #else
102  PluginService::FuncPointer<T> fp(::dlsym(handle, entry));
103  if ( !fp.fptr.ptr ) fp.fptr.ptr = ::dlsym(0, entry);
104 #endif
105  if ( 0 == fp.fptr.ptr ) {
106  string err = "DD4hep:PluginService: Failed to access symbol "
107  "\""+string(entry)+"\" in plugin library "+string(plugin)+
108  " ["+string(::strerror(errno))+"]";
109  throw runtime_error(err);
110  }
111  return fp.fptr.fcn;
112  }
113 
114  PluginInterface::PluginInterface() : getDebug(0), setDebug(0), create(0), add(0) {
115  void* handle = 0;
116  const char* plugin_name = ::getenv("DD4HEP_PLUGINMGR");
117  if ( 0 == plugin_name ) {
118  plugin_name = "libDD4hepGaudiPluginMgr";
119  }
120 #if !defined(DD4HEP_PARSERS_NO_ROOT)
121  gSystem->Load(plugin_name);
122 #else
123  handle = ::dlopen(plugin_name, RTLD_LAZY | RTLD_GLOBAL);
124 #endif
125  getDebug = get_func< int (*) ()>(handle, plugin_name,"dd4hep_pluginmgr_getdebug");
126  setDebug = get_func< int (*) (int)>(handle, plugin_name,"dd4hep_pluginmgr_getdebug");
127  create = get_func< void* (*) (const char*,
128  const char*)>(handle, plugin_name,"dd4hep_pluginmgr_create");
129  add = get_func< void (*) (const char* identifier,
130  void* creator_stub,
131  const char* signature,
132  const char* return_type)>(handle, plugin_name,"dd4hep_pluginmgr_add_factory");
133  }
134 }
135 
137 PluginDebug::PluginDebug(int dbg) : m_debug(0) {
138  m_debug = PluginInterface::instance().setDebug(dbg);
139 }
140 
143  PluginInterface::instance().setDebug(m_debug);
144 }
145 
147 string PluginDebug::missingFactory(const string& name) const {
148  string factoryname = "Create("+name+")";
149  string msg = "\t\tNo factory with name " + factoryname + " for type " + name + " found.\n"
150  "\t\tPlease check library load path and/or plugin factory name.";
151  return msg;
152 }
153 
154 void* PluginService::getCreator(const std::string& id, const std::type_info& info) {
155  return PluginInterface::instance().create(id.c_str(), info.name());
156 }
157 
158 void PluginService::addFactory(const std::string& id, stub_t stub,
159  const std::type_info& signature_type,
160  const std::type_info& return_type)
161 {
162  if ( PluginService::debug() ) {
163  printout(INFO,"PluginService","+++ Declared factory[%s] with signature %s type:%s.",
164  id.c_str(),signature_type.name(),return_type.name());
165  }
166  PluginInterface::instance().add(id.c_str(),stub,signature_type.name(),return_type.name());
167 }
168 #endif
169 
170 #if !defined(DD4HEP_PARSERS_NO_ROOT)
171 #include "DD4hep/LCDD.h"
172 #include "DD4hep/Handle.h"
173 #include "DD4hep/GeoHandler.h"
174 #include "XML/XMLElements.h"
176 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(NamedObject*, (Geometry::LCDD*,XML::Handle_t*))
177 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(NamedObject*, (Geometry::LCDD*))
178 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*,XML::Handle_t*))
179 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*,XML::Handle_t const*))
180 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*, int, char**))
181 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*))
182 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(long, (Geometry::LCDD*, const Geometry::GeoHandler*, const std::map<std::string,std::string>*))
184 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(void*, (const char*))
185 DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(void*, (Geometry::LCDD*,int,char**))
186 #endif
std::string missingFactory(const std::string &name) const
Helper to check factory existence.
Definition: Plugins.cpp:147
#define DD4HEP_IMPLEMENT_PLUGIN_REGISTRY(X, Y)
Definition: Plugins.h:173
static bool debug()
Definition: Plugins.cpp:32
static bool setDebug(bool new_value)
Definition: Plugins.cpp:36
Implementation of a named object.
Definition: NamedObject.h:31
~PluginDebug()
Default destructor.
Definition: Plugins.cpp:142
static void * getCreator(const std::string &id, const std::type_info &info)
Definition: Plugins.cpp:154
The base class for all DD4hep geometry crawlers.
Definition: GeoHandler.h:102
static void addFactory(const std::string &id, stub_t func, const std::type_info &signature_type, const std::type_info &return_type)
Definition: Plugins.cpp:158
PluginDebug(int dbg=2)
Default constructor.
Definition: Plugins.cpp:137
Handle< NamedObject > Ref_t
Default Ref_t definition describing named objects.
Definition: Handle.h:176
The main interface to the DD4hep detector description package.
Definition: LCDD.h:82
Class to easily access the properties of single XmlElements.
Definition: XMLElements.h:361
void handle(const O *o, const C &c, F pmf)
int printout(PrintLevel severity, const char *src, const char *fmt,...)
Calls the display action with a given severity level.
Definition: Printout.cpp:111