1use crate::{reflect::prelude::*, visitor::prelude::*, ComponentProvider};
44use std::{
45 any::{Any, TypeId},
46 fmt::Debug,
47 future::Future,
48 marker::PhantomData,
49 ops::{Index, IndexMut},
50 sync::atomic::{self, AtomicIsize},
51};
52
53pub mod handle;
54pub mod multiborrow;
55pub mod payload;
56
57pub use handle::*;
58pub use multiborrow::*;
59pub use payload::*;
60
61const INVALID_GENERATION: u32 = 0;
62
63#[derive(Debug)]
68pub struct Pool<T, P = Option<T>>
69where
70 T: Sized,
71 P: PayloadContainer<Element = T>,
72{
73 records: Vec<PoolRecord<T, P>>,
74 free_stack: Vec<u32>,
75}
76
77impl<T, P> Reflect for Pool<T, P>
78where
79 T: Reflect,
80 P: PayloadContainer<Element = T> + Reflect,
81{
82 #[inline]
83 fn source_path() -> &'static str {
84 file!()
85 }
86
87 #[inline]
88 fn type_name(&self) -> &'static str {
89 std::any::type_name::<Self>()
90 }
91
92 #[inline]
93 fn doc(&self) -> &'static str {
94 ""
95 }
96
97 #[inline]
98 fn fields_info(&self, func: &mut dyn FnMut(&[FieldInfo])) {
99 func(&[])
100 }
101
102 #[inline]
103 fn into_any(self: Box<Self>) -> Box<dyn Any> {
104 self
105 }
106
107 #[inline]
108 fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
109 func(self)
110 }
111
112 #[inline]
113 fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
114 func(self)
115 }
116
117 #[inline]
118 fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
119 func(self)
120 }
121
122 #[inline]
123 fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
124 func(self)
125 }
126
127 #[inline]
128 fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
129 let this = std::mem::replace(self, value.take()?);
130 Ok(Box::new(this))
131 }
132
133 fn assembly_name(&self) -> &'static str {
134 env!("CARGO_PKG_NAME")
135 }
136
137 fn type_assembly_name() -> &'static str {
138 env!("CARGO_PKG_NAME")
139 }
140
141 #[inline]
142 fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
143 func(Some(self))
144 }
145
146 #[inline]
147 fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
148 func(Some(self))
149 }
150}
151
152impl<T, P> ReflectArray for Pool<T, P>
153where
154 T: Reflect,
155 P: PayloadContainer<Element = T> + Reflect,
156{
157 #[inline]
158 fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
159 self.at(index as u32).map(|p| p as &dyn Reflect)
160 }
161
162 #[inline]
163 fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
164 self.at_mut(index as u32).map(|p| p as &mut dyn Reflect)
165 }
166
167 #[inline]
168 fn reflect_len(&self) -> usize {
169 self.get_capacity() as usize
170 }
171}
172
173impl<T, P> PartialEq for Pool<T, P>
174where
175 T: PartialEq,
176 P: PayloadContainer<Element = T> + PartialEq,
177{
178 #[inline]
179 fn eq(&self, other: &Self) -> bool {
180 self.records == other.records
181 }
182}
183
184#[derive(Default, Debug)]
187struct RefCounter(pub AtomicIsize);
188
189impl RefCounter {
190 fn increment(&self) {
191 self.0.fetch_add(1, atomic::Ordering::Relaxed);
192 }
193
194 fn decrement(&self) {
195 self.0.fetch_sub(1, atomic::Ordering::Relaxed);
196 }
197}
198
199#[derive(Debug)]
200struct PoolRecord<T, P = Option<T>>
201where
202 T: Sized,
203 P: PayloadContainer<Element = T>,
204{
205 ref_counter: RefCounter,
206 generation: u32,
210 payload: Payload<P>,
212}
213
214impl<T, P> PartialEq for PoolRecord<T, P>
215where
216 T: PartialEq,
217 P: PayloadContainer<Element = T> + PartialEq,
218{
219 #[inline]
220 fn eq(&self, other: &Self) -> bool {
221 self.generation == other.generation && self.payload.get() == other.payload.get()
222 }
223}
224
225impl<T, P> Default for PoolRecord<T, P>
226where
227 P: PayloadContainer<Element = T> + 'static,
228{
229 #[inline]
230 fn default() -> Self {
231 Self {
232 ref_counter: Default::default(),
233 generation: INVALID_GENERATION,
234 payload: Payload::new_empty(),
235 }
236 }
237}
238
239impl<T, P> Visit for PoolRecord<T, P>
240where
241 T: Visit + 'static,
242 P: PayloadContainer<Element = T> + Visit,
243{
244 #[inline]
245 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
246 let mut region = visitor.enter_region(name)?;
247
248 self.generation.visit("Generation", &mut region)?;
249 self.payload.get_mut().visit("Payload", &mut region)?;
250
251 Ok(())
252 }
253}
254
255impl<T> Clone for Handle<T> {
256 #[inline]
257 fn clone(&self) -> Handle<T> {
258 *self
259 }
260}
261
262impl<T, P> Visit for Pool<T, P>
263where
264 T: Visit + 'static,
265 P: PayloadContainer<Element = T> + Default + Visit + 'static,
266{
267 #[inline]
268 fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
269 let mut region = visitor.enter_region(name)?;
270 self.records.visit("Records", &mut region)?;
271 self.free_stack.visit("FreeStack", &mut region)?;
272 Ok(())
273 }
274}
275
276impl<T, P> Default for Pool<T, P>
277where
278 T: 'static,
279 P: PayloadContainer<Element = T> + 'static,
280{
281 #[inline]
282 fn default() -> Self {
283 Self::new()
284 }
285}
286
287#[derive(Debug)]
288pub struct Ticket<T> {
289 index: u32,
290 marker: PhantomData<T>,
291}
292
293impl<T> Drop for Ticket<T> {
294 fn drop(&mut self) {
295 panic!(
296 "An object at index {} must be returned to a pool it was taken from! \
297 Call Pool::forget_ticket if you don't need the object anymore.",
298 self.index
299 )
300 }
301}
302
303impl<T: Clone> Clone for PoolRecord<T> {
304 #[inline]
305 fn clone(&self) -> Self {
306 Self {
307 ref_counter: Default::default(),
308 generation: self.generation,
309 payload: self.payload.clone(),
310 }
311 }
312}
313
314impl<T: Clone> Clone for Pool<T> {
315 #[inline]
316 fn clone(&self) -> Self {
317 Self {
318 records: self.records.clone(),
319 free_stack: self.free_stack.clone(),
320 }
321 }
322}
323
324impl<T, P> Pool<T, P>
325where
326 P: PayloadContainer<Element = T> + 'static,
327{
328 #[inline]
329 pub fn new() -> Self {
330 Pool {
331 records: Vec::new(),
332 free_stack: Vec::new(),
333 }
334 }
335
336 #[inline]
337 pub fn with_capacity(capacity: u32) -> Self {
338 let capacity = usize::try_from(capacity).expect("capacity overflowed usize");
339 Pool {
340 records: Vec::with_capacity(capacity),
341 free_stack: Vec::new(),
342 }
343 }
344
345 fn records_len(&self) -> u32 {
346 u32::try_from(self.records.len()).expect("Number of records overflowed u32")
347 }
348
349 fn records_get(&self, index: u32) -> Option<&PoolRecord<T, P>> {
350 let index = usize::try_from(index).expect("Index overflowed usize");
351 self.records.get(index)
352 }
353
354 fn records_get_mut(&mut self, index: u32) -> Option<&mut PoolRecord<T, P>> {
355 let index = usize::try_from(index).expect("Index overflowed usize");
356 self.records.get_mut(index)
357 }
358
359 #[inline]
360 #[must_use]
361 pub fn spawn(&mut self, payload: T) -> Handle<T> {
362 self.spawn_with(|_| payload)
363 }
364
365 #[inline]
380 pub fn spawn_at(&mut self, index: u32, payload: T) -> Result<Handle<T>, T> {
381 self.spawn_at_internal(index, INVALID_GENERATION, payload)
382 }
383
384 #[inline]
399 pub fn spawn_at_handle(&mut self, handle: Handle<T>, payload: T) -> Result<Handle<T>, T> {
400 self.spawn_at_internal(handle.index, handle.generation, payload)
401 }
402
403 fn spawn_at_internal(
404 &mut self,
405 index: u32,
406 desired_generation: u32,
407 payload: T,
408 ) -> Result<Handle<T>, T> {
409 let index_usize = usize::try_from(index).expect("index overflowed usize");
410 match self.records.get_mut(index_usize) {
411 Some(record) => match record.payload.as_ref() {
412 Some(_) => Err(payload),
413 None => {
414 let position = self
415 .free_stack
416 .iter()
417 .rposition(|i| *i == index)
418 .expect("free_stack must contain the index of the empty record (most likely attempting to spawn at a reserved index)!");
419
420 self.free_stack.remove(position);
421
422 let generation = if desired_generation == INVALID_GENERATION {
423 record.generation + 1
424 } else {
425 desired_generation
426 };
427
428 record.generation = generation;
429 record.payload = Payload::new(payload);
430
431 Ok(Handle::new(index, generation))
432 }
433 },
434 None => {
435 for i in self.records_len()..index {
437 self.records.push(PoolRecord {
438 ref_counter: Default::default(),
439 generation: 1,
440 payload: Payload::new_empty(),
441 });
442 self.free_stack.push(i);
443 }
444
445 let generation = if desired_generation == INVALID_GENERATION {
446 1
447 } else {
448 desired_generation
449 };
450
451 self.records.push(PoolRecord {
452 ref_counter: Default::default(),
453 generation,
454 payload: Payload::new(payload),
455 });
456
457 Ok(Handle::new(index, generation))
458 }
459 }
460 }
461
462 #[inline]
463 #[must_use]
464 pub fn spawn_with<F: FnOnce(Handle<T>) -> T>(&mut self, callback: F) -> Handle<T> {
467 if let Some(free_index) = self.free_stack.pop() {
468 let record = self
469 .records_get_mut(free_index)
470 .expect("free stack contained invalid index");
471
472 if record.payload.is_some() {
473 panic!(
474 "Attempt to spawn an object at pool record with payload! Record index is {free_index}"
475 );
476 }
477
478 let generation = record.generation + 1;
479 let handle = Handle {
480 index: free_index,
481 generation,
482 type_marker: PhantomData,
483 };
484
485 let payload = callback(handle);
486
487 record.generation = generation;
488 record.payload.replace(payload);
489 handle
490 } else {
491 let generation = 1;
493
494 let handle = Handle {
495 index: self.records.len() as u32,
496 generation,
497 type_marker: PhantomData,
498 };
499
500 let payload = callback(handle);
501
502 let record = PoolRecord {
503 ref_counter: Default::default(),
504 generation,
505 payload: Payload::new(payload),
506 };
507
508 self.records.push(record);
509
510 handle
511 }
512 }
513
514 #[inline]
515 pub async fn spawn_with_async<F, Fut>(&mut self, callback: F) -> Handle<T>
518 where
519 F: FnOnce(Handle<T>) -> Fut,
520 Fut: Future<Output = T>,
521 {
522 if let Some(free_index) = self.free_stack.pop() {
523 let record = self
524 .records_get_mut(free_index)
525 .expect("free stack contained invalid index");
526
527 if record.payload.is_some() {
528 panic!(
529 "Attempt to spawn an object at pool record with payload! Record index is {free_index}"
530 );
531 }
532
533 let generation = record.generation + 1;
534 let handle = Handle {
535 index: free_index,
536 generation,
537 type_marker: PhantomData,
538 };
539
540 let payload = callback(handle).await;
541
542 record.generation = generation;
543 record.payload.replace(payload);
544 handle
545 } else {
546 let generation = 1;
548
549 let handle = Handle {
550 index: self.records.len() as u32,
551 generation,
552 type_marker: PhantomData,
553 };
554
555 let payload = callback(handle).await;
556
557 let record = PoolRecord {
558 generation,
559 ref_counter: Default::default(),
560 payload: Payload::new(payload),
561 };
562
563 self.records.push(record);
564
565 handle
566 }
567 }
568
569 #[inline]
573 pub fn generate_free_handles(&self, amount: usize) -> Vec<Handle<T>> {
574 let mut free_handles = Vec::with_capacity(amount);
575 free_handles.extend(
576 self.free_stack
577 .iter()
578 .take(amount)
579 .map(|i| Handle::new(*i, self.records[*i as usize].generation + 1)),
580 );
581 if free_handles.len() < amount {
582 let remainder = amount - free_handles.len();
583 free_handles.extend(
584 (self.records.len()..self.records.len() + remainder)
585 .map(|i| Handle::new(i as u32, 1)),
586 );
587 }
588 free_handles
589 }
590
591 #[inline]
599 #[must_use]
600 pub fn borrow(&self, handle: Handle<T>) -> &T {
601 if let Some(record) = self.records_get(handle.index) {
602 if record.generation == handle.generation {
603 if let Some(payload) = record.payload.as_ref() {
604 payload
605 } else {
606 panic!("Attempt to borrow destroyed object at {handle:?} handle.");
607 }
608 } else {
609 panic!(
610 "Attempt to use dangling handle {:?}. Record has generation {}!",
611 handle, record.generation
612 );
613 }
614 } else {
615 panic!(
616 "Attempt to borrow object using out-of-bounds handle {:?}! Record count is {}",
617 handle,
618 self.records.len()
619 );
620 }
621 }
622
623 #[inline]
641 #[must_use]
642 pub fn borrow_mut(&mut self, handle: Handle<T>) -> &mut T {
643 let record_count = self.records.len();
644 if let Some(record) = self.records_get_mut(handle.index) {
645 if record.generation == handle.generation {
646 if let Some(payload) = record.payload.as_mut() {
647 payload
648 } else {
649 panic!("Attempt to borrow destroyed object at {handle:?} handle.");
650 }
651 } else {
652 panic!("Attempt to borrow object using dangling handle {:?}. Record has {} generation!", handle, record.generation);
653 }
654 } else {
655 panic!(
656 "Attempt to borrow object using out-of-bounds handle {handle:?}! Record count is {record_count}"
657 );
658 }
659 }
660
661 #[inline]
667 #[must_use]
668 pub fn try_borrow(&self, handle: Handle<T>) -> Option<&T> {
669 self.records_get(handle.index).and_then(|r| {
670 if r.generation == handle.generation {
671 r.payload.as_ref()
672 } else {
673 None
674 }
675 })
676 }
677
678 #[inline]
684 #[must_use]
685 pub fn try_borrow_mut(&mut self, handle: Handle<T>) -> Option<&mut T> {
686 self.records_get_mut(handle.index).and_then(|r| {
687 if r.generation == handle.generation {
688 r.payload.as_mut()
689 } else {
690 None
691 }
692 })
693 }
694
695 #[inline]
715 #[must_use = "Handle set must not be ignored"]
716 pub fn borrow_two_mut(&mut self, handles: (Handle<T>, Handle<T>)) -> (&mut T, &mut T) {
717 assert_ne!(handles.0.index, handles.1.index);
719 unsafe {
720 let this = self as *mut Self;
721 ((*this).borrow_mut(handles.0), (*this).borrow_mut(handles.1))
722 }
723 }
724
725 #[inline]
747 #[must_use = "Handle set must not be ignored"]
748 pub fn borrow_three_mut(
749 &mut self,
750 handles: (Handle<T>, Handle<T>, Handle<T>),
751 ) -> (&mut T, &mut T, &mut T) {
752 assert_ne!(handles.0.index, handles.1.index);
754 assert_ne!(handles.0.index, handles.2.index);
755 assert_ne!(handles.1.index, handles.2.index);
756 unsafe {
757 let this = self as *mut Self;
758 (
759 (*this).borrow_mut(handles.0),
760 (*this).borrow_mut(handles.1),
761 (*this).borrow_mut(handles.2),
762 )
763 }
764 }
765
766 #[inline]
790 #[must_use = "Handle set must not be ignored"]
791 pub fn borrow_four_mut(
792 &mut self,
793 handles: (Handle<T>, Handle<T>, Handle<T>, Handle<T>),
794 ) -> (&mut T, &mut T, &mut T, &mut T) {
795 assert_ne!(handles.0.index, handles.1.index);
798 assert_ne!(handles.0.index, handles.2.index);
799 assert_ne!(handles.0.index, handles.3.index);
800 assert_ne!(handles.1.index, handles.2.index);
801 assert_ne!(handles.1.index, handles.3.index);
802 assert_ne!(handles.2.index, handles.3.index);
803 unsafe {
804 let this = self as *mut Self;
805 (
806 (*this).borrow_mut(handles.0),
807 (*this).borrow_mut(handles.1),
808 (*this).borrow_mut(handles.2),
809 (*this).borrow_mut(handles.3),
810 )
811 }
812 }
813
814 #[inline]
816 pub fn try_borrow_dependant_mut<F>(
817 &mut self,
818 handle: Handle<T>,
819 func: F,
820 ) -> (Option<&mut T>, Option<&mut T>)
821 where
822 F: FnOnce(&T) -> Handle<T>,
823 {
824 let this = unsafe { &mut *(self as *mut Pool<T, P>) };
825 let first = self.try_borrow_mut(handle);
826 if let Some(first_object) = first.as_ref() {
827 let second_handle = func(first_object);
828 if second_handle != handle {
829 return (first, this.try_borrow_mut(second_handle));
830 }
831 }
832
833 (first, None)
834 }
835
836 #[inline]
842 pub fn free(&mut self, handle: Handle<T>) -> T {
843 let index = usize::try_from(handle.index).expect("index overflowed usize");
844 if let Some(record) = self.records.get_mut(index) {
845 if record.generation == handle.generation {
846 self.free_stack.push(handle.index);
848 if let Some(payload) = record.payload.take() {
850 payload
851 } else {
852 panic!("Attempt to double free object at handle {handle:?}!");
853 }
854 } else {
855 panic!(
856 "Attempt to free object using dangling handle {:?}! Record generation is {}",
857 handle, record.generation
858 );
859 }
860 } else {
861 panic!("Attempt to free destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len());
862 }
863 }
864
865 #[inline]
869 pub fn try_free(&mut self, handle: Handle<T>) -> Option<T> {
870 let index = usize::try_from(handle.index).expect("index overflowed usize");
871 self.records.get_mut(index).and_then(|record| {
872 if record.generation == handle.generation {
873 if let Some(payload) = record.payload.take() {
874 self.free_stack.push(handle.index);
875 Some(payload)
876 } else {
877 None
878 }
879 } else {
880 None
881 }
882 })
883 }
884
885 #[inline]
906 pub fn take_reserve(&mut self, handle: Handle<T>) -> (Ticket<T>, T) {
907 if let Some(record) = self.records_get_mut(handle.index) {
908 if record.generation == handle.generation {
909 if let Some(payload) = record.payload.take() {
910 let ticket = Ticket {
911 index: handle.index,
912 marker: PhantomData,
913 };
914 (ticket, payload)
915 } else {
916 panic!("Attempt to take already taken object at handle {handle:?}!");
917 }
918 } else {
919 panic!(
920 "Attempt to take object using dangling handle {:?}! Record generation is {}",
921 handle, record.generation
922 );
923 }
924 } else {
925 panic!("Attempt to take destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len());
926 }
927 }
928
929 #[inline]
933 pub fn try_take_reserve(&mut self, handle: Handle<T>) -> Option<(Ticket<T>, T)> {
934 if let Some(record) = self.records_get_mut(handle.index) {
935 if record.generation == handle.generation {
936 if let Some(payload) = record.payload.take() {
937 let ticket = Ticket {
938 index: handle.index,
939 marker: PhantomData,
940 };
941 Some((ticket, payload))
942 } else {
943 None
944 }
945 } else {
946 None
947 }
948 } else {
949 None
950 }
951 }
952
953 #[inline]
958 pub fn put_back(&mut self, ticket: Ticket<T>, value: T) -> Handle<T> {
959 let record = self
960 .records_get_mut(ticket.index)
961 .expect("Ticket index was invalid");
962 let old = record.payload.replace(value);
963 assert!(old.is_none());
964 let handle = Handle::new(ticket.index, record.generation);
965 std::mem::forget(ticket);
966 handle
967 }
968
969 #[inline]
973 pub fn forget_ticket(&mut self, ticket: Ticket<T>) {
974 self.free_stack.push(ticket.index);
975 std::mem::forget(ticket);
976 }
977
978 #[inline]
980 #[must_use]
981 pub fn get_capacity(&self) -> u32 {
982 u32::try_from(self.records.len()).expect("records.len() overflowed u32")
983 }
984
985 #[inline]
993 pub fn clear(&mut self) {
994 self.records.clear();
995 self.free_stack.clear();
996 }
997
998 #[inline]
999 #[must_use]
1000 pub fn at_mut(&mut self, n: u32) -> Option<&mut T> {
1001 self.records_get_mut(n).and_then(|rec| rec.payload.as_mut())
1002 }
1003
1004 #[inline]
1005 #[must_use]
1006 pub fn at(&self, n: u32) -> Option<&T> {
1007 self.records_get(n)
1008 .and_then(|rec| rec.payload.get().as_ref())
1009 }
1010
1011 #[inline]
1012 #[must_use]
1013 pub fn handle_from_index(&self, n: u32) -> Handle<T> {
1014 if let Some(record) = self.records_get(n) {
1015 if record.generation != INVALID_GENERATION {
1016 return Handle::new(n, record.generation);
1017 }
1018 }
1019 Handle::NONE
1020 }
1021
1022 #[inline]
1043 #[must_use]
1044 pub fn alive_count(&self) -> u32 {
1045 let cnt = self.iter().count();
1046 u32::try_from(cnt).expect("alive_count overflowed u32")
1047 }
1048
1049 #[inline]
1060 pub fn total_count(&self) -> u32 {
1061 let free = u32::try_from(self.free_stack.len()).expect("free stack length overflowed u32");
1062 self.records_len() - free
1063 }
1064
1065 #[inline]
1066 pub fn replace(&mut self, handle: Handle<T>, payload: T) -> Option<T> {
1067 let index_usize = usize::try_from(handle.index).expect("index overflowed usize");
1068 if let Some(record) = self.records.get_mut(index_usize) {
1069 if record.generation == handle.generation {
1070 self.free_stack.retain(|i| *i != handle.index);
1071
1072 record.payload.replace(payload)
1073 } else {
1074 panic!("Attempt to replace object in pool using dangling handle! Handle is {:?}, but pool record has {} generation", handle, record.generation);
1075 }
1076 } else {
1077 None
1078 }
1079 }
1080
1081 pub fn first_ref(&self) -> Option<&T> {
1083 self.iter().next()
1084 }
1085
1086 pub fn first_mut(&mut self) -> Option<&mut T> {
1088 self.iter_mut().next()
1089 }
1090
1091 #[inline]
1102 pub fn is_valid_handle(&self, handle: Handle<T>) -> bool {
1103 if let Some(record) = self.records_get(handle.index) {
1104 record.payload.is_some() && record.generation == handle.generation
1105 } else {
1106 false
1107 }
1108 }
1109
1110 #[must_use]
1124 #[inline]
1125 pub fn iter(&self) -> PoolIterator<T, P> {
1126 unsafe {
1127 PoolIterator {
1128 ptr: self.records.as_ptr(),
1129 end: self.records.as_ptr().add(self.records.len()),
1130 marker: PhantomData,
1131 }
1132 }
1133 }
1134
1135 #[inline]
1139 pub fn pair_iter(&self) -> PoolPairIterator<T, P> {
1140 PoolPairIterator {
1141 pool: self,
1142 current: 0,
1143 }
1144 }
1145
1146 #[must_use]
1161 #[inline]
1162 pub fn iter_mut(&mut self) -> PoolIteratorMut<T, P> {
1163 unsafe {
1164 PoolIteratorMut {
1165 ptr: self.records.as_mut_ptr(),
1166 end: self.records.as_mut_ptr().add(self.records.len()),
1167 marker: PhantomData,
1168 }
1169 }
1170 }
1171
1172 #[inline]
1176 pub fn pair_iter_mut(&mut self) -> PoolPairIteratorMut<T, P> {
1177 unsafe {
1178 PoolPairIteratorMut {
1179 current: 0,
1180 ptr: self.records.as_mut_ptr(),
1181 end: self.records.as_mut_ptr().add(self.records.len()),
1182 marker: PhantomData,
1183 }
1184 }
1185 }
1186
1187 #[inline]
1190 pub fn retain<F>(&mut self, mut pred: F)
1191 where
1192 F: FnMut(&T) -> bool,
1193 {
1194 for (i, record) in self.records.iter_mut().enumerate() {
1195 if record.generation == INVALID_GENERATION {
1196 continue;
1197 }
1198
1199 let retain = if let Some(payload) = record.payload.as_ref() {
1200 pred(payload)
1201 } else {
1202 continue;
1203 };
1204
1205 if !retain {
1206 self.free_stack.push(i as u32);
1207 record.payload.take(); }
1209 }
1210 }
1211
1212 #[inline]
1215 pub fn begin_multi_borrow(&mut self) -> MultiBorrowContext<T, P> {
1216 MultiBorrowContext::new(self)
1217 }
1218
1219 #[inline]
1221 pub fn drain(&mut self) -> impl Iterator<Item = T> + '_ {
1222 self.free_stack.clear();
1223 self.records.drain(..).filter_map(|mut r| r.payload.take())
1224 }
1225
1226 fn end(&self) -> *const PoolRecord<T, P> {
1227 unsafe { self.records.as_ptr().add(self.records.len()) }
1228 }
1229
1230 fn begin(&self) -> *const PoolRecord<T, P> {
1231 self.records.as_ptr()
1232 }
1233
1234 #[inline]
1235 pub fn handle_of(&self, ptr: &T) -> Handle<T> {
1236 let begin = self.begin() as usize;
1237 let end = self.end() as usize;
1238 let val = ptr as *const T as usize;
1239 if val >= begin && val < end {
1240 let record_size = std::mem::size_of::<PoolRecord<T>>();
1241 let record_location = (val - offset_of!(PoolRecord<T>, payload)) - begin;
1242 if record_location % record_size == 0 {
1243 let index = record_location / record_size;
1244 let index = u32::try_from(index).expect("Index overflowed u32");
1245 return self.handle_from_index(index);
1246 }
1247 }
1248 Handle::NONE
1249 }
1250}
1251
1252impl<T, P> Pool<T, P>
1253where
1254 T: ComponentProvider,
1255 P: PayloadContainer<Element = T> + 'static,
1256{
1257 #[inline]
1259 pub fn try_get_component_of_type<C>(&self, handle: Handle<T>) -> Option<&C>
1260 where
1261 C: 'static,
1262 {
1263 self.try_borrow(handle)
1264 .and_then(|n| n.query_component_ref(TypeId::of::<C>()))
1265 .and_then(|c| c.downcast_ref())
1266 }
1267
1268 #[inline]
1270 pub fn try_get_component_of_type_mut<C>(&mut self, handle: Handle<T>) -> Option<&mut C>
1271 where
1272 C: 'static,
1273 {
1274 self.try_borrow_mut(handle)
1275 .and_then(|n| n.query_component_mut(TypeId::of::<C>()))
1276 .and_then(|c| c.downcast_mut())
1277 }
1278}
1279
1280impl<T> FromIterator<T> for Pool<T>
1281where
1282 T: 'static,
1283{
1284 #[inline]
1285 fn from_iter<C: IntoIterator<Item = T>>(iter: C) -> Self {
1286 let iter = iter.into_iter();
1287 let (lower_bound, upper_bound) = iter.size_hint();
1288 let lower_bound = u32::try_from(lower_bound).expect("lower_bound overflowed u32");
1289 let upper_bound =
1290 upper_bound.map(|b| u32::try_from(b).expect("upper_bound overflowed u32"));
1291 let mut pool = Self::with_capacity(upper_bound.unwrap_or(lower_bound));
1292 for v in iter {
1293 let _ = pool.spawn(v);
1294 }
1295 pool
1296 }
1297}
1298
1299impl<T, P> Index<Handle<T>> for Pool<T, P>
1300where
1301 T: 'static,
1302 P: PayloadContainer<Element = T> + 'static,
1303{
1304 type Output = T;
1305
1306 #[inline]
1307 fn index(&self, index: Handle<T>) -> &Self::Output {
1308 self.borrow(index)
1309 }
1310}
1311
1312impl<T, P> IndexMut<Handle<T>> for Pool<T, P>
1313where
1314 T: 'static,
1315 P: PayloadContainer<Element = T> + 'static,
1316{
1317 #[inline]
1318 fn index_mut(&mut self, index: Handle<T>) -> &mut Self::Output {
1319 self.borrow_mut(index)
1320 }
1321}
1322
1323impl<'a, T, P> IntoIterator for &'a Pool<T, P>
1324where
1325 P: PayloadContainer<Element = T> + 'static,
1326{
1327 type Item = &'a T;
1328 type IntoIter = PoolIterator<'a, T, P>;
1329
1330 #[inline]
1331 fn into_iter(self) -> Self::IntoIter {
1332 self.iter()
1333 }
1334}
1335
1336impl<'a, T, P> IntoIterator for &'a mut Pool<T, P>
1337where
1338 P: PayloadContainer<Element = T> + 'static,
1339{
1340 type Item = &'a mut T;
1341 type IntoIter = PoolIteratorMut<'a, T, P>;
1342
1343 #[inline]
1344 fn into_iter(self) -> Self::IntoIter {
1345 self.iter_mut()
1346 }
1347}
1348
1349pub struct PoolIterator<'a, T, P>
1350where
1351 P: PayloadContainer<Element = T>,
1352{
1353 ptr: *const PoolRecord<T, P>,
1354 end: *const PoolRecord<T, P>,
1355 marker: PhantomData<&'a T>,
1356}
1357
1358impl<'a, T, P> Iterator for PoolIterator<'a, T, P>
1359where
1360 P: PayloadContainer<Element = T> + 'static,
1361{
1362 type Item = &'a T;
1363
1364 #[inline]
1365 fn next(&mut self) -> Option<Self::Item> {
1366 unsafe {
1367 while self.ptr != self.end {
1368 let current = &*self.ptr;
1369 if let Some(payload) = current.payload.as_ref() {
1370 self.ptr = self.ptr.offset(1);
1371 return Some(payload);
1372 }
1373 self.ptr = self.ptr.offset(1);
1374 }
1375
1376 None
1377 }
1378 }
1379}
1380
1381pub struct PoolPairIterator<'a, T, P: PayloadContainer<Element = T>> {
1382 pool: &'a Pool<T, P>,
1383 current: usize,
1384}
1385
1386impl<'a, T, P> Iterator for PoolPairIterator<'a, T, P>
1387where
1388 P: PayloadContainer<Element = T>,
1389{
1390 type Item = (Handle<T>, &'a T);
1391
1392 #[inline]
1393 fn next(&mut self) -> Option<Self::Item> {
1394 loop {
1395 match self.pool.records.get(self.current) {
1396 Some(record) => {
1397 if let Some(payload) = record.payload.as_ref() {
1398 let handle = Handle::new(self.current as u32, record.generation);
1399 self.current += 1;
1400 return Some((handle, payload));
1401 }
1402 self.current += 1;
1403 }
1404 None => return None,
1405 }
1406 }
1407 }
1408}
1409
1410pub struct PoolIteratorMut<'a, T, P>
1411where
1412 P: PayloadContainer<Element = T>,
1413{
1414 ptr: *mut PoolRecord<T, P>,
1415 end: *mut PoolRecord<T, P>,
1416 marker: PhantomData<&'a mut T>,
1417}
1418
1419impl<'a, T, P> Iterator for PoolIteratorMut<'a, T, P>
1420where
1421 P: PayloadContainer<Element = T> + 'static,
1422{
1423 type Item = &'a mut T;
1424
1425 #[inline]
1426 fn next(&mut self) -> Option<Self::Item> {
1427 unsafe {
1428 while self.ptr != self.end {
1429 let current = &mut *self.ptr;
1430 if let Some(payload) = current.payload.as_mut() {
1431 self.ptr = self.ptr.offset(1);
1432 return Some(payload);
1433 }
1434 self.ptr = self.ptr.offset(1);
1435 }
1436
1437 None
1438 }
1439 }
1440}
1441
1442pub struct PoolPairIteratorMut<'a, T, P>
1443where
1444 P: PayloadContainer<Element = T>,
1445{
1446 ptr: *mut PoolRecord<T, P>,
1447 end: *mut PoolRecord<T, P>,
1448 marker: PhantomData<&'a mut T>,
1449 current: usize,
1450}
1451
1452impl<'a, T, P> Iterator for PoolPairIteratorMut<'a, T, P>
1453where
1454 P: PayloadContainer<Element = T> + 'static,
1455{
1456 type Item = (Handle<T>, &'a mut T);
1457
1458 #[inline]
1459 fn next(&mut self) -> Option<Self::Item> {
1460 unsafe {
1461 while self.ptr != self.end {
1462 let current = &mut *self.ptr;
1463 if let Some(payload) = current.payload.as_mut() {
1464 let handle = Handle::new(self.current as u32, current.generation);
1465 self.ptr = self.ptr.offset(1);
1466 self.current += 1;
1467 return Some((handle, payload));
1468 }
1469 self.ptr = self.ptr.offset(1);
1470 self.current += 1;
1471 }
1472
1473 None
1474 }
1475 }
1476}
1477
1478#[cfg(test)]
1479mod test {
1480 use crate::{
1481 pool::{AtomicHandle, Handle, Pool, PoolRecord, INVALID_GENERATION},
1482 visitor::{Visit, Visitor},
1483 };
1484
1485 #[test]
1486 fn pool_sanity_tests() {
1487 let mut pool: Pool<String> = Pool::new();
1488 let foobar_handle = pool.spawn(String::from("Foobar"));
1489 assert_eq!(foobar_handle.index, 0);
1490 assert_ne!(foobar_handle.generation, INVALID_GENERATION);
1491 let foobar_handle_copy = foobar_handle;
1492 assert_eq!(foobar_handle.index, foobar_handle_copy.index);
1493 assert_eq!(foobar_handle.generation, foobar_handle_copy.generation);
1494 let baz_handle = pool.spawn(String::from("Baz"));
1495 assert_eq!(pool.borrow(foobar_handle), "Foobar");
1496 assert_eq!(pool.borrow(baz_handle), "Baz");
1497 pool.free(foobar_handle);
1498 assert!(!pool.is_valid_handle(foobar_handle_copy));
1499 assert!(pool.is_valid_handle(baz_handle));
1500 let at_foobar_index = pool.spawn(String::from("AtFoobarIndex"));
1501 assert_eq!(at_foobar_index.index, 0);
1502 assert_ne!(at_foobar_index.generation, INVALID_GENERATION);
1503 assert_eq!(pool.borrow(at_foobar_index), "AtFoobarIndex");
1504 let bar_handle = pool.spawn_with(|_handle| String::from("Bar"));
1505 assert_ne!(bar_handle.index, 0);
1506 assert_ne!(bar_handle.generation, INVALID_GENERATION);
1507 assert_eq!(pool.borrow(bar_handle), "Bar");
1508 }
1509
1510 #[test]
1511 fn pool_iterator_mut_test() {
1512 let mut pool: Pool<String> = Pool::new();
1513 let foobar = pool.spawn("Foobar".to_string());
1514 let d = pool.spawn("Foo".to_string());
1515 pool.free(d);
1516 let baz = pool.spawn("Baz".to_string());
1517 for s in pool.iter() {
1518 println!("{s}");
1519 }
1520 for s in pool.iter_mut() {
1521 println!("{s}");
1522 }
1523 for s in &pool {
1524 println!("{s}");
1525 }
1526 for s in &mut pool {
1527 println!("{s}");
1528 }
1529 pool.free(foobar);
1530 pool.free(baz);
1531 }
1532
1533 #[test]
1534 fn handle_of() {
1535 #[allow(dead_code)]
1536 struct Value {
1537 data: String,
1538 }
1539
1540 let mut pool = Pool::<Value>::new();
1541 let foobar = pool.spawn(Value {
1542 data: "Foobar".to_string(),
1543 });
1544 let bar = pool.spawn(Value {
1545 data: "Bar".to_string(),
1546 });
1547 let baz = pool.spawn(Value {
1548 data: "Baz".to_string(),
1549 });
1550 assert_eq!(pool.handle_of(pool.borrow(foobar)), foobar);
1551 assert_eq!(pool.handle_of(pool.borrow(bar)), bar);
1552 assert_eq!(pool.handle_of(pool.borrow(baz)), baz);
1553 }
1554
1555 #[derive(Debug, Eq, PartialEq)]
1556 struct Payload;
1557
1558 #[test]
1559 fn pool_test_spawn_at() {
1560 let mut pool = Pool::<Payload>::new();
1561
1562 assert_eq!(pool.spawn_at(2, Payload), Ok(Handle::new(2, 1)));
1563 assert_eq!(pool.spawn_at(2, Payload), Err(Payload));
1564 assert_eq!(pool.records[0].payload.as_ref(), None);
1565 assert_eq!(pool.records[1].payload.as_ref(), None);
1566 assert_ne!(pool.records[2].payload.as_ref(), None);
1567
1568 assert_eq!(pool.spawn_at(2, Payload), Err(Payload));
1569
1570 pool.free(Handle::new(2, 1));
1571
1572 assert_eq!(pool.spawn_at(2, Payload), Ok(Handle::new(2, 2)));
1573
1574 assert_eq!(pool.spawn(Payload), Handle::new(1, 2));
1575 assert_eq!(pool.spawn(Payload), Handle::new(0, 2));
1576 }
1577
1578 #[test]
1579 fn pool_test_try_free() {
1580 let mut pool = Pool::<Payload>::new();
1581
1582 assert_eq!(pool.try_free(Handle::NONE), None);
1583 assert_eq!(pool.free_stack.len(), 0);
1584
1585 let handle = pool.spawn(Payload);
1586 assert_eq!(pool.try_free(handle), Some(Payload));
1587 assert_eq!(pool.free_stack.len(), 1);
1588 assert_eq!(pool.try_free(handle), None);
1589 assert_eq!(pool.free_stack.len(), 1);
1590 }
1591
1592 #[test]
1593 fn visit_for_pool_record() {
1594 let mut p = PoolRecord::<u32>::default();
1595 let mut visitor = Visitor::default();
1596
1597 assert!(p.visit("name", &mut visitor).is_ok());
1598 }
1599
1600 #[test]
1601 fn visit_for_pool() {
1602 let mut p = Pool::<u32>::default();
1603 let mut visitor = Visitor::default();
1604
1605 assert!(p.visit("name", &mut visitor).is_ok());
1606 }
1607
1608 #[test]
1609 fn default_for_pool() {
1610 assert_eq!(Pool::default(), Pool::<u32>::new());
1611 }
1612
1613 #[test]
1614 fn pool_with_capacity() {
1615 let p = Pool::<u32>::with_capacity(1);
1616 assert_eq!(p.records, Vec::with_capacity(1));
1617 assert_eq!(p.free_stack, Vec::new())
1618 }
1619
1620 #[test]
1621 fn pool_try_borrow() {
1622 let mut pool = Pool::<Payload>::new();
1623 let a = pool.spawn(Payload);
1624 let b = Handle::<Payload>::default();
1625
1626 assert_eq!(pool.try_borrow(a), Some(&Payload));
1627 assert_eq!(pool.try_borrow(b), None);
1628 }
1629
1630 #[test]
1631 fn pool_borrow_two_mut() {
1632 let mut pool = Pool::<u32>::new();
1633 let a = pool.spawn(1);
1634 let b = pool.spawn(2);
1635 let (a, b) = pool.borrow_two_mut((a, b));
1636
1637 assert_eq!(a, &mut 1);
1638 assert_eq!(b, &mut 2);
1639 }
1640
1641 #[test]
1642 fn pool_borrow_three_mut() {
1643 let mut pool = Pool::<u32>::new();
1644 let a = pool.spawn(1);
1645 let b = pool.spawn(2);
1646 let c = pool.spawn(3);
1647 let (a, b, c) = pool.borrow_three_mut((a, b, c));
1648
1649 assert_eq!(a, &mut 1);
1650 assert_eq!(b, &mut 2);
1651 assert_eq!(c, &mut 3);
1652 }
1653
1654 #[test]
1655 fn pool_borrow_four_mut() {
1656 let mut pool = Pool::<u32>::new();
1657 let a = pool.spawn(1);
1658 let b = pool.spawn(2);
1659 let c = pool.spawn(3);
1660 let d = pool.spawn(4);
1661 let (a, b, c, d) = pool.borrow_four_mut((a, b, c, d));
1662
1663 assert_eq!(a, &mut 1);
1664 assert_eq!(b, &mut 2);
1665 assert_eq!(c, &mut 3);
1666 assert_eq!(d, &mut 4);
1667 }
1668
1669 #[test]
1670 fn pool_try_borrow_dependant_mut() {
1671 let mut pool = Pool::<u32>::new();
1672 let a = pool.spawn(42);
1673 let b = pool.spawn(5);
1674
1675 assert_eq!(
1676 pool.try_borrow_dependant_mut(a, |_| b),
1677 (Some(&mut 42), Some(&mut 5))
1678 );
1679
1680 assert_eq!(
1681 pool.try_borrow_dependant_mut(a, |_| a),
1682 (Some(&mut 42), None)
1683 );
1684 }
1685
1686 #[test]
1687 fn pool_try_take_reserve() {
1688 let mut pool = Pool::<u32>::new();
1689
1690 let a = Handle::<u32>::default();
1691 assert!(pool.try_take_reserve(a).is_none());
1692
1693 let b = pool.spawn(42);
1694
1695 let (ticket, payload) = pool.try_take_reserve(b).unwrap();
1696 assert_eq!(ticket.index, 0);
1697 assert_eq!(payload, 42);
1698
1699 assert!(pool.try_take_reserve(a).is_none());
1700 assert!(pool.try_take_reserve(b).is_none());
1701
1702 pool.forget_ticket(ticket);
1703 }
1704
1705 #[test]
1706 fn pool_put_back() {
1707 let mut pool = Pool::<u32>::new();
1708 let a = pool.spawn(42);
1709 let (ticket, value) = pool.take_reserve(a);
1710 let b = pool.put_back(ticket, value);
1711
1712 assert_eq!(a, b);
1713 }
1714
1715 #[test]
1716 fn pool_forget_ticket() {
1717 let mut pool = Pool::<u32>::new();
1718 let a = pool.spawn(42);
1719 let (ticket, _) = pool.take_reserve(a);
1720
1721 pool.forget_ticket(ticket);
1722
1723 let b = pool.spawn(42);
1724
1725 assert_eq!(a.index, b.index);
1726 assert_ne!(a.generation, b.generation);
1727 }
1728
1729 #[test]
1730 fn pool_get_capacity() {
1731 let mut pool = Pool::<u32>::new();
1732 let _ = pool.spawn(42);
1733 let _ = pool.spawn(5);
1734
1735 assert_eq!(pool.get_capacity(), 2);
1736 }
1737
1738 #[test]
1739 fn pool_clear() {
1740 let mut pool = Pool::<u32>::new();
1741 let _ = pool.spawn(42);
1742
1743 assert!(!pool.records.is_empty());
1744
1745 pool.clear();
1746
1747 assert!(pool.records.is_empty());
1748 assert!(pool.free_stack.is_empty());
1749 }
1750
1751 #[test]
1752 fn pool_at_mut() {
1753 let mut pool = Pool::<u32>::new();
1754 let _ = pool.spawn(42);
1755
1756 assert_eq!(pool.at_mut(0), Some(&mut 42));
1757 assert_eq!(pool.at_mut(1), None);
1758 }
1759
1760 #[test]
1761 fn pool_at() {
1762 let mut pool = Pool::<u32>::new();
1763 let _ = pool.spawn(42);
1764
1765 assert_eq!(pool.at(0), Some(&42));
1766 assert_eq!(pool.at(1), None);
1767 }
1768
1769 #[test]
1770 fn pool_handle_from_index() {
1771 let mut pool = Pool::<u32>::new();
1772 let a = pool.spawn(42);
1773
1774 assert_eq!(pool.handle_from_index(0), a);
1775 assert_eq!(pool.handle_from_index(1), Handle::NONE);
1776 }
1777
1778 #[test]
1779 fn pool_alive_count() {
1780 let mut pool = Pool::<u32>::new();
1781 let a = pool.spawn(42);
1782 let _ = pool.spawn(5);
1783 let (ticket, _) = pool.take_reserve(a);
1784 pool.forget_ticket(ticket);
1785
1786 assert_eq!(pool.alive_count(), 1);
1787 }
1788
1789 #[test]
1790 fn pool_total_count() {
1791 let mut pool = Pool::<u32>::new();
1792 let a = pool.spawn(42);
1793 let _ = pool.spawn(5);
1794 let (ticket, _) = pool.take_reserve(a);
1795
1796 assert_eq!(pool.total_count(), 2);
1797
1798 pool.forget_ticket(ticket);
1799 }
1800
1801 #[test]
1802 fn pool_replace() {
1803 let mut pool = Pool::<u32>::new();
1804 let a = pool.spawn(42);
1805 let b = Handle::<u32>::new(1, 1);
1806
1807 assert_eq!(pool.replace(a, 5), Some(42));
1808 assert_eq!(pool.replace(b, 5), None);
1809 }
1810
1811 #[test]
1812 fn pool_pair_iter() {
1813 let pool = Pool::<u32>::new();
1814
1815 let iter = pool.pair_iter();
1816
1817 assert_eq!(iter.pool, &pool);
1818 assert_eq!(iter.current, 0);
1819 }
1820
1821 #[test]
1822 fn pool_pair_iter_mut() {
1823 let mut pool = Pool::<u32>::new();
1824 let _ = pool.spawn(42);
1825
1826 let iter = pool.pair_iter_mut();
1827
1828 assert_eq!(iter.current, 0);
1829 assert_eq!(iter.ptr, pool.records.as_mut_ptr());
1830 }
1831
1832 #[test]
1833 fn index_for_pool() {
1834 let mut pool = Pool::<u32>::new();
1835 let a = pool.spawn(42);
1836 let b = pool.spawn(5);
1837
1838 assert_eq!(pool[a], 42);
1839 assert_eq!(pool[b], 5);
1840 }
1841
1842 #[test]
1843 fn index_mut_for_pool() {
1844 let mut pool = Pool::<u32>::new();
1845 let a = pool.spawn(42);
1846 let b = pool.spawn(5);
1847
1848 pool[a] = 15;
1849
1850 assert_eq!(pool[a], 15);
1851 assert_eq!(pool[b], 5);
1852 }
1853
1854 #[test]
1855 fn test_atomic_handle() {
1856 let handle = AtomicHandle::new(123, 321);
1857 assert!(handle.is_some());
1858 assert_eq!(handle.index(), 123);
1859 assert_eq!(handle.generation(), 321);
1860
1861 let handle = AtomicHandle::default();
1862 assert!(handle.is_none());
1863 }
1864
1865 #[test]
1866 fn test_generate_free_handles() {
1867 let mut pool = Pool::<u32>::new();
1868
1869 let _ = pool.spawn(42);
1870 let b = pool.spawn(5);
1871 let _ = pool.spawn(228);
1872
1873 pool.free(b);
1874
1875 let h0 = Handle::new(1, 2);
1876 let h1 = Handle::new(3, 1);
1877 let h2 = Handle::new(4, 1);
1878 let h3 = Handle::new(5, 1);
1879 let h4 = Handle::new(6, 1);
1880
1881 let free_handles = pool.generate_free_handles(5);
1882 assert_eq!(free_handles, [h0, h1, h2, h3, h4]);
1883
1884 for (i, handle) in free_handles.into_iter().enumerate() {
1886 let instance_handle = pool.spawn_at_handle(handle, i as u32);
1887 assert_eq!(instance_handle, Ok(handle));
1888 }
1889
1890 assert_eq!(pool[h0], 0);
1891 assert_eq!(pool[h1], 1);
1892 assert_eq!(pool[h2], 2);
1893 assert_eq!(pool[h3], 3);
1894 assert_eq!(pool[h4], 4);
1895 }
1896}