Replies: 2 comments 15 replies
-
This is... huge and very expensive probably. What's the use case for that? I've never really had one that makes sense so far.
Why not do this in the storage constructor or when the
The same is true here. You can add a mixin and do the right thing in the pop function to avoid mistakes. The registry is provided to all storage objects upon construction, therefore you can easily access all other pools if you need to.
Making the registry functions virtual would be a cost that everyone would pay for a few corner cases. Consider that this is the first time it has been requested in years. Literally. |
Beta Was this translation helpful? Give feedback.
-
Sorry for having to come back to this discussion. I'm having difficulty in thinking on how to structure this. At the time I filled the team's requirements, I also advised against some of them because they could result in performance issues. In sum we have a railway with properties. This takes an old implementation a the data source, so there are some old design choices we have to keep in mind. At its core the railway has positions. These positions are just a single value ordered low to high. Much like a double linked list of nodes. At each position we have properties, like gradients, signals, stations, etc. Some of these properties are given as intervals, for example, the railway has a gradient N from A to B. And these components have to be iterated by position order due to system requirements. The positions are not all known at once, they are given by the railway's properties, i.e. we get positions from gradient's intervals, and might get a completely new position from a signal or a station. Given that they iterate by position, this pool must be always sorted. They also iterate by interval changes, i.e all gradient positions don't need to be iterated, however, a gradient should be able to be fetched directly from any position. This also means that, each time a new position is added to the registry, it should also be assigned a gradient or any other interval component for the entity that owns it, as long as the position belongs to an interval. At the time they wanted an implementation that was easy to use and maintained these relationships automatically, and time was not on my side 😅 So, to fulfill all requirements I developed a registry wrapper that restricts the usage to our use-case. This wrapper provides access to a const registry, or a mutable instance through a lambda. This mutable instance provides access to reduced number of functions and does a few things automatically. An entity is created given a position value. The entity is created and a position is emplaced. A map is also kept in the registry's context to provide the inverse relation, since there is a reuse of old code sometimes it's necessary to know an entity given a position. This map also ensures that positions are unique. This component is also not meant to be managed by the user, so a user trait was added. // traits are attached to components that the wrapper then identifies
static constexpr bool read_only = true; For the interval implementation another user trait was added. static constexpr bool range = true; Intervals, also called ranges in the implementation, behave the following way: template<typename T> struct range_of { entity from; };
template<typename T> struct range_head_of { entity to; };
struct T { ... }; // any T component images containing part of the documentation explaining how this works A range component is added the same way as any other component is assigned to an entity. However, the component is only added to the entity that corresponds to the beginning of the interval. Then a range can be added through a method provided by the mutable instance, where it receives the entities that correspond to the beginning and end. When this mutable instance goes out of scope, a synchronization sequence is invoked to sort all pools by position. Each time a new position is added, all ranged components are checked and if there is an existing interval containing the position, a new range_of is assigned to that entity pointing to the the correct head. Note: the range implementation was eased with boost icl intervals that are stored in registry's context So, as I expected, we're facing performance issues due to the amount of sorting done. Who would've thought... but oh well, I won't rant here 😅 I'm now exploring way of getting the design done the correct way, but I'm having difficulties on how to structure these interval relationships to allow the same usage. This is probably due to my inexperience with more complex requirements using an ECS. How could I design this in a better way? |
Beta Was this translation helpful? Give feedback.
-
For a specific use-case there's a need to restrict access to basic_registry. There are component relationships that need to be managed carefully, but since these can be generalized the extended registry handles that automatically. A couple of things to have in mind:
To handle some of it entt::meta is great! My current approach works alright, however, I would like to improve it. Not only in terms of design but code complexity too.
For example, it makes perfect sense for my current wrapper to be a more specialized version of a basic_registry. I would like to extend it, and override some functionality from the base class to add specific behavior. The perfect example for this is
assure
. It would be perfect if it could beoverride
and/or accessed from a derived class. For every new assured storage I want to set somemeta_type
information for themeta_ctx
used by this instance. Right now I can do that by adding that extra functionality to all public methods available by the the specialized registry. That's not to bad but could be improved. What if I wanted all the functionality from the base class but with some specific functionality?What about virtual methods? It wouldn't surprise me if someone wanted to have a container of custom extended basic_registry types, wanted to invoke the same method for all of them and expect it to dispatch correctly.
Beta Was this translation helpful? Give feedback.
All reactions