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 =
';';
152 const char* envVar =
"LD_LIBRARY_PATH";
153 const char sep =
':';
155 char* search_path = ::getenv( envVar );
159 std::string::size_type pos = 0;
160 std::string::size_type newpos = 0;
161 while ( pos != std::string::npos ) {
164 newpos =
path.find( sep, pos );
165 if ( newpos != std::string::npos ) {
166 dirName =
path.substr( pos, newpos - pos );
169 dirName =
path.substr( pos );
174 DIR* dir = opendir( dirName.
c_str() );
176 struct dirent* entry;
177 while ( ( entry = readdir( dir ) ) ) {
180 std::string::size_type extpos =
name.find(
".components" );
181 if ( ( extpos != std::string::npos ) && ( ( extpos + 11 ) ==
name.size() ) ) {
185 stat( fullPath.
c_str(), &buf );
186 if ( !S_ISREG( buf.st_mode ) )
continue;
192 int factoriesCount = 0;
199 if (
line.empty() ||
line[0] ==
'#' )
continue;
201 if (
line.substr( 0, 4 ) ==
"v1::" )
206 auto pos =
line.find(
':' );
207 if ( pos == std::string::npos ) {
214 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 217 if ( fact != old_name ) {
241 auto entry = facts.find(
id );
242 if ( entry == facts.end() ) {
244 entry = facts.emplace(
id,
FactoryInfo(
"unknown", factory,
type, rtype, className, props ) ).first;
247 if ( !entry->second.ptr ) entry->second.ptr = factory;
248 factoryInfoSetHelper( entry->second.type,
type,
"type",
id );
249 factoryInfoSetHelper( entry->second.rtype, rtype,
"return type",
id );
250 factoryInfoSetHelper( entry->second.className, className,
"class",
id );
252 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 255 if (
id != old_name )
256 add( old_name, factory,
type, rtype, className, props ).
properties[
"ReflexName"] =
"true";
258 return entry->second;
264 auto f = facts.find(
id );
265 if ( f != facts.end() ) {
266 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 267 const Properties& props = f->second.properties;
268 if ( props.
find(
"ReflexName" ) != props.
end() )
272 f->second.className +
"' instead" );
274 if ( !f->second.ptr ) {
275 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
276 logger().
warning(
"cannot load " + f->second.library +
" for factory " +
id );
277 char* dlmsg = dlerror();
281 f = facts.find(
id );
283 if ( f->second.type ==
type )
return f->second.ptr;
294 auto f = facts.
find(
id );
295 return ( f != facts.
end() ) ? f->second : unknown;
301 auto f = facts.find(
id );
302 if ( f != facts.end() ) f->second.properties[k] = v;
310 if ( f.second.ptr )
l.insert( f.first );
316 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : "};
320 static auto s_logger = std::make_unique<Logger>();
327 using namespace Details;
329 if ( debugLevel > 1 )
331 else if ( debugLevel > 0 )
338 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.