Reserve entities from async #18003
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
What problem does this solve or what need does it fill?
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 anEntity
, therefore we need to be able to reserve an entity in async contexts.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 theEntities
(or similar) to pass to async code.Risks
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.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" whetherEntities
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 theAssetServer
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 likeRes<AsyncEntityReserver>
. You would pass this into an async closure and callreserver.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.The text was updated successfully, but these errors were encountered: