14 #define GAUDI_PLUGIN_SERVICE_V1 39 constexpr
struct is_space_t {
40 bool operator()(
int i )
const {
return std::isspace( i ); }
66 }
else if (
dest != value ) {
68 ": " +
dest +
" != " + value );
74 void operator()(
const char c ) {
83 name.push_back(
'_' );
86 name.push_back(
'r' );
89 name.push_back(
'p' );
106 namespace PluginService {
120 abi::__cxa_demangle(
id.c_str(),
nullptr,
nullptr, &status ), free );
121 if ( !realname )
return id;
122 #if _GLIBCXX_USE_CXX11_ABI 125 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >( (?=>))?"},
134 auto _guard = std::scoped_lock{::registrySingletonMutex};
142 auto _guard = std::scoped_lock{
m_mutex};
145 #if defined( _WIN32 ) 146 const char* envVar =
"PATH";
147 const char sep =
';';
149 const char* envVar =
"LD_LIBRARY_PATH";
150 const char sep =
':';
152 char* search_path = ::getenv( envVar );
156 std::string::size_type pos = 0;
157 std::string::size_type newpos = 0;
158 while ( pos != std::string::npos ) {
161 newpos =
path.find( sep, pos );
162 if ( newpos != std::string::npos ) {
163 dirName =
path.substr( pos, newpos - pos );
166 dirName =
path.substr( pos );
171 DIR* dir = opendir( dirName.
c_str() );
173 struct dirent* entry;
174 while ( ( entry = readdir( dir ) ) ) {
177 std::string::size_type extpos =
name.find(
".components" );
178 if ( ( extpos != std::string::npos ) && ( ( extpos + 11 ) ==
name.size() ) ) {
182 stat( fullPath.
c_str(), &buf );
183 if ( !S_ISREG( buf.st_mode ) )
continue;
189 int factoriesCount = 0;
196 if (
line.empty() ||
line[0] ==
'#' )
continue;
198 if (
line.substr( 0, 4 ) ==
"v1::" )
203 auto pos =
line.find(
':' );
204 if ( pos == std::string::npos ) {
211 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 214 if ( fact != old_name ) {
236 auto _guard = std::scoped_lock{
m_mutex};
238 auto entry = facts.
find(
id );
239 if ( entry == facts.
end() ) {
244 if ( !entry->second.ptr ) entry->second.
ptr = factory;
245 factoryInfoSetHelper( entry->second.type,
type,
"type",
id );
246 factoryInfoSetHelper( entry->second.rtype, rtype,
"return type",
id );
247 factoryInfoSetHelper( entry->second.className, className,
"class",
id );
249 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 252 if (
id != old_name )
253 add( old_name, factory,
type, rtype, className, props ).
properties[
"ReflexName"] =
"true";
255 return entry->second;
259 auto _guard = std::scoped_lock{
m_mutex};
261 auto f = facts.
find(
id );
262 if ( f != facts.
end() ) {
263 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES 264 const Properties& props = f->second.properties;
265 if ( props.
find(
"ReflexName" ) != props.
end() )
269 f->second.className +
"' instead" );
271 if ( !f->second.ptr ) {
272 if ( !dlopen( f->second.library.c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
273 logger().
warning(
"cannot load " + f->second.library +
" for factory " +
id );
274 char* dlmsg = dlerror();
278 f = facts.
find(
id );
280 if ( f->second.type ==
type )
return f->second.
ptr;
288 auto _guard = std::scoped_lock{
m_mutex};
291 auto f = facts.
find(
id );
292 return ( f != facts.
end() ) ? f->second : unknown;
296 auto _guard = std::scoped_lock{
m_mutex};
298 auto f = facts.
find(
id );
304 auto _guard = std::scoped_lock{
m_mutex};
307 if ( f.second.ptr )
l.insert( f.first );
313 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : "};
317 static auto s_logger = std::make_unique<Logger>();
324 using namespace Details;
326 if ( debugLevel > 1 )
328 else if ( debugLevel > 0 )
335 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.
std::recursive_mutex m_mutex
Mutex used to control concurrent access to the internal data.
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.