1 #ifndef GAUDIPLUGINSERVICE_GAUDI_DETAILS_PLUGINSERVICEDETAILSV2_H
2 #define GAUDIPLUGINSERVICE_GAUDI_DETAILS_PLUGINSERVICEDETAILSV2_H
18 #if __cplusplus >= 201703
21 # include <boost/any.hpp>
24 using boost::any_cast;
25 using boost::bad_any_cast;
40 namespace PluginService {
52 template <
typename R,
typename... Args>
53 struct Traits<R( Args... )> {
54 using ReturnType = std::unique_ptr<std::remove_pointer_t<R>>;
55 using FactoryType = std::function<ReturnType( Args... )>;
61 std::string
demangle(
const std::type_info&
id );
70 template <
typename ID>
71 inline std::string stringify_id(
const ID&
id ) {
78 inline std::string stringify_id<std::string>(
const std::string&
id ) {
83 void reportBadAnyCast(
const std::type_info& factory_type,
const std::string&
id );
88 enum Level {
Debug = 0, Info = 1, Warning = 2, Error = 3 };
89 Logger( Level level = Warning ) : m_level( level ) {}
91 inline Level level()
const {
return m_level; }
92 inline void setLevel( Level level ) { m_level = level; }
93 inline void info(
const std::string& msg ) { report( Info, msg ); }
94 inline void debug(
const std::string& msg ) { report(
Debug, msg ); }
95 inline void warning(
const std::string& msg ) { report( Warning, msg ); }
96 inline void error(
const std::string& msg ) { report( Error, msg ); }
99 virtual void report( Level lvl,
const std::string& msg );
112 using KeyType = std::string;
115 using Properties = std::map<KeyType, std::string>;
120 Properties properties{};
122 inline bool is_set()
const {
123 #if __cplusplus >= 201703
124 return factory.has_value();
126 return !factory.empty();
129 Properties::mapped_type getprop(
const Properties::key_type& name )
const;
133 using FactoryMap = std::map<KeyType, FactoryInfo>;
136 template <
typename F>
137 F get(
const KeyType&
id ) {
138 const FactoryInfo&
info = Registry::instance().getInfo(
id,
true );
139 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
140 if ( !
info.getprop(
"ReflexName" ).empty() ) {
141 const std::string real_name =
info.getprop(
"ClassName" );
142 logger().warning(
"requesting factory via old name '" +
id +
"' use '" +
143 ( real_name.empty() ?
"<undefined>" : real_name ) +
"' instead" );
146 return std::any_cast<F>(
info.factory );
150 static Registry& instance();
153 FactoryInfo& add(
const KeyType&
id, FactoryInfo
info );
156 const FactoryInfo& getInfo(
const KeyType&
id,
const bool load =
false )
const;
159 Registry& addProperty(
const KeyType&
id,
const KeyType& k,
const std::string&
v );
162 std::set<KeyType> loadedFactoryNames()
const;
169 const FactoryMap& factories()
const;
176 Registry(
const Registry& ) =
delete;
179 FactoryMap& factories();
186 mutable std::once_flag m_initialized;
189 FactoryMap m_factories;
192 mutable std::recursive_mutex m_mutex;
199 template <
typename,
typename>
200 struct DefaultFactory;
201 template <
typename T,
typename R,
typename... Args>
202 struct DefaultFactory<T, Factory<R( Args... )>> {
203 inline typename Factory<R( Args... )>::ReturnType operator()( Args... args ) {
204 return std::make_unique<T>( std::move( args )... );
222 #define _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME_TOKEN( serial ) _register_##serial
223 #define _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME( serial ) \
224 _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME_TOKEN( serial )
225 #define _PS_V2_INTERNAL_FACTORY_REGISTER_CNAME _PS_V2_INTERNAL_FACTORY_MAKE_REGISTER_CNAME( __LINE__ )
227 #endif // GAUDIPLUGINSERVICE_GAUDI_DETAILS_PLUGINSERVICEDETAILSV2_H