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_V1_H_
0012 #define _GAUDI_PLUGIN_SERVICE_DETAILS_V1_H_
0013
0014
0015
0016 #include "Gaudi/Details/PluginServiceCommon.h"
0017
0018 #include <map>
0019 #include <set>
0020 #include <sstream>
0021 #include <string>
0022 #include <typeinfo>
0023 #include <utility>
0024
0025 #include <mutex>
0026
0027 namespace Gaudi {
0028 namespace PluginService {
0029 GAUDI_PLUGIN_SERVICE_V1_INLINE namespace v1 {
0030 namespace Details {
0031
0032
0033
0034
0035 template <class T>
0036 class Factory {
0037 public:
0038 template <typename S, typename... Args>
0039 static typename S::ReturnType create( Args&&... args ) {
0040 return new T( std::forward<Args>( args )... );
0041 }
0042 };
0043
0044
0045
0046 GAUDIPS_API
0047 void* getCreator( const std::string& id, const std::string& type );
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 template <typename F>
0062 inline F getCreator( const std::string& id ) {
0063 union {
0064 void* src;
0065 F dst;
0066 } p2p;
0067 p2p.src = getCreator( id, typeid( F ).name() );
0068 return p2p.dst;
0069 }
0070
0071
0072
0073 GAUDIPS_API
0074 std::string demangle( const std::type_info& id );
0075
0076
0077 template <typename T>
0078 inline std::string demangle() {
0079 return demangle( typeid( T ) );
0080 }
0081
0082
0083 class GAUDIPS_API Registry {
0084 public:
0085 typedef std::string KeyType;
0086
0087
0088 typedef std::map<KeyType, std::string> Properties;
0089
0090 struct FactoryInfo {
0091 FactoryInfo( std::string lib, void* p = nullptr, std::string t = "", std::string rt = "",
0092 std::string cn = "", Properties props = Properties() )
0093 : library( std::move( lib ) )
0094 , ptr( p )
0095 , type( std::move( t ) )
0096 , rtype( std::move( rt ) )
0097 , className( std::move( cn ) )
0098 , properties( std::move( props ) ) {}
0099
0100 std::string library;
0101 void* ptr;
0102 std::string type;
0103 std::string rtype;
0104 std::string className;
0105 Properties properties;
0106
0107 FactoryInfo& addProperty( const KeyType& k, std::string v ) {
0108 properties[k] = std::move( v );
0109 return *this;
0110 }
0111 };
0112
0113
0114 typedef std::map<KeyType, FactoryInfo> FactoryMap;
0115
0116
0117 static Registry& instance();
0118
0119
0120 template <typename F, typename T, typename I>
0121 inline FactoryInfo& add( const I& id, typename F::FuncType ptr ) {
0122 union {
0123 typename F::FuncType src;
0124 void* dst;
0125 } p2p;
0126 p2p.src = ptr;
0127 std::ostringstream o;
0128 o << id;
0129 return add( o.str(), p2p.dst, typeid( typename F::FuncType ).name(),
0130 typeid( typename F::ReturnType ).name(), demangle<T>() );
0131 }
0132
0133
0134 void* get( const std::string& id, const std::string& type ) const;
0135
0136
0137 const FactoryInfo& getInfo( const std::string& id ) const;
0138
0139
0140 Registry& addProperty( const std::string& id, const std::string& k, const std::string& v );
0141
0142
0143 std::set<KeyType> loadedFactoryNames() const;
0144
0145
0146 inline const FactoryMap& factories() const {
0147 if ( !m_initialized ) const_cast<Registry*>( this )->initialize();
0148 return m_factories;
0149 }
0150
0151 private:
0152
0153
0154
0155
0156 Registry();
0157
0158
0159 Registry( const Registry& ) : m_initialized( false ) {}
0160
0161
0162 FactoryInfo& add( const std::string& id, void* factory, const std::string& type, const std::string& rtype,
0163 const std::string& className, const Properties& props = Properties() );
0164
0165
0166 inline FactoryMap& factories() {
0167 if ( !m_initialized ) initialize();
0168 return m_factories;
0169 }
0170
0171
0172
0173 void initialize();
0174
0175
0176 bool m_initialized;
0177
0178
0179 FactoryMap m_factories;
0180
0181
0182 mutable std::recursive_mutex m_mutex;
0183 };
0184
0185
0186 class GAUDIPS_API Logger {
0187 public:
0188 enum Level { Debug = 0, Info = 1, Warning = 2, Error = 3 };
0189 Logger( Level level = Warning ) : m_level( level ) {}
0190 virtual ~Logger() {}
0191 inline Level level() const { return m_level; }
0192 inline void setLevel( Level level ) { m_level = level; }
0193 inline void info( const std::string& msg ) { report( Info, msg ); }
0194 inline void debug( const std::string& msg ) { report( Debug, msg ); }
0195 inline void warning( const std::string& msg ) { report( Warning, msg ); }
0196 inline void error( const std::string& msg ) { report( Error, msg ); }
0197
0198 private:
0199 virtual void report( Level lvl, const std::string& msg );
0200 Level m_level;
0201 };
0202
0203
0204 GAUDIPS_API Logger& logger();
0205
0206
0207 GAUDIPS_API void setLogger( Logger* logger );
0208 }
0209
0210
0211 GAUDIPS_API void SetDebug( int debugLevel );
0212
0213 GAUDIPS_API int Debug();
0214 }
0215 }
0216 }
0217
0218 #define _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( name, serial ) _register_##_##serial
0219
0220 #define _PS_V1_INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, typecreator, id, factory, serial ) \
0221 namespace { \
0222 class _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( type, serial ) { \
0223 public: \
0224 typedef factory s_t; \
0225 typedef typecreator f_t; \
0226 static s_t::FuncType creator() { return &f_t::create<s_t>; } \
0227 _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( type, serial )() { \
0228 using ::Gaudi::PluginService::v1::Details::Registry; \
0229 Registry::instance().add<s_t, type>( id, creator() ); \
0230 } \
0231 } _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( s_##type, serial ); \
0232 }
0233
0234 #define _PS_V1_INTERNAL_DECLARE_FACTORY( type, id, factory, serial ) \
0235 _PS_V1_INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, ::Gaudi::PluginService::v1::Details::Factory<type>, id, factory, \
0236 serial )
0237
0238 #endif