Skip to content
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

Empty archetypes #66

Open
Ratysz opened this issue Jun 30, 2020 · 3 comments
Open

Empty archetypes #66

Ratysz opened this issue Jun 30, 2020 · 3 comments

Comments

@Ratysz
Copy link
Contributor

Ratysz commented Jun 30, 2020

Despawning all entities of an archetype doesn't remove that archetype from the world, and doesn't advance archetype generation.

This is problematic for something like my library yaks, because it causes tests like this one to fail - summarized, it:

  • spawns some entities of two different types,
  • creates an executor with two systems that are disjoint (by resources and archetypes, but not by components, here meaning they modify the same type of component, but can be ran concurrently as long as their queries don't overlap on an archetype),
  • verifies that the systems run concurrently,
  • spawns some entities of a type that satisfies queries of both systems,
  • verifies that this forces the systems to run sequentially,
  • despawns all entities of that third type,
  • (unsuccessfully) verifies that the systems are ran concurrently again.

This means that as soon as a system-straddling entity is spawned those systems are forbidden from running concurrently until the world is recreated.

I see these approaches so far:

  • automatically removing archetypes once they are empty and advancing the archetype generation,
  • some form of World::defrag() that purges empty archetypes and advances the generation,
  • tacking the function of said ::defrag() onto World::flush(),
  • exposing Archetype::len() and/or ::is_empty(), and... advancing the generation once an archetype is empty?

The problem with last approach is obvious - the archetypes don't actually change - but there needs to be some mechanism of informing user code.

@Ralith
Copy link
Owner

Ralith commented Jun 30, 2020

It's intentional that the archetype sticks around; my thinking that if a certain combination of components existed once, it'll probably exist again, and this way we save some allocator pressure. That said, I agree that empty archetypes forcing serialization of queries is a bit silly.

I'm not opposed to an explicit method to drop empty archetypes to recover memory, but I don't think it's a good solution to this specific problem due to the performance consequences described above.

I think the way forward here is to provide an interface that behaves as if empty archetypes do not exist, even though their storage is retained. This should actually be pretty easy: slap a filter on to archetypes (dropping ExactSize in the process unless there's really a need for it) and take care to skip empty archetypes in dynamic borrow checking and to increment the generation when an archetype becomes empty.

@Ratysz
Copy link
Contributor Author

Ratysz commented Jun 30, 2020

Well, this is how my usage of current API looks like - so, yes, adding a filter is an obvious idea, hence why I suggested exposing Archetype::is_empty(). Ditching of ExactSize is not that big of an issue either; it's the archetype generation that I'm worried about.

@Ralith
Copy link
Owner

Ralith commented Jul 1, 2020

Updating the generation when an archetype becomes empty should handle that fine. Doing the filtering internally avoids expanding the API, which is desirable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants