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