28 #if defined( __GXX_EXPERIMENTAL_CXX0X__ ) || __cplusplus >= 201103L 29 #define REG_SCOPE_LOCK std::lock_guard<std::recursive_mutex> _guard( m_mutex ); 35 #define SINGLETON_LOCK std::lock_guard<std::mutex> _guard(::registrySingletonMutex ); 37 #define REG_SCOPE_LOCK 38 #define SINGLETON_LOCK 48 constexpr
struct is_space_t {
79 }
else if ( dest != value ) {
81 ": " + dest +
" != " + value );
122 namespace PluginService
133 return Registry::instance().get(
id, type );
140 abi::__cxa_demangle(
id.c_str(),
nullptr,
nullptr, &status ), free );
141 if ( !realname )
return id;
142 #if _GLIBCXX_USE_CXX11_ABI 145 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > ?"},
160 Registry::Registry() : m_initialized( false ) {}
167 #if defined( _WIN32 ) 168 const char* envVar =
"PATH";
169 const char sep =
';';
170 #elif defined( __APPLE__ ) 171 const char* envVar =
"DYLD_LIBRARY_PATH";
172 const char sep =
':';
174 const char* envVar =
"LD_LIBRARY_PATH";
175 const char sep =
':';
177 char* search_path = ::getenv( envVar );
181 std::string::size_type pos = 0;
182 std::string::size_type newpos = 0;
183 while ( pos != std::string::npos ) {
186 newpos = path.
find( sep, pos );
187 if ( newpos != std::string::npos ) {
188 dirName = path.
substr( pos, newpos - pos );
191 dirName = path.
substr( pos );
196 DIR* dir = opendir( dirName.
c_str() );
198 struct dirent* entry;
199 while ( ( entry = readdir( dir ) ) ) {
202 std::string::size_type extpos = name.
find(
".components" );
203 if ( ( extpos != std::string::npos ) && ( ( extpos + 11 ) == name.
size() ) ) {
207 stat( fullPath.
c_str(), &buf );
208 if ( !S_ISREG( buf.st_mode ) )
continue;
214 int factoriesCount = 0;
221 if ( line.
empty() || line[0] ==
'#' )
continue;
223 auto pos = line.
find(
':' );
224 if ( pos == std::string::npos ) {
231 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 234 if ( fact != old_name ) {
259 auto entry = facts.find(
id );
260 if ( entry == facts.end() ) {
262 entry = facts.emplace(
id,
FactoryInfo(
"unknown", factory, type, rtype, className, props ) ).first;
265 if ( !entry->second.ptr ) entry->second.ptr = factory;
266 factoryInfoSetHelper( entry->second.type, type,
"type",
id );
267 factoryInfoSetHelper( entry->second.rtype, rtype,
"return type",
id );
268 factoryInfoSetHelper( entry->second.className, className,
"class",
id );
270 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 273 if (
id != old_name )
add( old_name, factory, type, rtype, className, props ).
properties[
"ReflexName"] =
"true";
275 return entry->second;
282 auto f = facts.find(
id );
283 if ( f != facts.end() ) {
284 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 285 const Properties& props = f->second.properties;
286 if ( props.
find(
"ReflexName" ) != props.
end() )
287 logger().
warning(
"requesting factory via old name '" +
id +
"'" 289 f->second.className +
"' instead" );
291 if ( !f->second.ptr ) {
292 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
293 logger().
warning(
"cannot load " + f->second.library +
" for factory " +
id );
294 char* dlmsg = dlerror();
298 f = facts.find(
id );
300 if ( f->second.type == type )
return f->second.ptr;
302 " instead of " +
demangle( type ) );
312 auto f = facts.
find(
id );
313 return ( f != facts.
end() ) ? f->second : unknown;
320 auto f = facts.find(
id );
321 if ( f != facts.end() ) f->second.properties[k] = v;
330 for (
const auto& f : facts ) {
331 if ( f.second.ptr ) l.
insert( f.first );
338 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : "};
339 if ( lvl >=
level() ) {
352 using namespace Details;
354 if ( debugLevel > 1 )
356 else if ( debugLevel > 0 )
364 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.
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
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)