LibGDX/Ashley has a class IntervalIteratingSystem that allows you to process all entities in a particular family every X milliseconds. But if you have a lot of entities to process, it might be a bad idea to do all that at once. For example, if you want to process 10,000 entities once every 10 seconds, you might not actually want to wait 10 seconds, and then process all the entities -- you'd want to "spread it out" over many frames. Perhaps every 100ms you process 100 entities, cycling through them all.
To rephrase: I'd like to process a large number of entities but spread out across multiple frames, preferably:
- providing a reasonable guarantee that all entities will processed at least once every X seconds,
- enabling you to keep track of how much time has passed since that entity was last processed,
- with a random entity order,
- all entities are processed an equal number of times.
Here are my ideas so far...(some bad, some good)
- Every time an entity is added to the
Engine, add a Group1, Group2, or GroupN component (either randomly or sequentially), and then in my EntitySystem I cycle through the various families based on their Group#.
- Every 10 seconds, add all 10,000 entities to a list, and then every 100ms, drain and process 100 from that list. (Memory-intensive, and might fall behind)
- Every 100ms, iterate over all 10,000 entities, but skip 99% of them randomly (either using a PRNG or by checking their hashcode mod prime).
- Maintain a list (a copy, really) of all relevant entities inside an EntitySystem using
Engine#addEntityListener()and then process 1% of the list every 100ms by sequentially stepping through it, and wrapping around when reaching the end. (Uses LibGDX's unordered Array so removals are cheap).
- Same as 4., but rely on
Engine#getEntitiesForand just let Ashley handle ordering and tracking entities instead of keeping a separate list.
At the moment, #1 and #5 seem most promising. #1 seems to meet all my requirements, but is a bit pervasive (creating and adding a bunch of components), #5 is less pervasive, but doesn't meet the requirements quite as well (#2 and #3 mostly).
Thoughts? Is there something better than these?