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