Make scene handling of entity references robust#7335
Make scene handling of entity references robust#7335alice-i-cecile merged 25 commits intobevyengine:mainfrom
Conversation
alice-i-cecile
left a comment
There was a problem hiding this comment.
Very much like the technical elements of the changes, but this is rather tricky, so I'm being strict on code quality / docs.
I'm not sure I see a good way to do that that both preserves safety and doesn't make the API more awkward. Baked into |
|
Making this controversial because this is taking scene ids in a new-ish direction. Scenes should have "virtual self contained identity spaces" that don't (necessarily) correspond to real world entities. Introducing generation (especially for "top level" entities in the scene) makes the scene format longer / harder to read and compose (just look at the diffs in the scene files). Generation isn't a useful part of the of "scene mental model". Introducing generation also encourages people to think about "runtime ids" as the same thing as scene ids. There is definitely an issue in the current approach when it comes to uniqueness. Some alternative ideas to consider:
Curious what the reflection SMEs think: @MrGVSV @jakobhellermann |
This is very difficult to do because we currently can't look inside components with entity references when serializing, and so we can't allocate SceneIds for dangling references nor serialize component entity references as SceneIds. It would be a much, much larger change to start doing that. The entities in dangling references are only encountered when adding a deserialized scene to the world and no sooner (after both serialization and deserialization).
Amusingly, this is actually what the initial version of this PR did (well, almost: it was I think it makes sense for |
|
(moved back to the 0.10 milestone, but it might be too late at this point so no promises!) |
|
Moving this to 0.11 as it seems like we're going to be shipping 0.10 early today, and this isn't ready yet for a merge. |
But looks like comments were addressed. Or you mean that the approach is controversial? |
|
Need to resolve conflicts and this seems ready for a final review/merge, right? |
alice-i-cecile
left a comment
There was a problem hiding this comment.
@Illiux once this is rebased I think we can merge this ASAP
Shatur
left a comment
There was a problem hiding this comment.
Added a few very minor suggestions.
|
@Illiux I started using this new approach and found mutable world access inconvenient for the |
Objective
Parent'sMapEntitiesimplementation, which would, if the parent was outside the scene, cause the scene to be loaded into the new world with a parent reference potentially pointing to some random entity in that new world.Solution
Entityinstead of a u32, therefore including generationWorldexposes a newreserve_generationsfunction that despawns an entity and advances its generation by some extra amount.MapEntitiesimplementations have a newget_or_reservefunction available that will always return anEntity, establishing a new mapping to a dead entity when the entity they are called with is not in theEntityMap. Subsequent calls with that sameEntitywill return the same newly created dead entity reference, preserving equality semantics.Changelog
Changed
Fixed
Migration Guide
MapEntitiesimplementations must change from a&EntityMapparameter to a&mut EntityMapperparameter and can no longer return aResult. Finally, they should switch from callingEntityMap::getto callingEntityMapper::get_or_reserve.