File indexing completed on 2026-07-04 07:51:06
0001 #ifndef GAUDIPLUGINSERVICE_GAUDI_DETAILS_PLUGINSERVICEDETAILSV2_H
0002 #define GAUDIPLUGINSERVICE_GAUDI_DETAILS_PLUGINSERVICEDETAILSV2_H
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "Gaudi/Details/PluginServiceCommon.h"
0017
0018 #include <any>
0019
0020 #include <functional>
0021 #include <map>
0022 #include <memory>
0023 #include <mutex>
0024 #include <set>
0025 #include <sstream>
0026 #include <string>
0027 #include <typeinfo>
0028 #include <utility>
0029
0030 namespace Gaudi {
0031 namespace PluginService {
0032 GAUDI_PLUGIN_SERVICE_V2_INLINE namespace v2 {
0033
0034 template <typename>
0035 struct Factory;
0036
0037
0038
0039 namespace Details {
0040 template <typename>
0041 struct Traits;
0042
0043 template <typename R, typename... Args>
0044 struct Traits<R( Args... )> {
0045 using ReturnType = std::unique_ptr<std::remove_pointer_t<R>>;
0046 using FactoryType = std::function<ReturnType( Args... )>;
0047 };
0048
0049
0050
0051 GAUDIPS_API
0052 std::string demangle( const std::type_info& id );
0053
0054
0055 template <typename T>
0056 inline std::string demangle() {
0057 return demangle( typeid( T ) );
0058 }
0059
0060
0061 template <typename ID>
0062 inline std::string stringify_id( const ID& id ) {
0063 std::ostringstream o;
0064 o << id;
0065 return o.str();
0066 }
0067
0068 template <>
0069 inline std::string stringify_id<std::string>( const std::string& id ) {
0070 return id;
0071 }
0072
0073
0074 void reportBadAnyCast( const std::type_info& factory_type, const std::string& id );
0075
0076
0077 class GAUDIPS_API Logger {
0078 public:
0079 enum Level { Debug = 0, Info = 1, Warning = 2, Error = 3 };
0080 Logger( Level level = Warning ) : m_level( level ) {}
0081 virtual ~Logger() {}
0082 inline Level level() const { return m_level; }
0083 inline void setLevel( Level level ) { m_level = level; }
0084 inline void info( const std::string& msg ) { report( Info, msg ); }
0085 inline void debug( const std::string& msg ) { report( Debug, msg ); }
0086 inline void warning( const std::string& msg ) { report( Warning, msg ); }
0087 inline void error( const std::string& msg ) { report( Error, msg ); }
0088
0089 private:
0090 virtual void report( Level lvl, const std::string& msg );
0091 Level m_level;
0092 };
0093
0094
0095 GAUDIPS_API Logger& logger();
0096
0097
0098 GAUDIPS_API void setLogger( Logger* logger );
0099
0100
0101 class GAUDIPS_API Registry {
0102 public:
0103 using KeyType = std::string;
0104
0105
0106 using Properties = std::map<KeyType, std::string>;
0107
0108 struct FactoryInfo {
0109 std::string library;
0110 std::any factory{};
0111 Properties properties{};
0112
0113 inline bool is_set() const { return factory.has_value(); }
0114 Properties::mapped_type getprop( const Properties::key_type& name ) const;
0115 };
0116
0117
0118 using FactoryMap = std::map<KeyType, FactoryInfo>;
0119
0120
0121 template <typename F>
0122 F get( const KeyType& id ) {
0123 const FactoryInfo& info = Registry::instance().getInfo( id, true );
0124 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
0125 if ( !info.getprop( "ReflexName" ).empty() ) {
0126 const std::string real_name = info.getprop( "ClassName" );
0127 logger().warning( "requesting factory via old name '" + id + "' use '" +
0128 ( real_name.empty() ? "<undefined>" : real_name ) + "' instead" );
0129 }
0130 #endif
0131 return std::any_cast<F>( info.factory );
0132 }
0133
0134
0135 static Registry& instance();
0136
0137
0138 FactoryInfo& add( const KeyType& id, FactoryInfo info );
0139
0140
0141 const FactoryInfo& getInfo( const KeyType& id, const bool load = false ) const;
0142
0143
0144 Registry& addProperty( const KeyType& id, const KeyType& k, const std::string& v );
0145
0146
0147 std::set<KeyType> loadedFactoryNames() const;
0148
0149
0150
0151
0152
0153
0154 const FactoryMap& factories() const;
0155
0156 private:
0157
0158 Registry();
0159
0160
0161 Registry( const Registry& ) = delete;
0162
0163
0164 FactoryMap& factories();
0165
0166
0167
0168 void initialize();
0169
0170
0171 mutable std::once_flag m_initialized;
0172
0173
0174 FactoryMap m_factories;
0175
0176
0177 mutable std::recursive_mutex m_mutex;
0178 };
0179
0180
0181
0182
0183
0184 template <typename, typename>
0185 struct DefaultFactory;
0186 template <typename T, typename R, typename... Args>
0187 struct DefaultFactory<T, Factory<R( Args... )>> {
0188 inline typename Factory<R( Args... )>::ReturnType operator()( Args... args ) {
0189 return std::make_unique<T>( std::move( args )... );
0190 }
0191 };
0192
0193
0194
0195
0196 std::string getDSONameFor( void* fptr );
0197 }
0198
0199
0200 GAUDIPS_API void SetDebug( int debugLevel );
0201
0202 GAUDIPS_API int Debug();
0203 }
0204 }
0205 }
0206
0207 #define _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME_TOKEN( serial ) _register_##serial
0208 #define _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME( serial ) \
0209 _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME_TOKEN( serial )
0210 #define _PS_V2_INTERNAL_FACTORY_REGISTER_CNAME _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME( __LINE__ )
0211
0212 #endif