14 #define GAUDI_PLUGIN_SERVICE_V2
34 #ifdef USE_BOOST_FILESYSTEM
35 # include <boost/filesystem.hpp>
36 namespace fs = boost::filesystem;
38 # include <filesystem>
39 namespace fs = std::filesystem;
40 #endif // USE_BOOST_FILESYSTEM
42 #if __cplusplus >= 201703
43 # include <string_view>
45 # include <experimental/string_view>
47 using experimental::string_view;
60 void operator()(
const char c ) {
69 name.push_back(
'_' );
72 name.push_back(
'r' );
75 name.push_back(
'p' );
92 namespace PluginService {
98 abi::__cxa_demangle(
id.c_str(),
nullptr,
nullptr, &status ), free );
99 if ( !realname )
return id;
100 #if _GLIBCXX_USE_CXX11_ABI
103 std::regex{
"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >( (?=>))?"},
111 Registry& Registry::instance() {
112 auto _guard = std::scoped_lock{::registrySingletonMutex};
120 const auto& info = Registry::instance().getInfo(
id );
121 msg <<
"bad any_cast: requested factory " <<
id <<
" of type " <<
demangle( factory_type ) <<
", got ";
123 msg <<
demangle( info.factory.type() ) <<
" from " << info.library;
130 Registry::Properties::mapped_type Registry::FactoryInfo::getprop(
const Properties::key_type&
name )
const {
132 return ( p !=
end(
properties ) ) ? p->second : Properties::mapped_type{};
135 Registry::Registry() {}
137 void Registry::initialize() {
138 auto _guard = std::scoped_lock{m_mutex};
139 #if defined( _WIN32 )
140 const char* envVar =
"PATH";
141 const char sep =
';';
143 const char* envVar =
"LD_LIBRARY_PATH";
144 const char sep =
':';
147 std::regex line_format{
"^(?:[[:space:]]*(?:(v[0-9]+)::)?([^:]+):(.*[^[:space:]]))?[[:space:]]*(?:#.*)?$"};
150 std::string_view search_path =
std::getenv( envVar );
151 if ( !search_path.empty() ) {
154 std::string_view::size_type start_pos = 0, end_pos = 0;
155 while ( start_pos != std::string_view::npos ) {
157 if ( start_pos ) ++start_pos;
159 end_pos = search_path.find( sep, start_pos );
161 #ifdef USE_BOOST_FILESYSTEM
164 search_path.substr( start_pos, end_pos - start_pos );
168 logger().debug(
" looking into " + dirName.string() );
170 if ( is_directory( dirName ) ) {
171 for (
auto& p : fs::directory_iterator( dirName ) ) {
172 if ( p.path().extension() ==
".components" && is_regular_file( p.path() ) ) {
174 const auto& fullPath = p.path().string();
175 logger().debug(
" reading " + p.path().filename().string() );
178 int factoriesCount = 0;
184 if (
m[1] ==
"v2" ) {
187 m_factories.emplace( fact, FactoryInfo{lib, {}, {{
"ClassName", fact}}} );
188 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
191 if ( fact != old_name ) {
192 m_factories.emplace( old_name,
193 FactoryInfo{lib, {}, {{
"ReflexName",
"true"}, {
"ClassName", fact}}} );
213 std::call_once( m_initialized, &Registry::initialize,
const_cast<Registry*
>(
this ) );
222 Registry::FactoryInfo&
Registry::add(
const KeyType&
id, FactoryInfo info ) {
223 auto _guard = std::scoped_lock{m_mutex};
226 #ifdef GAUDI_REFLEX_COMPONENT_ALIASES
228 const auto old_name = old_style_name(
id );
229 if (
id != old_name ) {
230 auto new_info = info;
232 new_info.properties[
"ReflexName"] =
"true";
234 add( old_name, new_info );
238 auto entry = facts.find(
id );
239 if ( entry == facts.end() ) {
241 entry = facts.emplace(
id,
std::move( info ) ).first;
244 if ( !entry->second.is_set() ) entry->second =
std::move( info );
246 return entry->second;
249 const Registry::FactoryInfo& Registry::getInfo(
const KeyType&
id,
const bool load )
const {
250 auto _guard = std::scoped_lock{m_mutex};
251 static const FactoryInfo unknown = {
"unknown"};
253 auto f = facts.find(
id );
255 if ( f != facts.end() ) {
256 if ( load && !f->second.is_set() ) {
258 if ( !dlopen( library.
c_str(), RTLD_LAZY | RTLD_GLOBAL ) ) {
259 logger().warning(
"cannot load " + library +
" for factory " +
id );
260 char* dlmsg = dlerror();
261 if ( dlmsg )
logger().warning( dlmsg );
264 f = facts.find(
id );
272 Registry& Registry::addProperty(
const KeyType&
id,
const KeyType& k,
const std::string&
v ) {
273 auto _guard = std::scoped_lock{m_mutex};
275 auto f = facts.find(
id );
277 if ( f != facts.end() ) f->second.properties[k] =
v;
282 auto _guard = std::scoped_lock{m_mutex};
285 if ( f.second.is_set() )
l.insert( f.first );
291 static const char* levels[] = {
"DEBUG : ",
"INFO : ",
"WARNING: ",
"ERROR : "};
295 static auto s_logger = std::make_unique<Logger>();
303 if ( dladdr( fptr, &info ) == 0 )
return "";
309 return info.dli_fname;
318 using namespace Details;
320 if ( debugLevel > 1 )
322 else if ( debugLevel > 0 )
323 l.setLevel( Logger::Info );
325 l.setLevel( Logger::Warning );
329 using namespace Details;