-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Many to one #118
Comments
hum EntityMultiMap is the inverse of what you want I think, many entities for one component value. For an entity to hold multiple components of the same type, you would have to use a collection as component type: |
That’s a definitely a clean solution, but then all the components are in separate allocations and there’s no cache coherent global iteration over all the components. It also can trigger a lot of allocations. I really like how clean the solution is.
I think that the only way to maybe make it easier is to provide a pooled chunk allocator. I’ll see if i can find one and post a simple extension.
… On Jul 2, 2021, at 12:57 AM, Paillat Laszlo ***@***.***> wrote:
hum EntityMultiMap is the inverse of what you want I think, many entities for one component value. For an entity to hold multiple components of the same type, you would have to use a collection as component type: entity.Set(new List<MyComponent>{ ... }) and create your query accordingly With<List<MyComponent>>(). Would that work for you? I don't know what could be added to make it easier.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Yeah the allocation thing is why I didn't want to handle it ^^" That's more or less how the old child/parent relationship worked before, I was so displeased with the implementation that I just removed it completely. |
I’ve been looking at these today:
https://github.com/jtmueller/Collections.Pooled
https://github.com/faustodavid/ListPool
That if rolled into some kind of extension it could be pretty powerful. Especially if the disposal was handled nicely.
I’ll keep looking at the problem and see if I can put together an extension I’m happy with.
You made the right call to keep the whole parent / child thing out of the core.
…
AOn Jul 2, 2021, at 8:22 AM, Paillat Laszlo ***@***.***> wrote:
Yeah the allocation thing is why I didn't want to handle it ^^" That's more or less how the old child/parent relationship worked before, I was so displeased with the implementation that I just removed it completely.
I may have an idea on how to do it properly, in the internal storage components have some extra infos (parent entity id, number of parents). Maybe it is possible to construct a linked list of components by adding a "next id" on the internal storage to keep cache coherence and minimise allocation while keeping fast add/remove.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Components are not disposed even if they implement IDisposable once removed (seemed a little too much magic to me and not always what we want) but you can add it by using https://github.com/Doraku/DefaultEcs/blob/master/documentation/api/World_SubscribeComponentRemoved_T_(ComponentRemovedHandler_T_).md |
Is there a call to get the other entities on the other side of a shared component?
… On Jul 2, 2021, at 09:07, Paillat Laszlo ***@***.***> wrote:
Components are not disposed even if they implement IDisposable once removed (seemed a little too much magic to me and not always what we want) but you can add it by using https://github.com/Doraku/DefaultEcs/blob/master/documentation/api/World_SubscribeComponentRemoved_T_(ComponentRemovedHandler_T_).md
Your callback should be called even when the entity or the world is disposed. The problem is if you share the same pool between multiple entities :/
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Not with the way it works for now. The component only store the first entity that references it and the total number of references, so I don't need an other collection that could allocate. We could check for every entities but then it would be too costly to use in hot paths. If my idea to handle multiple components of the same type on a single entity works it should be possible to add something for that. |
I’ve been thinking about simply reversing the relationship and doing accumulation and iteration from the outside -> in.
There would be many entities with component B. Each of those would share a component A which would contain a reference to the owner.
This follows your architecture more closely.
It makes it harder to iterate across all owners, but for most applications its likely fine to iterate across all children.
For parallelism, I wish I could rely on all children sharing the same component all being on the same thread, but that’s probably too much to ask.
Anyway, thanks for the info.
Again, great work with the system.
… On Jul 11, 2021, at 2:30 PM, Paillat Laszlo ***@***.***> wrote:
Not with the way it works for now. The component only store the first entity that references it and the total number of references, so I don't need an other collection that could allocate. We could check for every entities but then it would be too costly to use in hot paths. If my idea to handle multiple components of the same type on a single entity works it should be possible to add something for that.
In the meantime I guess you could use EntityMultiMap if your component is a class or the struct values are unique.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub <#118 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABA3VTMFLOSRWQBS2GHLRRDTXIEPJANCNFSM47VVVDDA>.
|
Some thinking I have done on this issue: namespace DefaultEcs.Technical
{
internal struct ComponentLink
{
#region Fields
public int EntityId;
public int ReferenceCount;
#endregion
#region Initialisation
public ComponentLink(int entityId)
{
EntityId = entityId;
ReferenceCount = 1;
}
#endregion
}
} by adding a new field to save the next component, allowing us to have a linked list of component for an entity. They would still be in the same array and it should be possible to tweak the
The main problem with this scenario is when entities share component. Normally when you remove the component from one entity, the others sharing it keep the value. But because this would be a linked list, if we remove the first component for one entity, the others will still point to the first component of the linked list. The reference count would be a mess to keep updated to. I wondering if it would be better to forbid component sharing when you have multiple values. Just typing it all to help thinking. |
I think this is an excellent solution. As a start, I think choosing between sharing and multiples is a fine choice. If you use one, you can’t use the other. |
I’ve started using Haxe in addition to c#. If you should ever feel like you are looking for a new project, may I suggest porting your ecs to haxe? Your ECS is the best IMO and haxe is a better language than c# for game dev. |
Sorry if this has been asked before.
what is the best way to do a one entity to many component relationship where one entity ‘owns’ many components of a certain type? Ideally one where you can easily iterate over an entities set of related components.
unity uses some chunked system to make an array component or something like that. I can’t find anything in the Default ecs other than using an entity multit-map.
The text was updated successfully, but these errors were encountered: