28 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L 29 #define REG_SCOPE_LOCK \ 30 std::lock_guard<std::recursive_mutex> _guard(m_mutex); 35 #define SINGLETON_LOCK \ 36 std::lock_guard<std::mutex> _guard(::registrySingletonMutex); 38 #define REG_SCOPE_LOCK 39 #define SINGLETON_LOCK 48 constexpr
struct is_space_t {
67 return ltrim(rtrim(s));
80 }
else if (dest != value) {
82 "new factory loaded for '" +
id +
"' with different " 83 + desc +
": " + dest +
" != " + value );
89 void operator() (
const char c) {
115 namespace Gaudi {
namespace PluginService {
125 return Registry::instance().get(
id, type);
132 if (!realname)
return id;
133 #if _GLIBCXX_USE_CXX11_ABI 135 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > ?"},
151 Registry::Registry(): m_initialized(false) {}
158 const char* envVar =
"PATH";
159 const char sep =
';';
161 const char* envVar =
"LD_LIBRARY_PATH";
162 const char sep =
':';
164 char *search_path = ::getenv(envVar);
168 std::string::size_type pos = 0;
169 std::string::size_type newpos = 0;
170 while (pos != std::string::npos) {
173 newpos = path.
find(sep, pos);
174 if (newpos != std::string::npos) {
175 dirName = path.
substr(pos, newpos - pos);
178 dirName = path.
substr(pos);
183 DIR *dir = opendir(dirName.
c_str());
185 struct dirent * entry;
186 while ((entry = readdir(dir))) {
189 std::string::size_type extpos = name.
find(
".components");
190 if ((extpos != std::string::npos) &&
191 ((extpos+11) == name.
size())) {
195 stat(fullPath.
c_str(), &buf);
196 if (!S_ISREG(buf.st_mode))
continue;
202 int factoriesCount = 0;
209 if (line.
empty() || line[0] ==
'#')
continue;
211 auto pos = line.
find(
':');
212 if (pos == std::string::npos) {
221 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 224 if (fact != old_name) {
251 auto entry = facts.find(
id);
252 if (entry == facts.end())
255 entry = facts.emplace(
id,
FactoryInfo(
"unknown", factory,
256 type, rtype, className, props) ).first;
259 if (!entry->second.ptr) entry->second.ptr = factory;
260 factoryInfoSetHelper(entry->second.type, type,
"type",
id);
261 factoryInfoSetHelper(entry->second.rtype, rtype,
"return type",
id);
262 factoryInfoSetHelper(entry->second.className, className,
"class",
id);
264 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 268 add(old_name, factory, type, rtype, className, props)
271 return entry->second;
277 auto f = facts.find(
id);
278 if (f != facts.end())
280 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 281 const Properties& props = f->second.properties;
282 if (props.
find(
"ReflexName") != props.
end())
283 logger().
warning(
"requesting factory via old name '" +
id +
"'" 284 "use '" + f->second.className +
"' instead");
286 if (!f->second.ptr) {
287 if (!dlopen(f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL)) {
289 " for factory " +
id);
290 char *dlmsg = dlerror();
296 if (f->second.type == type)
return f->second.ptr;
297 logger().
warning(
"found factory " +
id +
", but of wrong type: " +
307 auto f = facts.
find(
id);
308 return (f != facts.
end()) ? f->second : unknown;
317 auto f = facts.find(
id);
318 if (f != facts.end()) f->second.properties[k] = v;
326 for (
const auto& f : facts )
328 if (f.second.ptr) l.
insert(f.first);
334 static const char* levels[] = {
"DEBUG : ",
338 if (lvl >=
level()) {
350 using namespace Details;
354 else if (debugLevel > 0)
360 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.)
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.
T regex_replace(T...args)
std::string demangle(const std::string &id)
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
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)
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Function used to load a specific factory function.
In-memory database of the loaded factories.
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.
const char * what() const override
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)