1use std::fmt::{self, Debug};
62use std::iter::FusedIterator;
63use std::marker::PhantomData;
64
65use crate::data_structures::entity_vec::EntityVec;
66use crate::entity::{Entity, EntityId};
67
68#[derive(Clone, PartialEq, Eq)]
70pub struct EntityMap<E: Entity, V> {
71 data: Vec<Option<V>>,
72 len: usize,
73 _phantom: PhantomData<E>,
74}
75
76impl<E: Entity, V> EntityMap<E, V> {
77 #[must_use]
79 pub fn new() -> Self {
80 Self {
81 data: Vec::new(),
82 len: 0,
83 _phantom: PhantomData,
84 }
85 }
86
87 #[must_use]
89 pub fn with_capacity(capacity: usize) -> Self {
90 Self {
91 data: Vec::with_capacity(capacity),
92 len: 0,
93 _phantom: PhantomData,
94 }
95 }
96
97 #[must_use]
99 pub fn into_entity_vec(self) -> EntityVec<E, Option<V>> {
100 self.data.into()
101 }
102
103 #[inline]
105 #[must_use]
106 pub fn len(&self) -> usize {
107 self.len
108 }
109
110 #[inline]
112 #[must_use]
113 pub fn capacity(&self) -> usize {
114 self.data.capacity()
115 }
116
117 #[inline]
119 #[must_use]
120 pub fn is_empty(&self) -> bool {
121 self.len == 0
122 }
123
124 pub fn reserve(&mut self, additional: usize) {
126 self.data.reserve(additional);
127 }
128
129 pub fn shrink_to_fit(&mut self) {
131 while self.data.last().is_some_and(Option::is_none) {
132 self.data.pop();
133 }
134 self.data.shrink_to_fit();
135 }
136
137 #[must_use]
139 pub fn contains_key(&self, entity_id: EntityId<E>) -> bool {
140 self.get(entity_id).is_some()
141 }
142
143 #[must_use]
145 pub fn get(&self, entity_id: EntityId<E>) -> Option<&V> {
146 self.data.get(entity_id.0).and_then(Option::as_ref)
147 }
148
149 #[must_use]
151 pub fn get_mut(&mut self, entity_id: EntityId<E>) -> Option<&mut V> {
152 self.data.get_mut(entity_id.0).and_then(Option::as_mut)
153 }
154
155 pub fn insert(&mut self, entity_id: EntityId<E>, value: V) -> Option<V> {
157 if entity_id.0 >= self.data.len() {
158 self.data.resize_with(entity_id.0 + 1, || None);
159 }
160
161 let slot = &mut self.data[entity_id.0];
162 let previous = slot.replace(value);
163 if previous.is_none() {
164 self.len += 1;
165 }
166 previous
167 }
168
169 pub fn get_or_insert(&mut self, entity_id: EntityId<E>, value: V) -> &mut V {
171 self.get_or_insert_with(entity_id, || value)
172 }
173
174 pub fn get_or_insert_with<F>(&mut self, entity_id: EntityId<E>, f: F) -> &mut V
176 where
177 F: FnOnce() -> V,
178 {
179 if entity_id.0 >= self.data.len() {
180 self.data.resize_with(entity_id.0 + 1, || None);
181 }
182
183 let slot = &mut self.data[entity_id.0];
184 if slot.is_none() {
185 *slot = Some(f());
186 self.len += 1;
187 }
188
189 slot.as_mut().unwrap()
190 }
191
192 #[must_use]
194 pub fn remove(&mut self, entity_id: EntityId<E>) -> Option<V> {
195 let removed = self.data.get_mut(entity_id.0).and_then(Option::take);
196 if removed.is_some() {
197 self.len -= 1;
198 }
199 removed
200 }
201
202 pub fn clear(&mut self) {
204 self.data.clear();
205 self.len = 0;
206 }
207
208 #[must_use]
210 pub fn iter(&self) -> Iter<'_, E, V> {
211 Iter {
212 inner: self.data.iter().enumerate(),
213 remaining: self.len,
214 _phantom: PhantomData,
215 }
216 }
217}
218
219impl<E: Entity, V> Default for EntityMap<E, V> {
220 fn default() -> Self {
221 Self::new()
222 }
223}
224
225impl<E: Entity, V: Debug> Debug for EntityMap<E, V> {
226 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227 f.debug_map().entries(self.iter()).finish()
228 }
229}
230
231impl<E: Entity, V> Extend<(EntityId<E>, V)> for EntityMap<E, V> {
232 fn extend<I: IntoIterator<Item = (EntityId<E>, V)>>(&mut self, iter: I) {
233 for (entity_id, value) in iter {
234 let _ = self.insert(entity_id, value);
235 }
236 }
237}
238
239impl<E: Entity, V> FromIterator<(EntityId<E>, V)> for EntityMap<E, V> {
240 fn from_iter<I: IntoIterator<Item = (EntityId<E>, V)>>(iter: I) -> Self {
241 let mut map = Self::new();
242 map.extend(iter);
243 map
244 }
245}
246
247impl<'a, E: Entity, V> IntoIterator for &'a EntityMap<E, V> {
248 type Item = (EntityId<E>, &'a V);
249 type IntoIter = Iter<'a, E, V>;
250
251 fn into_iter(self) -> Self::IntoIter {
252 self.iter()
253 }
254}
255
256pub struct Iter<'a, E: Entity, V> {
258 inner: std::iter::Enumerate<std::slice::Iter<'a, Option<V>>>,
259 remaining: usize,
260 _phantom: PhantomData<E>,
261}
262
263impl<'a, E: Entity, V> Iterator for Iter<'a, E, V> {
264 type Item = (EntityId<E>, &'a V);
265
266 fn next(&mut self) -> Option<Self::Item> {
267 for (index, value) in self.inner.by_ref() {
268 if let Some(value) = value.as_ref() {
269 self.remaining -= 1;
270 return Some((EntityId::new(index), value));
271 }
272 }
273 None
274 }
275
276 fn size_hint(&self) -> (usize, Option<usize>) {
277 (self.remaining, Some(self.remaining))
278 }
279
280 fn count(self) -> usize {
281 self.remaining
282 }
283
284 fn nth(&mut self, n: usize) -> Option<Self::Item> {
285 if n >= self.remaining {
286 self.remaining = 0;
287 self.inner.by_ref().for_each(drop);
288 return None;
289 }
290
291 let mut skipped = 0;
292 for (index, value) in self.inner.by_ref() {
293 if let Some(value) = value.as_ref() {
294 if skipped == n {
295 self.remaining -= n + 1;
296 return Some((EntityId::new(index), value));
297 }
298 skipped += 1;
299 }
300 }
301
302 self.remaining = 0;
303 None
304 }
305}
306
307impl<'a, E: Entity, V> ExactSizeIterator for Iter<'a, E, V> {
308 fn len(&self) -> usize {
309 self.remaining
310 }
311}
312
313impl<'a, E: Entity, V> FusedIterator for Iter<'a, E, V> {}
314
315#[cfg(test)]
316mod tests {
317 use super::EntityMap;
318 use crate::define_entity;
319 use crate::entity::EntityId;
320
321 define_entity!(TestEntity);
322
323 #[test]
324 fn new_is_empty() {
325 let map = EntityMap::<TestEntity, i32>::new();
326
327 assert_eq!(map.len(), 0);
328 assert!(map.is_empty());
329 assert_eq!(map.capacity(), 0);
330 }
331
332 #[test]
333 fn with_capacity_sets_initial_capacity() {
334 let map = EntityMap::<TestEntity, i32>::with_capacity(8);
335
336 assert_eq!(map.len(), 0);
337 assert!(map.capacity() >= 8);
338 }
339
340 #[test]
341 fn insert_and_get_work_for_sparse_ids() {
342 let mut map = EntityMap::<TestEntity, &'static str>::new();
343 let id2 = EntityId::new(2);
344 let id5 = EntityId::new(5);
345
346 assert_eq!(map.insert(id2, "two"), None);
347 assert_eq!(map.insert(id5, "five"), None);
348
349 assert_eq!(map.len(), 2);
350 assert!(!map.is_empty());
351 assert_eq!(map.get(EntityId::new(0)), None);
352 assert_eq!(map.get(id2), Some(&"two"));
353 assert_eq!(map.get(id5), Some(&"five"));
354 assert_eq!(map.get(EntityId::new(6)), None);
355 }
356
357 #[test]
358 fn insert_replaces_existing_value_without_changing_len() {
359 let mut map = EntityMap::<TestEntity, i32>::new();
360 let id = EntityId::new(3);
361
362 assert_eq!(map.insert(id, 10), None);
363 assert_eq!(map.insert(id, 20), Some(10));
364
365 assert_eq!(map.len(), 1);
366 assert_eq!(map.get(id), Some(&20));
367 }
368
369 #[test]
370 fn get_mut_updates_value() {
371 let mut map = EntityMap::<TestEntity, i32>::new();
372 let id = EntityId::new(1);
373 let _ = map.insert(id, 10);
374
375 *map.get_mut(id).unwrap() = 99;
376
377 assert_eq!(map.get(id), Some(&99));
378 assert_eq!(map.get_mut(EntityId::new(7)), None);
379 }
380
381 #[test]
382 fn get_or_insert_inserts_missing_value_and_returns_mutable_reference() {
383 let mut map = EntityMap::<TestEntity, i32>::new();
384 let id = EntityId::new(3);
385
386 let value = map.get_or_insert(id, 10);
387 *value = 15;
388
389 assert_eq!(map.len(), 1);
390 assert_eq!(map.get(id), Some(&15));
391 }
392
393 #[test]
394 fn get_or_insert_does_not_replace_existing_value() {
395 let mut map = EntityMap::<TestEntity, i32>::new();
396 let id = EntityId::new(2);
397 let _ = map.insert(id, 20);
398
399 let value = map.get_or_insert(id, 99);
400
401 assert_eq!(*value, 20);
402 assert_eq!(map.len(), 1);
403 assert_eq!(map.get(id), Some(&20));
404 }
405
406 #[test]
407 fn get_or_insert_with_only_evaluates_closure_for_missing_key() {
408 let mut map = EntityMap::<TestEntity, i32>::new();
409 let missing_id = EntityId::new(1);
410 let existing_id = EntityId::new(4);
411 let _ = map.insert(existing_id, 40);
412 let mut calls = 0;
413
414 let inserted = map.get_or_insert_with(missing_id, || {
415 calls += 1;
416 10
417 });
418 assert_eq!(*inserted, 10);
419
420 let existing = map.get_or_insert_with(existing_id, || {
421 calls += 1;
422 99
423 });
424 assert_eq!(*existing, 40);
425
426 assert_eq!(calls, 1);
427 assert_eq!(map.len(), 2);
428 }
429
430 #[test]
431 fn contains_key_tracks_presence() {
432 let mut map = EntityMap::<TestEntity, i32>::new();
433 let id = EntityId::new(4);
434
435 assert!(!map.contains_key(id));
436 let _ = map.insert(id, 12);
437 assert!(map.contains_key(id));
438 assert!(!map.contains_key(EntityId::new(3)));
439 }
440
441 #[test]
442 fn remove_returns_value_and_decrements_len() {
443 let mut map = EntityMap::<TestEntity, i32>::new();
444 let id1 = EntityId::new(1);
445 let id4 = EntityId::new(4);
446 let _ = map.insert(id1, 10);
447 let _ = map.insert(id4, 40);
448
449 assert_eq!(map.remove(id1), Some(10));
450 assert_eq!(map.remove(id1), None);
451
452 assert_eq!(map.len(), 1);
453 assert_eq!(map.get(id1), None);
454 assert_eq!(map.get(id4), Some(&40));
455 }
456
457 #[test]
458 fn remove_missing_key_returns_none_without_changing_len() {
459 let mut map = EntityMap::<TestEntity, i32>::new();
460 let _ = map.insert(EntityId::new(1), 10);
461 let _ = map.insert(EntityId::new(8), 80);
462
463 assert_eq!(map.remove(EntityId::new(4)), None);
464
465 assert_eq!(map.len(), 2);
466 assert!(!map.is_empty());
467 assert_eq!(map.get(EntityId::new(1)), Some(&10));
468 assert_eq!(map.get(EntityId::new(8)), Some(&80));
469 }
470
471 #[test]
472 fn clear_removes_all_entries() {
473 let mut map = EntityMap::<TestEntity, i32>::new();
474 let _ = map.insert(EntityId::new(0), 1);
475 let _ = map.insert(EntityId::new(2), 2);
476
477 map.clear();
478
479 assert!(map.is_empty());
480 assert_eq!(map.len(), 0);
481 assert_eq!(map.get(EntityId::new(0)), None);
482 assert_eq!(map.get(EntityId::new(2)), None);
483 }
484
485 #[test]
486 fn reserve_and_shrink_to_fit_manage_capacity() {
487 let mut map = EntityMap::<TestEntity, i32>::new();
488 map.reserve(16);
489 assert!(map.capacity() >= 16);
490
491 let _ = map.insert(EntityId::new(10), 10);
492 let _ = map.insert(EntityId::new(20), 20);
493 assert_eq!(map.remove(EntityId::new(20)), Some(20));
494
495 map.shrink_to_fit();
496
497 assert_eq!(map.len(), 1);
498 assert_eq!(map.get(EntityId::new(10)), Some(&10));
499 assert_eq!(map.get(EntityId::new(20)), None);
500 assert!(map.capacity() >= 11);
501 }
502
503 #[test]
504 fn iter_yields_only_present_entries_in_entity_id_order() {
505 let mut map = EntityMap::<TestEntity, &'static str>::new();
506 let _ = map.insert(EntityId::new(3), "three");
507 let _ = map.insert(EntityId::new(0), "zero");
508 let _ = map.insert(EntityId::new(5), "five");
509
510 let items: Vec<_> = map.iter().collect();
511
512 assert_eq!(
513 items,
514 vec![
515 (EntityId::new(0), &"zero"),
516 (EntityId::new(3), &"three"),
517 (EntityId::new(5), &"five"),
518 ]
519 );
520 }
521
522 #[test]
523 fn iter_size_hint_len_and_count_track_remaining_entries() {
524 let mut map = EntityMap::<TestEntity, i32>::new();
525 let _ = map.insert(EntityId::new(1), 10);
526 let _ = map.insert(EntityId::new(4), 40);
527 let _ = map.insert(EntityId::new(7), 70);
528
529 let mut iter = map.iter();
530 assert_eq!(iter.size_hint(), (3, Some(3)));
531 assert_eq!(iter.len(), 3);
532
533 assert_eq!(iter.next(), Some((EntityId::new(1), &10)));
534 assert_eq!(iter.size_hint(), (2, Some(2)));
535 assert_eq!(iter.len(), 2);
536 assert_eq!(iter.count(), 2);
537 }
538
539 #[test]
540 fn iter_nth_skips_missing_entries_and_updates_remaining_len() {
541 let mut map = EntityMap::<TestEntity, i32>::new();
542 let _ = map.insert(EntityId::new(2), 20);
543 let _ = map.insert(EntityId::new(5), 50);
544 let _ = map.insert(EntityId::new(8), 80);
545
546 let mut iter = map.iter();
547 assert_eq!(iter.nth(1), Some((EntityId::new(5), &50)));
548 assert_eq!(iter.len(), 1);
549 assert_eq!(iter.next(), Some((EntityId::new(8), &80)));
550 assert_eq!(iter.next(), None);
551 assert_eq!(iter.next(), None);
552 }
553
554 #[test]
555 fn iter_nth_past_end_returns_none_and_exhausts_iterator() {
556 let mut map = EntityMap::<TestEntity, i32>::new();
557 let _ = map.insert(EntityId::new(1), 10);
558 let _ = map.insert(EntityId::new(3), 30);
559
560 let mut iter = map.iter();
561 assert_eq!(iter.nth(2), None);
562 assert_eq!(iter.len(), 0);
563 assert_eq!(iter.next(), None);
564 }
565
566 #[test]
567 fn debug_formats_like_a_map() {
568 let mut map = EntityMap::<TestEntity, i32>::new();
569 let _ = map.insert(EntityId::new(1), 10);
570 let _ = map.insert(EntityId::new(4), 40);
571
572 assert_eq!(
573 format!("{:?}", map),
574 "{TestEntityId(1): 10, TestEntityId(4): 40}"
575 );
576 }
577
578 #[test]
579 fn default_matches_new() {
580 let map = EntityMap::<TestEntity, i32>::default();
581
582 assert!(map.is_empty());
583 assert_eq!(map.len(), 0);
584 }
585
586 #[test]
587 fn extend_and_from_iter_insert_all_entries() {
588 let entries = vec![(EntityId::new(2), 20), (EntityId::new(5), 50)];
589
590 let mut map = EntityMap::<TestEntity, i32>::new();
591 map.extend(entries.clone());
592 assert_eq!(map.get(EntityId::new(2)), Some(&20));
593 assert_eq!(map.get(EntityId::new(5)), Some(&50));
594
595 let collected = EntityMap::<TestEntity, i32>::from_iter(entries);
596 assert_eq!(collected.get(EntityId::new(2)), Some(&20));
597 assert_eq!(collected.get(EntityId::new(5)), Some(&50));
598 assert_eq!(collected.len(), 2);
599 }
600
601 #[test]
602 fn into_iterator_for_reference_matches_iter() {
603 let mut map = EntityMap::<TestEntity, i32>::new();
604 let _ = map.insert(EntityId::new(0), 10);
605 let _ = map.insert(EntityId::new(2), 20);
606
607 let from_iter: Vec<_> = map.iter().collect();
608 let from_into_iter: Vec<_> = (&map).into_iter().collect();
609
610 assert_eq!(from_iter, from_into_iter);
611 }
612}