[entt::meta] How do I safely insert a component instance into a registry with only its entt::meta_type info? #1223
-
For my game, I'm writing a reflection system with entt::meta and a simple editor. With the reflected type info, I can make a list of components that an entity doesn't have and present them under an "Add Component" drop-down menu. We can easily get the component storage ( entt::entity entity = selectedEntity;
for (auto [id, meta] : entt::resolve())
{
if (meta.traits<Traits>() & Traits::COMPONENT)
{
// Ignore if entity already has component.
if (registry.storage(id)->contains(entity)) // <---- Crashes if storage doesn't exist, but easy to avoid by checking if storage is null.
{
continue;
}
if (ImGui::Selectable(std::string(meta.info().name()).c_str()))
{
registry.storage(id)->push(entity); // <---- Crashes if storage doesn't exist.
}
}
} Since the storage can be nonexistent, causing The more I think about it, the more it seems like the only way to go about solving this is to register an "add component" function on every reflected component type (as in, I think this is a C++ limitation). So something like this: // Side note: I don't know how to forward references to these, so I just use pointers.
entt::meta<Foo>().func<[](entt::registry* registry, entt::entity entity) { registry->emplace(entity); }>("EmplaceComponent"_hs); Then I can invoke this function in my editor: if (ImGui::Selectable(std::string(meta.info().name()).c_str()))
{
if (auto emplaceFunc = meta.func("EmplaceComponent"_hs))
{
emplaceFunc.invoke({}, ®istry, entity);
}
} I hope there is a better way to do this, but if not, I can automate it away with macros. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
This question has been asked many times and I think there are several discussions with different examples. Have you seen those already? |
Beta Was this translation helpful? Give feedback.
This question has been asked many times and I think there are several discussions with different examples. Have you seen those already?
The main problem is that the registry cannot create a storage for you if it doesn't know the C++ type, and it's unknown when you invoke
storage
with a type info object.Briefly, you've literally two options here: attach to the meta type a let's create the storage function to which you pass the registry, or set up a sort of emplace-or-replace function that returns the element wrapped in a
meta_any
by reference.Let me know if you can't find a proper answer to your doubts and need more details. 👍