14 #define GAUDI_PLUGIN_SERVICE_V1 29 #define REG_SCOPE_LOCK std::lock_guard<std::recursive_mutex> _guard( m_mutex ); 34 #define SINGLETON_LOCK std::lock_guard<std::mutex> _guard( ::registrySingletonMutex ); 42 constexpr
struct is_space_t {
43 bool operator()(
int i )
const {
return std::isspace( i ); }
69 }
else if (
dest != value ) {
71 ": " +
dest +
" != " + value );
77 void operator()(
const char c ) {
86 name.push_back(
'_' );
89 name.push_back(
'r' );
92 name.push_back(
'p' );
109 namespace PluginService {
123 abi::__cxa_demangle(
id.c_str(),
nullptr,
nullptr, &status ), free );
124 if ( !realname )
return id;
125 #if _GLIBCXX_USE_CXX11_ABI 128 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >( (?=>))?"},
148 #if defined( _WIN32 ) 149 const char* envVar =
"PATH";
150 const char sep =
';';
151 #elif defined( __APPLE__ ) 152 const char* envVar =
"DYLD_LIBRARY_PATH";
153 const char sep =
':';
155 const char* envVar =
"LD_LIBRARY_PATH";
156 const char sep =
':';
158 char* search_path = ::getenv( envVar );
162 std::string::size_type pos = 0;
163 std::string::size_type newpos = 0;
164 while ( pos != std::string::npos ) {
167 newpos =
path.find( sep, pos );
168 if ( newpos != std::string::npos ) {
169 dirName =
path.substr( pos, newpos - pos );
172 dirName =
path.substr( pos );
177 DIR* dir = opendir( dirName.
c_str() );
179 struct dirent* entry;
180 while ( ( entry = readdir( dir ) ) ) {
183 std::string::size_type extpos =
name.find(
".components" );
184 if ( ( extpos != std::string::npos ) && ( ( 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 if (
line.substr( 0, 4 ) ==
"v1::" )
209 auto pos =
line.find(
':' );
210 if ( pos == std::string::npos ) {
217 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 220 if ( fact != old_name ) {
244 auto entry = facts.find(
id );
245 if ( entry == facts.end() ) {
247 entry = facts.emplace(
id,
FactoryInfo(
"unknown", factory,
type, rtype, className, props ) ).first;
250 if ( !entry->second.ptr ) entry->second.ptr = factory;
251 factoryInfoSetHelper( entry->second.type,
type,
"type",
id );
252 factoryInfoSetHelper( entry->second.rtype, rtype,
"return type",
id );
253 factoryInfoSetHelper( entry->second.className, className,
"class",
id );
255 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 258 if (
id != old_name )
259 add( old_name, factory,
type, rtype, className, props ).
properties[
"ReflexName"] =
"true";
261 return entry->second;
267 auto f = facts.find(
id );
268 if ( f != facts.end() ) {
269 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 270 const Properties& props = f->second.properties;
271 if ( props.
find(
"ReflexName" ) != props.
end() )
275 f->second.className +
"' instead" );
277 if ( !f->second.ptr ) {
278 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
279 logger().
warning(
"cannot load " + f->second.library +
" for factory " +
id );
280 char* dlmsg = dlerror();
284 f = facts.find(
id );
286 if ( f->second.type ==
type )
return f->second.ptr;
297 auto f = facts.
find(
id );
298 return ( f != facts.
end() ) ? f->second : unknown;
304 auto f = facts.find(
id );
305 if ( f != facts.end() ) f->second.properties[k] = v;
313 if ( f.second.ptr )
l.insert( f.first );
319 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : "};
323 static auto s_logger = std::make_unique<Logger>();
330 using namespace Details;
332 if ( debugLevel > 1 )
334 else if ( debugLevel > 0 )
341 using namespace Details;
const char * what() const override
const FactoryMap & factories() const
Return the known factories (loading the list if not yet done).
FactoryInfo & add(const I &id, typename F::FuncType ptr)
Add a factory to the database.
GAUDIPS_API void * getCreator(const std::string &id, const std::string &type)
Function used to load a specific factory function.
virtual void report(Level lvl, const std::string &msg)
Simple logging class, just to provide a default implementation.
static Registry & instance()
Retrieve the singleton instance of Registry.
Exception(std::string msg)
FactoryMap m_factories
Internal storage for factories.
GAUDIPS_API void setLogger(Logger *logger)
Set the logger instance to use.
void debug(const std::string &msg)
#define GAUDI_PLUGIN_SERVICE_V1_INLINE
void warning(const std::string &msg)
void * get(const std::string &id, const std::string &type) const
Retrieve the factory for the given id.
GAUDIPS_API Logger & logger()
Return the current logger instance.
T regex_replace(T... args)
In-memory database of the loaded factories.
std::set< KeyType > loadedFactoryNames() const
Return a list of all the known and loaded factories.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
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...
Registry()
Private constructor for the singleton pattern.
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
Header file for std:chrono::duration-based Counters.
bool m_initialized
Flag recording if the registry has been initialized or not.