I've been finding most of them via searching the issues here, for example "entt::DefaultRegistry" becomes "entt::registry".
However, some things that have changed such as "registry.attachee()" don't appear to be documented but throw a compilation error so I assume have been updated. Is there anywhere I can find a list of changes made? I haven't upgraded entt in some time, and I have hundreds of errors which is quite discouraging.
Specifically the only things I've not been able to find are the "registry.attachee()" function as above, and various snapshot functions - restore, tag, orphans and so on. I see orphans() is still in the wiki section on snapshots, so I'm not sure if this may be an error with the (deprecated?) cereal code instead.
Here's a vague and incomplete list of things that have changed since 2.7.3
snake_caseentt::entity and entt::registryIn the works:
For a full detailed list written by skypjack himself, read the 237 commit messages since 2.7.3!
Indeed, v3 is quite a different beast if compared to v2, as noted by @Kerndog73 above.
First fo all, everything has been ported to C++17 and the API slightly changed in some parts because of this. As an example, connecting a signal:
signal.connect<my_type, &my_type::my_member_function>(&instance); // C++14
signal.connect<&my_type::my_member_function>(&instance); // C++17
Moreover, snake case is consistently used throughout the whole library now, not only for _exported types_ as it was before (eg DefaultRegistry::entity_type).
Major features added so far are the groups and the runtime reflection system.
The latter is a standalone part that I'll integrate with the view and the registry sooner or later. The former have been introduced to offer a fast tool that allows even perfect SoA in some cases. In other words, something for when you really need extreme performance. Persistent views no longer exist, non-owning groups fully replaced them.
An interesting aspect of groups is that you can also use exclusion lists with them, so you can constructs a group that contains eg all the entities that have components A and B but not C.
Major internal changes that didn't affect the API are the empty type optimization and the pagination of the sparse array for the pools. Memory usage is highly reduced now in the average case.
Another major change is the possibility to create views and groups from a const registry, something that wasn't possible with v2. In particular, you can explicitly specify the constness of components iterated and returned by these tools:
auto view = registry.view<a_type, const another_type>();
A const registry obviously allows for views and groups the components of which are all const. There is a dedicated section in the documentation for this stuff.
If you ever wanted to use EnTT across boundaries, it's possible now with the latest version. It means mainly that is works also with DLLs on Windows, something that wasn't supported by v2.
If you want to reduce the compilation time instead, forward headers (fwd.hpp) have been added for the purpose.
The delegate class has been fully reviewed and allows now to bind user data when used with free functions among the other features. This reflects also on the signal class, the dispatcher and the signals offered by the registry. Although it went almost unnoticed, this was for me one of the most useful changes.
Some other functions and tool have been added all around, as an example registry::get_if or registry::get_or_assign. All of them are documented in-code, most of them are also mentioned in the wiki. @Kerndog73 mentioned several of them (bulk operations and so on).
You can find also some extra utilities like as_view or entt::tag.
As you pointed out, single instance components no longer exist. We agreed in the gitter channel (I invite you to join it to know what's going on in EnTT) that they weren't that useful the way they were designed. Most of the time users wanted just per-registry singletons, the entity wasn't required. You've them now, they are called context variables.
This is also the reason for which snapshot::tag no longer exists. Instead I didn't get what you said about snapshot::orhpans, because ofc it's still there.
Finally, the build system has been reviewed/updated and I started a FAQ document when I found (with the help of other users) that EnTT can be fast also in debug on Windows, something nobody expected because of its use of the standard library. :smile:
Surely I forgot something, but this is what came to my mind on the spot.
Branch master is a stable work in progress towards the v3, but I didn't cut a new release so far. I'm almost there, but not yet. When I'll do that, you can find a more comprehensive list of changes here.
Let me know if you have any other question, otherwise please close the issue if you got your answer.
Also, do not forget to star the project if you're actively using it. It would be really appreciated. Thanks.
Perfect response, thank you! I will star the projectof course.
One last question, what would now be the correct method to store e.g. a "tag" or equivalent in a snapshot? The context is that I wish to tag an entity as the local player rather than a networked or AI player, and of course there should only be one local player. Would I just create a boolean in my input component or is there a more elegant solution?
Thanks again :)
@Kazsilop It sounds like you just want a regular component that is only assigned to one entity. You could just create this and assign it to the player.
struct LocalPlayer {};
You could also create components for other types of players.
struct NetworkedPlayer {
// maybe a network connection handle or something
};
struct AIPlayer {};
Tags from 2.7.3 would enforce the constraint that the component can only be assigned to one entity but there isn't really a need for this. You can just assign a regular component to the player and make sure you do it once.
This is actually a bit more flexible than tags. What if you want old-school local multiplayer (multiple players using the same keyboard and screen or split-screen on a console)? If LocalPlayer is a regular component and not a 2.7.3 tag then you'd just have two entities with LocalPlayer components. Although you'd probably want to differentiate between the players so that the input system knows that the two players have a different set of controls.
Thanks to the pagination, you can use a regular component as mentioned by @Kerndog73 and there is no longer the risk to waste memory in an unpredictable way as it happens with v2. Probably I'd put an assert(registry.size<player>() < 2)) to enforce the constraint.
Otherwise, you can use a context variable like this:
// define the struct to store the player
struct player { entt::entity id; };
// create the entity and set up the context variable
player current{registry.create()};
registry.set<player>(current);
// use it when needed
auto &curr = registry.ctx<player>(); // curr.id is the entity you're looking for
The aim of the context variables is (I mention an user from gitter) to use a registry as _the only source of truth_. They are a kind of per-registry singletons.
To serialize it you can just prepend or append the id to your archive before or after constructing the snapshot. The purpose of the snapshot class is to ease serializing entities and components, but nothing forbids from extending your archive with custom data. Ofc the other way around using a component would be transparent instead.
If I was you, I'd use a local_player component as well as ai_player and networked_player components. However you're the only one that has the full context and can decide for the best.
Thanks for the detailed response guys, I really appreciate it. I think everything has been very well explained so I'll close this issue now.
You're welcome. Thank you for using EnTT.
If you have any other question, you can either open an issue or join the gitter channel.
v3 is really a huge change, but the hope is that it will be a change for the better for everybody. :wink:
:+1: thanks @Kerndog73 i totally missed that ctx singletons are a thing now. this helps a lot with making registry the absolute source of truth when it comes to game state.
Most helpful comment
Indeed,
v3is quite a different beast if compared tov2, as noted by @Kerndog73 above.First fo all, everything has been ported to C++17 and the API slightly changed in some parts because of this. As an example, connecting a signal:
Moreover, snake case is consistently used throughout the whole library now, not only for _exported types_ as it was before (eg
DefaultRegistry::entity_type).Major features added so far are the groups and the runtime reflection system.
The latter is a standalone part that I'll integrate with the view and the registry sooner or later. The former have been introduced to offer a fast tool that allows even perfect SoA in some cases. In other words, something for when you really need extreme performance. Persistent views no longer exist, non-owning groups fully replaced them.
An interesting aspect of groups is that you can also use exclusion lists with them, so you can constructs a group that contains eg all the entities that have components
AandBbut notC.Major internal changes that didn't affect the API are the empty type optimization and the pagination of the sparse array for the pools. Memory usage is highly reduced now in the average case.
Another major change is the possibility to create views and groups from a const registry, something that wasn't possible with
v2. In particular, you can explicitly specify the constness of components iterated and returned by these tools:A const registry obviously allows for views and groups the components of which are all const. There is a dedicated section in the documentation for this stuff.
If you ever wanted to use
EnTTacross boundaries, it's possible now with the latest version. It means mainly that is works also with DLLs on Windows, something that wasn't supported byv2.If you want to reduce the compilation time instead, forward headers (
fwd.hpp) have been added for the purpose.The delegate class has been fully reviewed and allows now to bind user data when used with free functions among the other features. This reflects also on the signal class, the dispatcher and the signals offered by the registry. Although it went almost unnoticed, this was for me one of the most useful changes.
Some other functions and tool have been added all around, as an example
registry::get_iforregistry::get_or_assign. All of them are documented in-code, most of them are also mentioned in the wiki. @Kerndog73 mentioned several of them (bulk operations and so on).You can find also some extra utilities like
as_vieworentt::tag.As you pointed out, single instance components no longer exist. We agreed in the gitter channel (I invite you to join it to know what's going on in
EnTT) that they weren't that useful the way they were designed. Most of the time users wanted just per-registry singletons, the entity wasn't required. You've them now, they are called context variables.This is also the reason for which
snapshot::tagno longer exists. Instead I didn't get what you said aboutsnapshot::orhpans, because ofc it's still there.Finally, the build system has been reviewed/updated and I started a FAQ document when I found (with the help of other users) that
EnTTcan be fast also in debug on Windows, something nobody expected because of its use of the standard library. :smile:Surely I forgot something, but this is what came to my mind on the spot.
Branch
masteris a stable work in progress towards thev3, but I didn't cut a new release so far. I'm almost there, but not yet. When I'll do that, you can find a more comprehensive list of changes here.Let me know if you have any other question, otherwise please close the issue if you got your answer.
Also, do not forget to star the project if you're actively using it. It would be really appreciated. Thanks.