Skip to content

Commit

Permalink
Add back deprecated post-mapping methods
Browse files Browse the repository at this point in the history
  • Loading branch information
jrobsonchase committed Jul 31, 2024
1 parent fd136c6 commit f410d21
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions crates/bevy_ecs/src/reflect/map_entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use bevy_reflect::{FromReflect, FromType, Reflect};
#[derive(Clone)]
pub struct ReflectMapEntities {
map_entities: fn(&mut dyn Reflect, &mut dyn DynEntityMapper),
map_all_world_entities: fn(&mut World, &mut SceneEntityMapper),
map_world_entities: fn(&mut World, &mut SceneEntityMapper, &[Entity]),
}

impl ReflectMapEntities {
Expand All @@ -25,6 +27,42 @@ impl ReflectMapEntities {
pub fn map_entities(&self, component: &mut dyn Reflect, mapper: &mut dyn DynEntityMapper) {
(self.map_entities)(component, mapper);
}

/// A general method for applying [`MapEntities`] behavior to all elements in an [`EntityHashMap<Entity>`].
///
/// Be mindful in its usage: Works best in situations where the entities in the [`EntityHashMap<Entity>`] are newly
/// created, before systems have a chance to add new components. If some of the entities referred to
/// by the [`EntityHashMap<Entity>`] might already contain valid entity references, you should use [`map_world_entities`](Self::map_world_entities).
///
/// An example of this: A scene can be loaded with `Parent` components, but then a `Parent` component can be added
/// to these entities after they have been loaded. If you reload the scene using [`map_all_world_entities`](Self::map_all_world_entities), those `Parent`
/// components with already valid entity references could be updated to point at something else entirely.
#[deprecated = "map_all_world_entities doesn't play well with Observers. Use map_entities instead."]
pub fn map_all_world_entities(
&self,
world: &mut World,
entity_map: &mut EntityHashMap<Entity>,
) {
SceneEntityMapper::world_scope(entity_map, world, self.map_all_world_entities);
}

/// A general method for applying [`MapEntities`] behavior to elements in an [`EntityHashMap<Entity>`]. Unlike
/// [`map_all_world_entities`](Self::map_all_world_entities), this is applied to specific entities, not all values
/// in the [`EntityHashMap<Entity>`].
///
/// This is useful mostly for when you need to be careful not to update components that already contain valid entity
/// values. See [`map_all_world_entities`](Self::map_all_world_entities) for more details.
#[deprecated = "map_world_entities doesn't play well with Observers. Use map_entities instead."]
pub fn map_world_entities(
&self,
world: &mut World,
entity_map: &mut EntityHashMap<Entity>,
entities: &[Entity],
) {
SceneEntityMapper::world_scope(entity_map, world, |world, mapper| {
(self.map_world_entities)(world, mapper, entities);
});
}
}

impl<C: Component + MapEntities + Reflect + FromReflect> FromType<C> for ReflectMapEntities {
Expand All @@ -35,6 +73,25 @@ impl<C: Component + MapEntities + Reflect + FromReflect> FromType<C> for Reflect
concrete.map_entities(&mut UnDynEntityMapper(entity_mapper));
component.apply(&concrete as _);
},
map_world_entities: |world, entity_mapper, entities| {
for &entity in entities {
if let Some(mut component) = world.get_mut::<C>(entity) {
component.map_entities(entity_mapper);
}
}
},
map_all_world_entities: |world, entity_mapper| {
let entities = entity_mapper
.get_map()
.values()
.copied()
.collect::<Vec<Entity>>();
for entity in &entities {
if let Some(mut component) = world.get_mut::<C>(*entity) {
component.map_entities(entity_mapper);
}
}
},
}
}
}
Expand Down

0 comments on commit f410d21

Please sign in to comment.