27 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
28 #define REG_SCOPE_LOCK \
29 std::lock_guard<std::recursive_mutex> _guard(m_mutex);
34 #define SINGLETON_LOCK \
35 std::lock_guard<std::mutex> _guard(::registrySingletonMutex);
37 #define REG_SCOPE_LOCK
38 #define SINGLETON_LOCK
47 constexpr
struct is_space_t {
66 return ltrim(rtrim(s));
79 }
else if (dest != value) {
81 "new factory loaded for '" +
id +
"' with different "
82 + desc +
": " + dest +
" != " + value );
88 void operator() (
const char c) {
114 namespace Gaudi {
namespace PluginService {
131 if (!realname)
return id;
151 const char* envVar =
"PATH";
152 const char sep =
';';
154 const char* envVar =
"LD_LIBRARY_PATH";
155 const char sep =
':';
157 char *search_path = ::getenv(envVar);
161 std::string::size_type pos = 0;
162 std::string::size_type newpos = 0;
163 while (pos != std::string::npos) {
166 newpos = path.
find(sep, pos);
167 if (newpos != std::string::npos) {
168 dirName = path.
substr(pos, newpos - pos);
171 dirName = path.
substr(pos);
176 DIR *dir = opendir(dirName.
c_str());
178 struct dirent * entry;
179 while ((entry = readdir(dir))) {
182 std::string::size_type extpos = name.
find(
".components");
183 if ((extpos != std::string::npos) &&
184 ((extpos+11) == name.
size())) {
188 stat(fullPath.
c_str(), &buf);
189 if (!S_ISREG(buf.st_mode))
continue;
195 int factoriesCount = 0;
202 if (line.
empty() || line[0] ==
'#')
continue;
204 auto pos = line.
find(
':');
205 if (pos == std::string::npos) {
214 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
217 if (fact != old_name) {
244 auto entry = facts.find(
id);
245 if (entry == facts.end())
248 entry = facts.emplace(
id,
FactoryInfo(
"unknown", factory,
249 type, rtype, className, props) ).first;
252 if (!entry->second.ptr) entry->second.ptr = factory;
253 factoryInfoSetHelper(entry->second.type, type,
"type",
id);
254 factoryInfoSetHelper(entry->second.rtype, rtype,
"return type",
id);
255 factoryInfoSetHelper(entry->second.className, className,
"class",
id);
257 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
261 add(old_name, factory, type, rtype, className, props)
264 return entry->second;
270 auto f = facts.find(
id);
271 if (f != facts.end())
273 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
274 const Properties& props = f->second.properties;
275 if (props.
find(
"ReflexName") != props.
end())
276 logger().
warning(
"requesting factory via old name '" +
id +
"'"
277 "use '" + f->second.className +
"' instead");
279 if (!f->second.ptr) {
280 if (!dlopen(f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL)) {
282 " for factory " +
id);
283 char *dlmsg = dlerror();
289 if (f->second.type == type)
return f->second.ptr;
290 logger().
warning(
"found factory " +
id +
", but of wrong type: " +
300 auto f = facts.
find(
id);
301 return (f != facts.
end()) ? f->second : unknown;
310 auto f = facts.find(
id);
311 if (f != facts.end()) f->second.properties[k] = v;
319 for (
const auto& f : facts )
321 if (f.second.ptr) l.
insert(f.first);
327 static const char* levels[] = {
"DEBUG : ",
331 if (lvl >=
level()) {
343 using namespace Details;
347 else if (debugLevel > 0)
353 using namespace Details;
const FactoryInfo & getInfo(const std::string &id) const
Retrieve the FactoryInfo object for an id.
Registry & addProperty(const std::string &id, const std::string &k, const std::string &v)
Add a property to an already existing FactoryInfo object (via its id.)
Registry()
Private constructor for the singleton pattern.
void initialize()
Initialize the registry loading the list of factories from the .component files in the library search...
std::set< KeyType > loadedFactories() const
Return a list of all the known and loaded factories.
GAUDIPS_API Logger & logger()
Return the current logger instance.
Simple logging class, just to provide a default implementation.
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
void * get(const std::string &id, const std::string &type) const
Retrieve the factory for the given id.
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
Exception(std::string msg)
const FactoryMap & factories() const
Return the known factories (loading the list if not yet done).
virtual void report(Level lvl, const std::string &msg)
void warning(const std::string &msg)
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Function used to load a specific factory function.
static Registry & instance()
Retrieve the singleton instance of Registry.
In-memory database of the loaded factories.
virtual const char * what() const
FactoryInfo & add(const I &id, typename F::FuncType ptr)
Add a factory to the database.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
GAUDIPS_API void setLogger(Logger *logger)
Set the logger instance to use.
FactoryMap m_factories
Internal storage for factories.
Helper functions to set/get the application return code.
bool m_initialized
Flag recording if the registry has been initialized or not.
void debug(const std::string &msg)