Skip to content

Commit

Permalink
Try #7570:
Browse files Browse the repository at this point in the history
  • Loading branch information
bors[bot] authored Feb 8, 2023
2 parents 09cb590 + d535c42 commit 086c731
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
17 changes: 13 additions & 4 deletions crates/bevy_ecs/src/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ impl_from_reflect_value!(Entity);

#[derive(Clone)]
pub struct ReflectMapEntities {
map_entities: fn(&mut World, &EntityMap) -> Result<(), MapEntitiesError>,
map_entities: fn(&mut World, &EntityMap, Vec<Entity>) -> Result<(), MapEntitiesError>,
}

impl ReflectMapEntities {
Expand All @@ -418,15 +418,24 @@ impl ReflectMapEntities {
world: &mut World,
entity_map: &EntityMap,
) -> Result<(), MapEntitiesError> {
(self.map_entities)(world, entity_map)
(self.map_entities)(world, entity_map, entity_map.values().collect())
}

pub fn map_specific_entities(
&self,
world: &mut World,
entity_map: &EntityMap,
entities: Vec<Entity>,
) -> Result<(), MapEntitiesError> {
(self.map_entities)(world, entity_map, entities)
}
}

impl<C: Component + MapEntities> FromType<C> for ReflectMapEntities {
fn from_type() -> Self {
ReflectMapEntities {
map_entities: |world, entity_map| {
for entity in entity_map.values() {
map_entities: |world, entity_map, entities| {
for entity in entities {
if let Some(mut component) = world.get_mut::<C>(entity) {
component.map_entities(entity_map)?;
}
Expand Down
21 changes: 19 additions & 2 deletions crates/bevy_scene/src/dynamic_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use bevy_ecs::{
world::World,
};
use bevy_reflect::{Reflect, TypeRegistryArc, TypeUuid};
use bevy_utils::HashMap;

#[cfg(feature = "serialize")]
use crate::serde::SceneSerializer;
Expand Down Expand Up @@ -64,6 +65,11 @@ impl DynamicScene {
) -> Result<(), SceneSpawnError> {
let type_registry = type_registry.read();

// Collection of entities that have references to entities in the scene,
// that need to be updated to entities in the world.
// Keyed by Component's TypeId.
let mut entity_mapped_entities = HashMap::default();

for scene_entity in &self.entities {
// Fetch the entity with the given entity id from the `entity_map`
// or spawn a new entity with a transiently unique id if there is
Expand All @@ -87,17 +93,28 @@ impl DynamicScene {
}
})?;

// If this component references entities in the scene, track it
// so we can update it to the entity in the world.
if registration.data::<ReflectMapEntities>().is_some() {
entity_mapped_entities
.entry(registration.type_id())
.or_insert(Vec::new())
.push(entity);
}

// If the entity already has the given component attached,
// just apply the (possibly) new value, otherwise add the
// component to the entity.
reflect_component.apply_or_insert(entity_mut, &**component);
}
}

for registration in type_registry.iter() {
// Updates references to entities in the scene to entities in the world
for (type_id, entities) in entity_mapped_entities.into_iter() {
let registration = type_registry.get(type_id).unwrap();
if let Some(map_entities_reflect) = registration.data::<ReflectMapEntities>() {
map_entities_reflect
.map_entities(world, entity_map)
.map_specific_entities(world, entity_map, entities)
.unwrap();
}
}
Expand Down

0 comments on commit 086c731

Please sign in to comment.