I might just be having an idiot moment but ...
I don't see a way to get all components on an entity for inspection/tool purposes?
Is there something I'm missing or a recommended way of doing that. Even just a bitset or vector
I'm not completely sure what you mean but you can check if an entity has one or more components.
entt::DefaultRegistry reg;
reg.has<Position>(entity); // true if the entity has a Position component
reg.has<Position, Velocity, Goblin>(entity); // true if entity has Position and Velocity and Goblin
You might be able to take a typelist and create a bitset of the components an entity has by calling reg.has for each type in the list. EnTT is a bitset-free ECS so you can't just grab a bitset from the internals because there isn't one!
template <typename... Comps>
std::bitset<sizeof...(Comps)> getComponentBitset(
entt::DefaultRegistry ®,
const uint32_t entity
) {
using List = Utils::TypeList<Comps...>;
std::bitset<sizeof...(Comps)> bitset = 0;
size_t index = 0;
Utils::forEach<List>([&bitset, &index, ®, entity] (auto type) {
using Component = UTILS_TYPE(type);
bitset[index] = reg.has<Component>(entity);
++index;
});
return bitset;
}
Use it like this:
auto bitset = getComponentBitset<Position, Velocity, Goblin>(reg, entity);
// bitset[2] is true if entity has Goblin component
You'll have to replace Utils::TypeList and Utils::forEach with your own type list library of course! 馃榾 @skypjack might be aware of a way to do this more efficiently than calling reg.has for each component type.
You can get a list of components all at once. This only works only if the entity has all of the components.
reg.get<Position, Velocity, Goblin>(entity); // returns a std::tuple containing the three components
You could use typelists to do some fancy stuff if you like.
template <typename... Comps>
auto getComponentPointers(
entt::DefaultRegistry ®,
const uint32_t entity
) {
using List = Utils::TypeList<Comps...>;
using PtrList = Utils::TransformList<List, std::add_pointer>;
using Tuple = Utils::ListToTuple<PtrList>;
Tuple tuple;
Utils::forEach(tuple, [®, entity] (auto &comp) {
using Component = std::remove_pointer_t<decltype(comp)>;
if (reg.has<Component>(entity)) {
comp = ®.get<Component>(entity);
} else {
comp = nullptr;
}
});
return tuple;
}
Use it like this:
auto tuple = getComponentPointers<Position, Velocity, Goblin>(reg, entity);
// the type of tuple is
std::tuple<Position *, Velocity *, Goblin *>
// the pointers are null if the entity doesn't have the component.
Once again, @skypjack might be aware of a more efficient way of doing this. I haven't properly tested the fancy type list functions but they compile. That's a pretty good test when working with type lists!
@JSandusky did that solve your problem?
In case the suggestions from @Kerndog73 don't solve your problem, it would help if you can give more details and an example of use of what you are looking for.
Thank you.
@Kerndog73 yeah I think so. Even if it doesn't that's close enough that I get it.
Though it just dawned on me that the serialization stuff could probably be used assuming I can serialize/deserialize 1 specific entity, even if I can't ATM that's probably not going to be a tough tweak.
@skypjack exact purpose in my case is that I'm embedding a small HTTP server into the program for introspection/editing purposes. For that I need to get a list of every component on an entity ideally as close to typeless as I can for as long as I can - though in some cases that isn't necessary, not needed in a trivial inspector but is needed for a coalesced data-table view of entities.
TL/DR: user-interface needs.
For that I need to get a list of every component on an entity ideally as close to typeless as I can for as long as I can
So, a sort of range of component_types (aka std::size_t) would work for you?
This put your side the burden of _deducing_ what's the actual type of the i-th item in the range.
Yeah, that'd work.
Though I'm thinking that using the Snapshot is the more appropriate thing to do for this. The archive implementation I feed to it can emit the information that I need and the details/mess don't need to be in Entt.
Hmm sounds like visitor pattern, this example may help
So, @JSandusky nothing to do for this issue? Not sure serialization is the best tool for this purpose, but it's fine for me if it works for you. :-)
Yeah, nothing to do. Going along the lines of what @Kerndog73 posted will work plenty well. The Snapshot interface involves too much hard writing to be usable for this (usable, but really unpleasant).
The Snapshot interface involves too much hard writing to be usable for this (usable, but really unpleasant).
Feel free to contribute with a suggestion to improve the snapshot stuff. This library is mostly made by its users, their requests and suggestions.
Also, do not forget to star the project. This helps to make it known and to attract even more users, so more contributions and suggestions.
Also, do not forget to star the project. This helps to make it known and to attract even more users, so more contributions and suggestions.
No. Ended up going with a late 90's Bungie style ECS instead. Can't actually recommend Entt enough to star it. Need concrete identification of things in order to write tools, Entt makes that template hell.
I love this _C-ish_ stuff that pops out from late 90's.
However, if you need help with modern C++, modern techniques and therefore with EnTT, feel free to ask in future.
There exist already tools like the one you're writing that use EnTT under the hood, fortunately. It's only a matter of approach and design sometimes.
@JSandusky Sorry for the necro-post, but can you please refer to some documentation as to what you meant by _"late 90's Bungie style ECS"_? I am also hitting the same complexity barriers, and would like to study simpler alternatives. The only thing my research yielded was Halo 2's "tag" system, but I am not sure if this is what you were referring to (and how to use this to build a full entity-management system to top of this)?
Getting all components of an entity as an opaque identifier has since become possible with visit. That will give you a type_info object. What you can do with this is growing. You can create a table of function pointers or use the other facilities available.
Most helpful comment
I'm not completely sure what you mean but you can check if an entity
hasone or more components.You might be able to take a typelist and create a bitset of the components an entity has by calling
reg.hasfor each type in the list. EnTT is a bitset-free ECS so you can't just grab a bitset from the internals because there isn't one!Use it like this:
You'll have to replace
Utils::TypeListandUtils::forEachwith your own type list library of course! 馃榾 @skypjack might be aware of a way to do this more efficiently than callingreg.hasfor each component type.You can get a list of components all at once. This only works only if the entity has all of the components.
You could use typelists to do some fancy stuff if you like.
Use it like this:
Once again, @skypjack might be aware of a more efficient way of doing this. I haven't properly tested the fancy type list functions but they compile. That's a pretty good test when working with type lists!