Skip to content

Commit 7b316af

Browse files
committed
make ReflectMapEntities match MapEntities
2 parents b411dac + 42d8b65 commit 7b316af

File tree

20 files changed

+251
-82
lines changed

20 files changed

+251
-82
lines changed

crates/bevy_animation/src/lib.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::{
1919
collections::BTreeMap,
2020
fmt::Debug,
2121
hash::{Hash, Hasher},
22-
iter,
22+
iter, option,
2323
};
2424

2525
use bevy_app::{App, Plugin, PostUpdate};
@@ -1291,9 +1291,19 @@ impl From<&Name> for AnimationTargetId {
12911291
}
12921292
}
12931293

1294-
impl MapEntities for AnimationTarget {
1295-
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
1296-
self.player = entity_mapper.map_entity(self.player);
1294+
impl<'a> IntoIterator for &'a mut AnimationTarget {
1295+
type IntoIter = option::IntoIter<&'a mut Entity>;
1296+
type Item = <Self::IntoIter as Iterator>::Item;
1297+
fn into_iter(self) -> Self::IntoIter {
1298+
Some(&mut self.player).into_iter()
1299+
}
1300+
}
1301+
1302+
impl<'a> IntoIterator for &'a AnimationTarget {
1303+
type IntoIter = option::IntoIter<Entity>;
1304+
type Item = <Self::IntoIter as Iterator>::Item;
1305+
fn into_iter(self) -> Self::IntoIter {
1306+
Some(self.player).into_iter()
12971307
}
12981308
}
12991309

crates/bevy_ecs/src/entity/map_entities.rs

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,56 @@ use super::EntityHashMap;
3838
/// }
3939
/// ```
4040
pub trait MapEntities {
41-
/// Updates all [`Entity`] references stored inside using `entity_mapper`.
42-
///
43-
/// Implementors should look up any and all [`Entity`] values stored within `self` and
44-
/// update them to the mapped values via `entity_mapper`.
45-
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M);
41+
fn map_entities<F: FnMut(Entity)>(&self, f: F);
42+
}
43+
44+
pub trait MapEntitiesMut: MapEntities {
45+
fn map_entities_mut<F: FnMut(&mut Entity)>(&mut self, f: F);
46+
}
47+
48+
impl<T> MapEntities for T
49+
where
50+
T: IterEntities,
51+
{
52+
fn map_entities<F: FnMut(Entity)>(&self, f: F) {
53+
self.iter_entities().for_each(f)
54+
}
55+
}
56+
57+
impl<T> MapEntitiesMut for T
58+
where
59+
T: MapEntities + IterEntitiesMut,
60+
{
61+
fn map_entities_mut<F: FnMut(&mut Entity)>(&mut self, f: F) {
62+
self.iter_entities_mut().for_each(f)
63+
}
64+
}
65+
66+
pub trait IterEntities {
67+
fn iter_entities(&self) -> impl Iterator<Item = Entity>;
68+
}
69+
70+
impl<T> IterEntities for T
71+
where
72+
for<'a> &'a T: IntoIterator<Item = Entity>,
73+
{
74+
fn iter_entities(&self) -> impl Iterator<Item = Entity> {
75+
self.into_iter()
76+
}
77+
}
78+
79+
pub trait IterEntitiesMut: IterEntities {
80+
fn iter_entities_mut(&mut self) -> impl Iterator<Item = &mut Entity>;
81+
}
82+
83+
impl<T> IterEntitiesMut for T
84+
where
85+
for<'a> &'a mut T: IntoIterator<Item = &'a mut Entity>,
86+
T: IterEntities,
87+
{
88+
fn iter_entities_mut(&mut self) -> impl Iterator<Item = &mut Entity> {
89+
self.into_iter()
90+
}
4691
}
4792

4893
/// An implementor of this trait knows how to map an [`Entity`] into another [`Entity`].

crates/bevy_ecs/src/reflect/map_entities.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{
22
component::Component,
3-
entity::{Entity, EntityHashMap, MapEntities, SceneEntityMapper},
3+
entity::{Entity, EntityHashMap, EntityMapper, MapEntities, MapEntitiesMut, SceneEntityMapper},
44
world::World,
55
};
6-
use bevy_reflect::FromType;
6+
use bevy_reflect::{FromReflect, FromType, PartialReflect};
77

88
/// For a specific type of component, this maps any fields with values of type [`Entity`] to a new world.
99
///
@@ -15,6 +15,8 @@ use bevy_reflect::FromType;
1515
pub struct ReflectMapEntities {
1616
map_all_world_entities: fn(&mut World, &mut SceneEntityMapper),
1717
map_world_entities: fn(&mut World, &mut SceneEntityMapper, &[Entity]),
18+
map_entities_mut: fn(&mut dyn PartialReflect, &mut dyn FnMut(&mut Entity)),
19+
map_entities: fn(&dyn PartialReflect, &mut dyn FnMut(Entity)),
1820
}
1921

2022
impl ReflectMapEntities {
@@ -51,15 +53,29 @@ impl ReflectMapEntities {
5153
(self.map_world_entities)(world, mapper, entities);
5254
});
5355
}
56+
57+
pub fn map_entities(&self, component: &dyn PartialReflect, f: &mut dyn FnMut(Entity)) {
58+
(self.map_entities)(component, f)
59+
}
60+
61+
pub fn map_entities_mut(
62+
&self,
63+
component: &mut dyn PartialReflect,
64+
f: &mut dyn FnMut(&mut Entity),
65+
) {
66+
(self.map_entities_mut)(component, f)
67+
}
5468
}
5569

56-
impl<C: Component + MapEntities> FromType<C> for ReflectMapEntities {
70+
impl<C: Component + FromReflect + MapEntitiesMut> FromType<C> for ReflectMapEntities {
5771
fn from_type() -> Self {
5872
ReflectMapEntities {
5973
map_world_entities: |world, entity_mapper, entities| {
6074
for &entity in entities {
6175
if let Some(mut component) = world.get_mut::<C>(entity) {
62-
component.map_entities(entity_mapper);
76+
component.map_entities_mut(|entity| {
77+
*entity = entity_mapper.map_entity(*entity);
78+
});
6379
}
6480
}
6581
},
@@ -71,10 +87,21 @@ impl<C: Component + MapEntities> FromType<C> for ReflectMapEntities {
7187
.collect::<Vec<Entity>>();
7288
for entity in &entities {
7389
if let Some(mut component) = world.get_mut::<C>(*entity) {
74-
component.map_entities(entity_mapper);
90+
component.map_entities_mut(|entity| {
91+
*entity = entity_mapper.map_entity(*entity);
92+
});
7593
}
7694
}
7795
},
96+
map_entities: |component, f| {
97+
let concrete = C::from_reflect(component).unwrap();
98+
concrete.map_entities(f);
99+
},
100+
map_entities_mut: |component, f| {
101+
let mut concrete = C::from_reflect(component).unwrap();
102+
concrete.map_entities_mut(f);
103+
component.apply(&concrete);
104+
},
78105
}
79106
}
80107
}
@@ -99,12 +126,14 @@ impl ReflectMapEntitiesResource {
99126
}
100127
}
101128

102-
impl<R: crate::system::Resource + MapEntities> FromType<R> for ReflectMapEntitiesResource {
129+
impl<R: crate::system::Resource + MapEntitiesMut> FromType<R> for ReflectMapEntitiesResource {
103130
fn from_type() -> Self {
104131
ReflectMapEntitiesResource {
105132
map_entities: |world, entity_mapper| {
106133
if let Some(mut resource) = world.get_resource_mut::<R>() {
107-
resource.map_entities(entity_mapper);
134+
resource.map_entities_mut(|entity| {
135+
*entity = entity_mapper.map_entity(*entity);
136+
});
108137
}
109138
},
110139
}

crates/bevy_hierarchy/src/components/children.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use bevy_ecs::reflect::{ReflectComponent, ReflectFromWorld, ReflectMapEntities};
33
use bevy_ecs::{
44
component::Component,
5-
entity::{Entity, EntityMapper, MapEntities},
5+
entity::{Entity, MapEntitiesMut},
66
prelude::FromWorld,
77
world::World,
88
};
@@ -28,14 +28,6 @@ use std::ops::Deref;
2828
#[cfg_attr(feature = "reflect", reflect(Component, MapEntities, Debug, FromWorld))]
2929
pub struct Children(pub(crate) SmallVec<[Entity; 8]>);
3030

31-
impl MapEntities for Children {
32-
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
33-
for entity in &mut self.0 {
34-
*entity = entity_mapper.map_entity(*entity);
35-
}
36-
}
37-
}
38-
3931
// TODO: We need to impl either FromWorld or Default so Children can be registered as Reflect.
4032
// This is because Reflect deserialize by creating an instance and apply a patch on top.
4133
// However Children should only ever be set with a real user-defined entities. Its worth looking
@@ -152,13 +144,36 @@ impl Deref for Children {
152144
}
153145
}
154146

147+
impl<'a> IntoIterator for &'a mut Children {
148+
type Item = <Self::IntoIter as Iterator>::Item;
149+
150+
type IntoIter = slice::IterMut<'a, Entity>;
151+
152+
#[inline(always)]
153+
fn into_iter(self) -> Self::IntoIter {
154+
self.0.iter_mut()
155+
}
156+
}
157+
155158
impl<'a> IntoIterator for &'a Children {
156159
type Item = <Self::IntoIter as Iterator>::Item;
157160

158-
type IntoIter = slice::Iter<'a, Entity>;
161+
type IntoIter = std::iter::Copied<slice::Iter<'a, Entity>>;
159162

160163
#[inline(always)]
161164
fn into_iter(self) -> Self::IntoIter {
162-
self.0.iter()
165+
self.0.iter().copied()
166+
}
167+
}
168+
169+
#[cfg(test)]
170+
mod test {
171+
use super::*;
172+
173+
fn assert_impls_map_entities_mut<M: MapEntitiesMut>() {}
174+
175+
#[test]
176+
fn children_impls_map_entities_mut() {
177+
assert_impls_map_entities_mut::<Children>();
163178
}
164179
}

crates/bevy_hierarchy/src/components/parent.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
use bevy_ecs::reflect::{ReflectComponent, ReflectFromWorld, ReflectMapEntities};
33
use bevy_ecs::{
44
component::Component,
5-
entity::{Entity, EntityMapper, MapEntities},
5+
entity::Entity,
66
traversal::Traversal,
77
world::{FromWorld, World},
88
};
9-
use std::ops::Deref;
9+
use std::{ops::Deref, option};
1010

1111
/// Holds a reference to the parent entity of this entity.
1212
/// This component should only be present on entities that actually have a parent entity.
@@ -59,9 +59,21 @@ impl FromWorld for Parent {
5959
}
6060
}
6161

62-
impl MapEntities for Parent {
63-
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
64-
self.0 = entity_mapper.map_entity(self.0);
62+
impl<'a> IntoIterator for &'a Parent {
63+
type Item = Entity;
64+
type IntoIter = option::IntoIter<Entity>;
65+
66+
fn into_iter(self) -> Self::IntoIter {
67+
Some(self.0).into_iter()
68+
}
69+
}
70+
71+
impl<'a> IntoIterator for &'a mut Parent {
72+
type Item = &'a mut Entity;
73+
type IntoIter = option::IntoIter<&'a mut Entity>;
74+
75+
fn into_iter(self) -> Self::IntoIter {
76+
Some(&mut self.0).into_iter()
6577
}
6678
}
6779

crates/bevy_hierarchy/src/query_extension.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,7 @@ where
9292
pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
9393
DescendantIter {
9494
children_query,
95-
vecdeque: children_query
96-
.get(entity)
97-
.into_iter()
98-
.flatten()
99-
.copied()
100-
.collect(),
95+
vecdeque: children_query.get(entity).into_iter().flatten().collect(),
10196
}
10297
}
10398
}

crates/bevy_render/src/mesh/mesh/skinning.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,21 @@ pub struct SkinnedMesh {
1616
pub joints: Vec<Entity>,
1717
}
1818

19-
impl MapEntities for SkinnedMesh {
20-
fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {
21-
for joint in &mut self.joints {
22-
*joint = entity_mapper.map_entity(*joint);
23-
}
19+
impl<'a> IntoIterator for &'a mut SkinnedMesh {
20+
type IntoIter = std::slice::IterMut<'a, Entity>;
21+
type Item = <Self::IntoIter as Iterator>::Item;
22+
23+
fn into_iter(self) -> Self::IntoIter {
24+
self.joints.iter_mut()
25+
}
26+
}
27+
28+
impl<'a> IntoIterator for &'a SkinnedMesh {
29+
type IntoIter = std::iter::Copied<std::slice::Iter<'a, Entity>>;
30+
type Item = <Self::IntoIter as Iterator>::Item;
31+
32+
fn into_iter(self) -> Self::IntoIter {
33+
self.joints.iter().copied()
2434
}
2535
}
2636

crates/bevy_render/src/view/visibility/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ fn visibility_propagate_system(
370370
inherited_visibility.0 = is_visible;
371371

372372
// Recursively update the visibility of each child.
373-
for &child in children.into_iter().flatten() {
373+
for child in children.into_iter().flatten() {
374374
let _ =
375375
propagate_recursive(is_visible, child, &mut visibility_query, &children_query);
376376
}
@@ -401,7 +401,7 @@ fn propagate_recursive(
401401
inherited_visibility.0 = is_visible;
402402

403403
// Recursively update the visibility of each child.
404-
for &child in children_query.get(entity).ok().into_iter().flatten() {
404+
for child in children_query.get(entity).ok().into_iter().flatten() {
405405
let _ = propagate_recursive(is_visible, child, visibility_query, children_query);
406406
}
407407
}

0 commit comments

Comments
 (0)