-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Reserve entities from async #18003
Copy link
Copy link
Closed
Labels
A-ECSEntities, components, systems, and eventsEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleA new feature, making something new possibleD-ComplexQuite challenging from either a design or technical perspective. Ask for help!Quite challenging from either a design or technical perspective. Ask for help!S-Needs-DesignThis issue requires design work to think about how it would best be accomplishedThis issue requires design work to think about how it would best be accomplishedX-BlessedHas a large architectural impact or tradeoffs, but the design has been endorsed by decision makersHas a large architectural impact or tradeoffs, but the design has been endorsed by decision makers
Metadata
Metadata
Assignees
Labels
A-ECSEntities, components, systems, and eventsEntities, components, systems, and eventsC-FeatureA new feature, making something new possibleA new feature, making something new possibleD-ComplexQuite challenging from either a design or technical perspective. Ask for help!Quite challenging from either a design or technical perspective. Ask for help!S-Needs-DesignThis issue requires design work to think about how it would best be accomplishedThis issue requires design work to think about how it would best be accomplishedX-BlessedHas a large architectural impact or tradeoffs, but the design has been endorsed by decision makersHas 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?
AssetLoaderin 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
Arcfor theEntities(or similar) to pass to async code.Risks
Entitiesto 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" whetherEntitiesis 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 theAssetServercan pass it to async at any point.Alternatives
Rather than try to make
Entitieswork 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
AssetLoaderis 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.