1pub use bevy_ecs_macros::MapEntities;
2use indexmap::{IndexMap, IndexSet};
3
4use crate::{
5 entity::{hash_map::EntityHashMap, Entity},
6 world::World,
7};
8
9use alloc::{
10 collections::{BTreeMap, BTreeSet, VecDeque},
11 vec::Vec,
12};
13use bevy_platform::collections::{HashMap, HashSet};
14use core::{
15 hash::{BuildHasher, Hash},
16 mem,
17};
18use smallvec::SmallVec;
19
20use super::EntityIndexSet;
21
22pub trait MapEntities {
57 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E);
62}
63
64impl MapEntities for Entity {
65 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
66 *self = entity_mapper.get_mapped(*self);
67 }
68}
69
70impl<T: MapEntities> MapEntities for Option<T> {
71 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
72 if let Some(entities) = self {
73 entities.map_entities(entity_mapper);
74 }
75 }
76}
77
78impl<K: MapEntities + Eq + Hash, V: MapEntities, S: BuildHasher + Default> MapEntities
79 for HashMap<K, V, S>
80{
81 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
82 *self = self
83 .drain()
84 .map(|(mut key_entities, mut value_entities)| {
85 key_entities.map_entities(entity_mapper);
86 value_entities.map_entities(entity_mapper);
87 (key_entities, value_entities)
88 })
89 .collect();
90 }
91}
92
93impl<T: MapEntities + Eq + Hash, S: BuildHasher + Default> MapEntities for HashSet<T, S> {
94 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
95 *self = self
96 .drain()
97 .map(|mut entities| {
98 entities.map_entities(entity_mapper);
99 entities
100 })
101 .collect();
102 }
103}
104
105impl<K: MapEntities + Eq + Hash, V: MapEntities, S: BuildHasher + Default> MapEntities
106 for IndexMap<K, V, S>
107{
108 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
109 *self = self
110 .drain(..)
111 .map(|(mut key_entities, mut value_entities)| {
112 key_entities.map_entities(entity_mapper);
113 value_entities.map_entities(entity_mapper);
114 (key_entities, value_entities)
115 })
116 .collect();
117 }
118}
119
120impl<T: MapEntities + Eq + Hash, S: BuildHasher + Default> MapEntities for IndexSet<T, S> {
121 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
122 *self = self
123 .drain(..)
124 .map(|mut entities| {
125 entities.map_entities(entity_mapper);
126 entities
127 })
128 .collect();
129 }
130}
131
132impl MapEntities for EntityIndexSet {
133 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
134 *self = self
135 .drain(..)
136 .map(|e| entity_mapper.get_mapped(e))
137 .collect();
138 }
139}
140
141impl<K: MapEntities + Ord, V: MapEntities> MapEntities for BTreeMap<K, V> {
142 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
143 *self = mem::take(self)
144 .into_iter()
145 .map(|(mut key_entities, mut value_entities)| {
146 key_entities.map_entities(entity_mapper);
147 value_entities.map_entities(entity_mapper);
148 (key_entities, value_entities)
149 })
150 .collect();
151 }
152}
153
154impl<T: MapEntities + Ord> MapEntities for BTreeSet<T> {
155 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
156 *self = mem::take(self)
157 .into_iter()
158 .map(|mut entities| {
159 entities.map_entities(entity_mapper);
160 entities
161 })
162 .collect();
163 }
164}
165
166impl<T: MapEntities, const N: usize> MapEntities for [T; N] {
167 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
168 for entities in self.iter_mut() {
169 entities.map_entities(entity_mapper);
170 }
171 }
172}
173
174impl<T: MapEntities> MapEntities for Vec<T> {
175 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
176 for entities in self.iter_mut() {
177 entities.map_entities(entity_mapper);
178 }
179 }
180}
181
182impl<T: MapEntities> MapEntities for VecDeque<T> {
183 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
184 for entities in self.iter_mut() {
185 entities.map_entities(entity_mapper);
186 }
187 }
188}
189
190impl<T: MapEntities, A: smallvec::Array<Item = T>> MapEntities for SmallVec<A> {
191 fn map_entities<E: EntityMapper>(&mut self, entity_mapper: &mut E) {
192 for entities in self.iter_mut() {
193 entities.map_entities(entity_mapper);
194 }
195 }
196}
197
198pub trait EntityMapper {
230 fn get_mapped(&mut self, source: Entity) -> Entity;
232
233 fn set_mapped(&mut self, source: Entity, target: Entity);
236}
237
238impl EntityMapper for () {
239 #[inline]
240 fn get_mapped(&mut self, source: Entity) -> Entity {
241 source
242 }
243
244 #[inline]
245 fn set_mapped(&mut self, _source: Entity, _target: Entity) {}
246}
247
248impl EntityMapper for (Entity, Entity) {
249 #[inline]
250 fn get_mapped(&mut self, source: Entity) -> Entity {
251 if source == self.0 {
252 self.1
253 } else {
254 source
255 }
256 }
257
258 fn set_mapped(&mut self, _source: Entity, _target: Entity) {}
259}
260
261impl EntityMapper for &mut dyn EntityMapper {
262 fn get_mapped(&mut self, source: Entity) -> Entity {
263 (*self).get_mapped(source)
264 }
265
266 fn set_mapped(&mut self, source: Entity, target: Entity) {
267 (*self).set_mapped(source, target);
268 }
269}
270
271impl EntityMapper for SceneEntityMapper<'_> {
272 fn get_mapped(&mut self, source: Entity) -> Entity {
274 if let Some(&mapped) = self.map.get(&source) {
275 return mapped;
276 }
277
278 let new = Entity::from_row_and_generation(
280 self.dead_start.row(),
281 self.dead_start.generation.after_versions(self.generations),
282 );
283 self.generations = self.generations.wrapping_add(1);
284
285 self.map.insert(source, new);
286
287 new
288 }
289
290 fn set_mapped(&mut self, source: Entity, target: Entity) {
291 self.map.insert(source, target);
292 }
293}
294
295impl EntityMapper for EntityHashMap<Entity> {
296 fn get_mapped(&mut self, source: Entity) -> Entity {
298 self.get(&source).cloned().unwrap_or(source)
299 }
300
301 fn set_mapped(&mut self, source: Entity, target: Entity) {
302 self.insert(source, target);
303 }
304}
305
306pub struct SceneEntityMapper<'m> {
312 map: &'m mut EntityHashMap<Entity>,
321 dead_start: Entity,
323 generations: u32,
325}
326
327impl<'m> SceneEntityMapper<'m> {
328 pub fn get_map(&'m self) -> &'m EntityHashMap<Entity> {
330 self.map
331 }
332
333 pub fn get_map_mut(&'m mut self) -> &'m mut EntityHashMap<Entity> {
335 self.map
336 }
337
338 pub fn new(map: &'m mut EntityHashMap<Entity>, world: &mut World) -> Self {
340 world.flush_entities();
343 Self {
344 map,
345 dead_start: unsafe { world.entities_mut().alloc() },
347 generations: 0,
348 }
349 }
350
351 pub fn finish(self, world: &mut World) {
355 let entities = unsafe { world.entities_mut() };
357 assert!(entities.free(self.dead_start).is_some());
358 assert!(entities.reserve_generations(self.dead_start.index(), self.generations));
359 }
360
361 pub fn world_scope<R>(
368 entity_map: &'m mut EntityHashMap<Entity>,
369 world: &mut World,
370 f: impl FnOnce(&mut World, &mut Self) -> R,
371 ) -> R {
372 let mut mapper = Self::new(entity_map, world);
373 let result = f(world, &mut mapper);
374 mapper.finish(world);
375 result
376 }
377}
378
379#[cfg(test)]
380mod tests {
381
382 use crate::{
383 entity::{Entity, EntityHashMap, EntityMapper, SceneEntityMapper},
384 world::World,
385 };
386
387 #[test]
388 fn entity_mapper() {
389 let mut map = EntityHashMap::default();
390 let mut world = World::new();
391 let mut mapper = SceneEntityMapper::new(&mut map, &mut world);
392
393 let mapped_ent = Entity::from_raw_u32(1).unwrap();
394 let dead_ref = mapper.get_mapped(mapped_ent);
395
396 assert_eq!(
397 dead_ref,
398 mapper.get_mapped(mapped_ent),
399 "should persist the allocated mapping from the previous line"
400 );
401 assert_eq!(
402 mapper.get_mapped(Entity::from_raw_u32(2).unwrap()).index(),
403 dead_ref.index(),
404 "should re-use the same index for further dead refs"
405 );
406
407 mapper.finish(&mut world);
408 let entity = world.spawn_empty().id();
410 assert_eq!(entity.index(), dead_ref.index());
411 assert!(entity
412 .generation()
413 .cmp_approx(&dead_ref.generation())
414 .is_gt());
415 }
416
417 #[test]
418 fn world_scope_reserves_generations() {
419 let mut map = EntityHashMap::default();
420 let mut world = World::new();
421
422 let dead_ref = SceneEntityMapper::world_scope(&mut map, &mut world, |_, mapper| {
423 mapper.get_mapped(Entity::from_raw_u32(0).unwrap())
424 });
425
426 let entity = world.spawn_empty().id();
428 assert_eq!(entity.index(), dead_ref.index());
429 assert!(entity
430 .generation()
431 .cmp_approx(&dead_ref.generation())
432 .is_gt());
433 }
434
435 #[test]
436 fn entity_mapper_no_panic() {
437 let mut world = World::new();
438 world.entities.reserve_entity();
440 assert!(world.entities.needs_flush());
441
442 SceneEntityMapper::world_scope(&mut Default::default(), &mut world, |_, m| {
445 m.get_mapped(Entity::PLACEHOLDER);
446 });
447
448 assert!(!world.entities.needs_flush());
450 }
451}