28 #define REG_SCOPE_LOCK std::lock_guard<std::recursive_mutex> _guard( m_mutex ); 34 #define SINGLETON_LOCK std::lock_guard<std::mutex> _guard(::registrySingletonMutex ); 43 constexpr
struct is_space_t {
74 }
else if ( dest != value ) {
76 ": " + dest +
" != " + value );
117 namespace PluginService
128 return Registry::instance().get(
id, type );
135 abi::__cxa_demangle(
id.c_str(),
nullptr,
nullptr, &status ), free );
136 if ( !realname )
return id;
137 #if _GLIBCXX_USE_CXX11_ABI 140 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >( (?=>))?"},
155 Registry::Registry() : m_initialized( false ) {}
162 #if defined( _WIN32 ) 163 const char* envVar =
"PATH";
164 const char sep =
';';
165 #elif defined( __APPLE__ ) 166 const char* envVar =
"DYLD_LIBRARY_PATH";
167 const char sep =
':';
169 const char* envVar =
"LD_LIBRARY_PATH";
170 const char sep =
':';
172 char* search_path = ::getenv( envVar );
176 std::string::size_type pos = 0;
177 std::string::size_type newpos = 0;
178 while ( pos != std::string::npos ) {
181 newpos = path.
find( sep, pos );
182 if ( newpos != std::string::npos ) {
183 dirName = path.
substr( pos, newpos - pos );
186 dirName = path.
substr( pos );
191 DIR* dir = opendir( dirName.
c_str() );
193 struct dirent* entry;
194 while ( ( entry = readdir( dir ) ) ) {
197 std::string::size_type extpos = name.
find(
".components" );
198 if ( ( extpos != std::string::npos ) && ( ( extpos + 11 ) == name.
size() ) ) {
202 stat( fullPath.
c_str(), &buf );
203 if ( !S_ISREG( buf.st_mode ) )
continue;
209 int factoriesCount = 0;
216 if ( line.
empty() || line[0] ==
'#' )
continue;
218 auto pos = line.
find(
':' );
219 if ( pos == std::string::npos ) {
226 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 229 if ( fact != old_name ) {
254 auto entry = facts.find(
id );
255 if ( entry == facts.end() ) {
257 entry = facts.emplace(
id,
FactoryInfo(
"unknown", factory, type, rtype, className, props ) ).first;
260 if ( !entry->second.ptr ) entry->second.ptr = factory;
261 factoryInfoSetHelper( entry->second.type, type,
"type",
id );
262 factoryInfoSetHelper( entry->second.rtype, rtype,
"return type",
id );
263 factoryInfoSetHelper( entry->second.className, className,
"class",
id );
265 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 268 if (
id != old_name )
add( old_name, factory, type, rtype, className, props ).
properties[
"ReflexName"] =
"true";
270 return entry->second;
277 auto f = facts.find(
id );
278 if ( f != facts.end() ) {
279 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 280 const Properties& props = f->second.properties;
281 if ( props.
find(
"ReflexName" ) != props.
end() )
282 logger().
warning(
"requesting factory via old name '" +
id +
"'" 284 f->second.className +
"' instead" );
286 if ( !f->second.ptr ) {
287 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
288 logger().
warning(
"cannot load " + f->second.library +
" for factory " +
id );
289 char* dlmsg = dlerror();
293 f = facts.find(
id );
295 if ( f->second.type == type )
return f->second.ptr;
297 " instead of " +
demangle( type ) );
307 auto f = facts.
find(
id );
308 return ( f != facts.
end() ) ? f->second : unknown;
315 auto f = facts.find(
id );
316 if ( f != facts.end() ) f->second.properties[k] = v;
325 if ( f.second.ptr ) l.insert( f.first );
332 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : "};
333 if ( lvl >=
level() ) {
346 using namespace Details;
348 if ( debugLevel > 1 )
350 else if ( debugLevel > 0 )
358 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...
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.
std::set< KeyType > loadedFactoryNames() const
Return a list of all the known and loaded factories.
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)