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

Reserve entities from async #18003

Open
andriyDev opened this issue Feb 23, 2025 · 1 comment · May be fixed by #18195 or #18266
Open

Reserve entities from async #18003

andriyDev opened this issue Feb 23, 2025 · 1 comment · May be fixed by #18195 or #18266
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Blessed Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers

Comments

@andriyDev
Copy link
Contributor

andriyDev commented Feb 23, 2025

What problem does this solve or what need does it fill?

  1. The asset system needs to support creating new asset handles in an AssetLoader in order to load dependencies (e.g., a material asset needs to load a separate PNG asset and include that handle in the material). Assets as Entities #11266 aims to make asset handles a wrapper around an Entity, therefore we need to be able to reserve an entity in async contexts.
  2. If you want to asynchronously generate some entities, you must use CommandQueue. The main limitation it has is that you cannot spawn entities and get its id - you can only queue a command that uses the ID internally. This makes it difficult to generate relationships between entities without just putting everything in one big command.

What solution would you like?

We should allow entities to be reserved asynchronously. We mostly have this already as systems can reserve entities multithreaded. One thing that's missing is being able to get an Arc for the Entities (or similar) to pass to async code.

Risks

  1. We "flush" Entities to turn the reserved IDs into allocated IDs. This means we either need to be really clever with how we flush, or we need to just lock everything whenever we do a flush. This will likely have some synchronization overhead that may affect non-async code.
  2. Exclusive world access uses a "fast path" for allocating entities: Entities::alloc. We can't really use this anymore, since asynchronous code could have reserved the entity we would just be allocating. This is a performance concern even for exclusive world access. Note we likely can't "specialize" whether Entities is aliased (e.g., if there is no async users, use the fast path), since something like assets-as-entities will need to perpetually hold a reference (i.e., Arc) so the AssetServer can pass it to async at any point.

Alternatives

Rather than try to make Entities work fully multithreaded, we can instead make reserving an entity an async operation. In other words, we could have something like Res<AsyncEntityReserver>. You would pass this into an async closure and call reserver.reserve_entity().await. This would enqueue a request for an entity. In Bevy, we'd have a system that looks at this queue allocates an entity from the system using regular commands, and then responds with that entity's ID back to the async closure (i.e., through an async channel).

In regards to Assets-as-entities, this means that loading a dependency in an AssetLoader is now an async operation, which is quite sad (load_context.loader().load("some_other_asset.txt").await). In addition, loading assets this way would be slower, requiring waiting a frame to elapse before moving loading forward.

@andriyDev andriyDev added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled A-ECS Entities, components, systems, and events D-Complex Quite challenging from either a design or technical perspective. Ask for help! labels Feb 23, 2025
@alice-i-cecile alice-i-cecile added S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Blessed Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers and removed S-Needs-Triage This issue needs to be labelled labels Feb 23, 2025
@alice-i-cecile
Copy link
Member

To explain my labelling a bit:

  • this is a tricky issue that will likely require tradeoffs to solve, simply due to how hot the entity reservation code is
  • everyone agrees that assets-as-entities is superior and important
  • everyone agrees that async entity reservation is the critical blocker there, following Cart's exploratory work
  • we're not sure on the best way to do async entity reservation

I personally think that #17701 is the right primitive for this, but I'd appreciate more opinions from folks who are more experienced with async.

@andriyDev andriyDev linked a pull request Mar 7, 2025 that will close this issue
@ElliottjPierce ElliottjPierce linked a pull request Mar 11, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Feature A new feature, making something new possible D-Complex Quite challenging from either a design or technical perspective. Ask for help! S-Needs-Design This issue requires design work to think about how it would best be accomplished X-Blessed Has a large architectural impact or tradeoffs, but the design has been endorsed by decision makers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants