The Gaudi Framework  v30r3 (a5ef0a68)
PluginServiceDetailsV1.h
Go to the documentation of this file.
1 #ifndef _GAUDI_PLUGIN_SERVICE_DETAILS_V1_H_
2 #define _GAUDI_PLUGIN_SERVICE_DETAILS_V1_H_
3 /*****************************************************************************\
4 * (c) Copyright 2013 CERN *
5 * *
6 * This software is distributed under the terms of the GNU General Public *
7 * Licence version 3 (GPL Version 3), copied verbatim in the file "LICENCE". *
8 * *
9 * In applying this licence, CERN does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 \*****************************************************************************/
13 
15 
17 
18 #include <map>
19 #include <set>
20 #include <sstream>
21 #include <string>
22 #include <typeinfo>
23 #include <utility>
24 
25 #include <mutex>
26 
27 namespace Gaudi
28 {
29  namespace PluginService
30  {
32  {
33  namespace Details
34  {
39  template <class T>
40  class Factory
41  {
42  public:
43  template <typename S, typename... Args>
44  static typename S::ReturnType create( Args&&... args )
45  {
46  return new T( std::forward<Args>( args )... );
47  }
48  };
49 
53  void* getCreator( const std::string& id, const std::string& type );
54 
67  template <typename F>
68  inline F getCreator( const std::string& id )
69  {
70  union {
71  void* src;
72  F dst;
73  } p2p;
74  p2p.src = getCreator( id, typeid( F ).name() );
75  return p2p.dst;
76  }
77 
81  std::string demangle( const std::type_info& id );
82 
84  template <typename T>
86  {
87  return demangle( typeid( T ) );
88  }
89 
92  {
93  public:
95 
98 
99  struct FactoryInfo {
100  FactoryInfo( std::string lib, void* p = nullptr, std::string t = "", std::string rt = "",
101  std::string cn = "", Properties props = Properties() )
102  : library( std::move( lib ) )
103  , ptr( p )
104  , type( std::move( t ) )
105  , rtype( std::move( rt ) )
106  , className( std::move( cn ) )
107  , properties( std::move( props ) )
108  {
109  }
110 
112  void* ptr;
116  Properties properties;
117 
118  FactoryInfo& addProperty( const KeyType& k, std::string v )
119  {
120  properties[k] = std::move( v );
121  return *this;
122  }
123  };
124 
127 
129  static Registry& instance();
130 
132  template <typename F, typename T, typename I>
133  inline FactoryInfo& add( const I& id, typename F::FuncType ptr )
134  {
135  union {
136  typename F::FuncType src;
137  void* dst;
138  } p2p;
139  p2p.src = ptr;
141  o << id;
142  return add( o.str(), p2p.dst, typeid( typename F::FuncType ).name(),
143  typeid( typename F::ReturnType ).name(), demangle<T>() );
144  }
145 
147  void* get( const std::string& id, const std::string& type ) const;
148 
150  const FactoryInfo& getInfo( const std::string& id ) const;
151 
153  Registry& addProperty( const std::string& id, const std::string& k, const std::string& v );
154 
156  std::set<KeyType> loadedFactoryNames() const;
157 
159  inline const FactoryMap& factories() const
160  {
161  if ( !m_initialized ) const_cast<Registry*>( this )->initialize();
162  return m_factories;
163  }
164 
165  private:
170  Registry();
171 
173  Registry( const Registry& ) : m_initialized( false ) {}
174 
176  FactoryInfo& add( const std::string& id, void* factory, const std::string& type, const std::string& rtype,
177  const std::string& className, const Properties& props = Properties() );
178 
180  inline FactoryMap& factories()
181  {
182  if ( !m_initialized ) initialize();
183  return m_factories;
184  }
185 
188  void initialize();
189 
192 
194  FactoryMap m_factories;
195 
198  };
199 
202  {
203  public:
204  enum Level { Debug = 0, Info = 1, Warning = 2, Error = 3 };
205  Logger( Level level = Warning ) : m_level( level ) {}
206  virtual ~Logger() {}
207  inline Level level() const { return m_level; }
208  inline void setLevel( Level level ) { m_level = level; }
209  inline void info( const std::string& msg ) { report( Info, msg ); }
210  inline void debug( const std::string& msg ) { report( Debug, msg ); }
211  inline void warning( const std::string& msg ) { report( Warning, msg ); }
212  inline void error( const std::string& msg ) { report( Error, msg ); }
213 
214  private:
215  virtual void report( Level lvl, const std::string& msg );
217  };
218 
224  }
225 
227  GAUDIPS_API void SetDebug( int debugLevel );
229  GAUDIPS_API int Debug();
230  }
231  }
232 }
233 
234 #define _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( name, serial ) _register_##_##serial
235 
236 #define _PS_V1_INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, typecreator, id, factory, serial ) \
237  namespace \
238  { \
239  class _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( type, serial ) \
240  { \
241  public: \
242  typedef factory s_t; \
243  typedef typecreator f_t; \
244  static s_t::FuncType creator() { return &f_t::create<s_t>; } \
245  _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( type, serial )() \
246  { \
247  using ::Gaudi::PluginService::v1::Details::Registry; \
248  Registry::instance().add<s_t, type>( id, creator() ); \
249  } \
250  } _PS_V1_INTERNAL_FACTORY_REGISTER_CNAME( s_##type, serial ); \
251  }
252 
253 #define _PS_V1_INTERNAL_DECLARE_FACTORY( type, id, factory, serial ) \
254  _PS_V1_INTERNAL_DECLARE_FACTORY_WITH_CREATOR( type, ::Gaudi::PluginService::v1::Details::Factory<type>, id, factory, \
255  serial )
256 
257 #endif //_GAUDI_PLUGIN_SERVICE_DETAILS_H_
std::map< KeyType, std::string > Properties
Type used for the properties implementation.
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.
Simple logging class, just to provide a default implementation.
FactoryMap m_factories
Internal storage for factories.
GAUDIPS_API void setLogger(Logger *logger)
Set the logger instance to use.
STL namespace.
std::vector< Gaudi::Details::PropertyBase * > Properties
Definition: PropertyMgr.h:133
Registry(const Registry &)
Private copy constructor for the singleton pattern.
#define GAUDI_PLUGIN_SERVICE_V1_INLINE
FactoryMap & factories()
Return the known factories (loading the list if not yet done).
const FactoryMap & factories() const
Return the known factories (loading the list if not yet done).
STL class.
GAUDIPS_API Logger & logger()
Return the current logger instance.
In-memory database of the loaded factories.
std::map< KeyType, FactoryInfo > FactoryMap
Type used for the database implementation.
#define GAUDIPS_API
T move(T...args)
FactoryInfo & addProperty(const KeyType &k, std::string v)
STL class.
GAUDIPS_API int Debug()
Backward compatibility with Reflex.
std::recursive_mutex m_mutex
Mutex used to control concurrent access to the internal data.
static S::ReturnType create(Args &&...args)
GAUDIPS_API std::string demangle(const std::type_info &id)
Return a canonical name for type_info object (implementation borrowed from GaudiKernel/System).
Class providing default factory functions.
FactoryInfo(std::string lib, void *p=nullptr, std::string t="", std::string rt="", std::string cn="", Properties props=Properties())
GAUDIPS_API void SetDebug(int debugLevel)
Backward compatibility with Reflex.
Helper functions to set/get the application return code.
Definition: __init__.py:1
bool m_initialized
Flag recording if the registry has been initialized or not.