17 #ifndef GZ_SIM_COMPONENTS_FACTORY_HH_
18 #define GZ_SIM_COMPONENTS_FACTORY_HH_
30 #include <gz/common/SingletonT.hh>
31 #include <gz/common/Util.hh>
33 #include <gz/sim/config.hh>
34 #include <gz/sim/Export.hh>
36 #include <gz/utils/NeverDestroyed.hh>
43 inline namespace GZ_SIM_VERSION_NAMESPACE {
65 template <
typename ComponentTypeT>
72 return std::make_unique<ComponentTypeT>();
79 ComponentTypeT comp(*
static_cast<const ComponentTypeT *
>(_data));
80 return std::make_unique<ComponentTypeT>(comp);
90 : id(reinterpret_cast<
std::uintptr_t>(_ptr))
105 return this->
id == _other.
id;
132 return this->queue.empty();
143 this->queue.push_front({_regObjId, _comp});
154 auto compIt =
std::find_if(this->queue.rbegin(), this->queue.rend(),
155 [&](
const auto &_item)
156 { return _item.first == _regObjId; });
158 if (compIt != this->queue.rend())
161 this->queue.erase(
std::prev(compIt.base()));
171 if (!this->queue.empty())
173 return this->queue.front().second->Create();
184 if (!this->queue.empty())
186 return this->queue.front().second->Create(_data);
215 public:
template <
typename ComponentTypeT>
219 const char* typeDup = strdup(_type.c_str());
220 this->Register<ComponentTypeT>(typeDup, _compDesc,
233 public:
template <
typename ComponentTypeT>
237 const char* typeDup = strdup(_type.c_str());
238 this->Register<ComponentTypeT>(typeDup, _compDesc, _regObjId);
250 public:
template <
typename ComponentTypeT>
259 ComponentTypeT::typeId = typeHash;
260 ComponentTypeT::typeName = _type;
263 auto runtimeName =
typeid(ComponentTypeT).name();
264 auto runtimeNameIt = this->runtimeNamesById.find(typeHash);
265 if (runtimeNameIt != this->runtimeNamesById.end())
270 if (runtimeNameIt->second != runtimeName)
273 <<
"Registered components of different types with same name: type ["
274 << runtimeNameIt->second <<
"] and type [" << runtimeName
275 <<
"] with name [" << _type <<
"]. Second type will not work."
286 if (debugEnv !=
"true")
289 if (debugEnv ==
"true")
291 std::cerr <<
"Environment variable [IGN_DEBUG_COMPONENT_FACTORY] "
292 <<
"is deprecated! Please use [GZ_DEBUG_COMPONENT_FACTORY]"
297 if (debugEnv ==
"true")
299 std::cout <<
"Registering [" << ComponentTypeT::typeName <<
"]"
304 this->compsById[ComponentTypeT::typeId].Add(_regObjId, _compDesc);
305 namesById[ComponentTypeT::typeId] = ComponentTypeT::typeName;
306 runtimeNamesById[ComponentTypeT::typeId] = runtimeName;
313 public:
template <
typename ComponentTypeT>
325 public:
template<
typename ComponentTypeT>
328 this->Unregister(ComponentTypeT::typeId, _regObjId);
355 auto it = this->compsById.find(_typeId);
356 if (it != this->compsById.end())
358 it->second.Remove(_regObjId);
360 if (it->second.Empty())
362 this->compsById.erase(it);
371 public:
template<
typename ComponentTypeT>
375 this->New(ComponentTypeT::typeId).release()));
387 auto it = this->compsById.find(_type);
388 if (it != this->compsById.end())
390 comp = it->second.Create();
406 if (
nullptr == _data)
408 gzerr <<
"Requested to create a new component instance with null "
411 else if (_type != _data->
TypeId())
413 gzerr <<
"The typeID of _type [" << _type <<
"] does not match the "
418 auto it = this->compsById.find(_type);
419 if (it != this->compsById.end())
421 comp = it->second.Create(_data);
435 for (
const auto &comp : this->compsById)
445 return this->compsById.find(_typeId) != this->compsById.end();
452 if (this->namesById.find(_typeId) != this->namesById.end())
453 return namesById.
at(_typeId);
461 friend gz::utils::NeverDestroyed<Factory>;
482 #define GZ_SIM_REGISTER_COMPONENT(_compType, _classname) \
483 class GzSimComponents##_classname \
485 public: GzSimComponents##_classname() \
488 using Desc = sim::components::ComponentDescriptor<_classname>; \
489 sim::components::Factory::Instance()->Register<_classname>(\
490 _compType, new Desc(), sim::components::RegistrationObjectId(this));\
492 public: GzSimComponents##_classname( \
493 const GzSimComponents##_classname&) = delete; \
494 public: GzSimComponents##_classname( \
495 GzSimComponents##_classname&) = delete; \
496 public: ~GzSimComponents##_classname() \
498 using namespace gz; \
499 sim::components::Factory::Instance()->Unregister<_classname>( \
500 sim::components::RegistrationObjectId(this)); \
503 static GzSimComponents##_classname\
504 GzSimComponentsInitializer##_classname;