Go to the documentation of this file. 19 #ifndef IGNITION_COMMON_DETAIL_PLUGINMACROS_HH_ 20 #define IGNITION_COMMON_DETAIL_PLUGINMACROS_HH_ 24 #include <type_traits> 25 #include <unordered_set> 31 #if defined _WIN32 || defined __CYGWIN__ 33 #define DETAIL_IGN_PLUGIN_VISIBLE __attribute__ ((dllexport)) 35 #define DETAIL_IGN_PLUGIN_VISIBLE __declspec(dllexport) 39 #define DETAIL_IGN_PLUGIN_VISIBLE __attribute__ ((visibility ("default"))) 41 #define DETAIL_IGN_PLUGIN_VISIBLE 45 #define DETAIL_IGN_COMMON_SPECIALIZE_INTERFACE(interfaceName) \ 46 static_assert(std::is_same<interfaceName, ::interfaceName>::value, \ 47 #interfaceName " must be fully qualified like ::ns::MyClass"); \ 48 static constexpr const char* IGNCOMMONInterfaceName = #interfaceName; 51 #define DETAIL_IGN_COMMON_REGISTER_PLUGININFO_META_DATA \ 53 std::size_t DETAIL_IGN_PLUGIN_VISIBLE IGNCOMMONPluginInfoSize = \ 54 sizeof(ignition::common::PluginInfo); \ 56 std::size_t DETAIL_IGN_PLUGIN_VISIBLE IGNCOMMONPluginInfoAlignment = \ 57 alignof(ignition::common::PluginInfo); \ 59 int DETAIL_IGN_PLUGIN_VISIBLE IGNCOMMONPluginAPIVersion = \ 60 ignition::common::PLUGIN_API_VERSION; \ 64 #define DETAIL_IGN_COMMON_BEGIN_ADDING_PLUGINS \ 65 DETAIL_IGN_COMMON_REGISTER_PLUGININFO_META_DATA \ 66 IGN_COMMON_WARN_IGNORE__DELETE_NON_VIRTUAL_DESTRUCTOR \ 69 struct IGN_macro_must_be_used_in_global_namespace; \ 70 static_assert(std::is_same < IGN_macro_must_be_used_in_global_namespace, \ 71 ::IGN_macro_must_be_used_in_global_namespace>::value, \ 72 "Macro for registering plugins must be used in global namespace"); \ 90 extern "C" std::size_t DETAIL_IGN_PLUGIN_VISIBLE IGNCOMMONMultiPluginInfo( \ 91 void * * const _outputInfo, \ 92 const std::size_t _pluginId, \ 93 const std::size_t _size) \ 95 if (_size != sizeof(ignition::common::PluginInfo)) \ 99 std::unordered_set<std::string> visitedPlugins; \ 100 ignition::common::PluginInfo * * const ptrToPlugin = \ 101 reinterpret_cast<ignition::common::PluginInfo * *>(_outputInfo); \ 102 if ( !(*ptrToPlugin) ) \ 104 *ptrToPlugin = new ignition::common::PluginInfo; \ 106 ignition::common::PluginInfo *plugin = *ptrToPlugin; \ 107 plugin->name.clear(); \ 108 plugin->interfaces.clear(); \ 109 plugin->factory = nullptr; \ 110 plugin->deleter = nullptr; 113 #define DETAIL_IGN_COMMON_ADD_PLUGIN(pluginName, interface) \ 115 static_assert(std::is_same<pluginName, ::pluginName>::value, \ 116 #pluginName " must be fully qualified like ::ns::MyClass"); \ 117 static_assert(std::is_same<interface, ::interface>::value, \ 118 #interface " must be fully qualified like ::ns::MyClass"); \ 124 static_assert(!std::is_abstract<pluginName>::value, \ 125 "[" #pluginName "] must not be an abstract class. It contains at least " \ 126 "one pure virtual function!"); \ 129 static_assert(std::is_base_of<interface, pluginName>::value, \ 130 "[" #interface "] is not a base class of [" #pluginName "], so it " \ 131 "cannot be used as a plugin interface for [" #pluginName "]!"); \ 136 const bool insertion = visitedPlugins.insert(#pluginName).second; \ 139 if (_pluginId == visitedPlugins.size() - 1) \ 143 plugin->name = #pluginName; \ 144 plugin->factory = []() { \ 145 return static_cast<void*>(new pluginName()); \ 147 plugin->deleter = [](void* ptr) { \ 148 delete static_cast< pluginName* >(ptr); \ 153 if ( #pluginName == plugin->name ) \ 157 plugin->interfaces.insert(std::make_pair( \ 158 #interface , [=](void* v_ptr) { \ 159 pluginName * d_ptr = static_cast< pluginName *>(v_ptr); \ 160 return static_cast< interface *>(d_ptr); \ 166 #define DETAIL_IGN_COMMON_FINISH_ADDING_PLUGINS \ 167 if (_pluginId >= visitedPlugins.size()) \ 173 return visitedPlugins.size() - _pluginId; \ 175 IGN_COMMON_WARN_RESUME__DELETE_NON_VIRTUAL_DESTRUCTOR