sebas77/Svelto.ECS

Major refactoring incoming

Closed this issue · 10 comments

This refactoring started as result of a design issue regarding how entity IDs should work. I never really cared much about entityID as svelto uses them exclusively to query indexable entity views.

Because I introduced the RemoveEntity without entity descriptor, it could have worked only if globally unique ID were used.

Unluckily Cardlife was already designed to not use unique IDs which caused some issues. In any case the Svelto code wasn't designed to care much about the IDs.

At the same time I wasn't liking the direction the code was taking so I decided to simplify it and at the same time optimize it:

  • Entities are now always built in groups. You can still query all the entityviews regardless the group. If you build an entity without specifying a group, it will be built in a special group
  • Because of this, the RemoveEntity will need to know the group ID of the entity. I am still not sure if I like this, I will need to do some tests
  • I removed the concept of MetaEntites, it was confusing and probably was a practice I should not encourage.
  • I am optimizing the building of entities in general, fixing code and adding comments and new tests

I am still thinking about the unique ID issue, which is more complex than I thought.

Initially it was simple: the rule was that Enitity could share the same ID as long as the IDs of the EntityViews generated were unique. This means that you could have two Entities with the same ID as long as they were generating different EntityViews.

Because of this, the RemoveEntity needed the EntityDescriptor parameter, which I wanted to remove as it was awkward. In the moment I removed it, I shifted the rule to every entityID must be unique, although this was not properly enforced.

It's a while I am thinking that Entities should be always built in a group. However it's a bit awkward to force the user to specify a group if it's not needed.
I can hide this and use a "standard group" when the group is not specified, however the user must still be able to access to a global pool of entity views when an engine is not interested in the group subdivision. If you have the group of enemies and the group of players and they both generate HealthEntityView, the HealthEntityViews engine needs to query all of them, regardless the group, otherwiseyou will be forced to write an EnemyHealthEntityEngine and a PlayerHealthEntityViewEngine which would be very bad, as abstracted engine are a powerful concept in Svelto.
however if I leave a global pool, I will need a gain the unique ID.
Let's remember that the only reason Svelto needs ID is to let you us the QueryEntityView(ID) method. This would surely not be needed by an abstracted engine!
This means that I could us an internal global ID somehow for all the entities, and a custom user ID that the user can use only to query entity views inside groups. I see where I can get to from this

OK I believe I may have found a reasonable solution.
I will create a GID as combinaton of group ID and EntityID. In order to achieve this, I cannot allow more than 256 groups and more than 2^24 entities.
seems reasonable right?

How will be the implementation? struct of GID? or int/long type?

OK it's done, I need to do some cleaningup/optimizations and add more tests, but it works. If you want to have a look, you can find it in the database_refactoring branch, I added the branch in the Survival demo too.