fyrox_core/pool/
mod.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! A generational arena - a contiguous growable array type which allows removing
22//! from the middle without shifting and therefore without invalidating other indices.
23//!
24//! Pool is a contiguous block of memory with fixed-size entries, each entry can be
25//! either vacant or occupied. When you put an object into the pool you get a handle to
26//! that object. You can use that handle later on to borrow a reference to an object.
27//! A handle can point to some object or be invalid, this may look similar to raw
28//! pointers, but there is two major differences:
29//!
30//! 1) We can check if a handle is valid before accessing the object it might point to.
31//! 2) We can ensure the handle we're using is still valid for the object it points to
32//! to make sure it hasn't been replaced with a different object on the same position.
33//! Each handle stores a special field called generation which is shared across the entry
34//! and the handle, so the handle is valid if these fields are the same on both the entry
35//! and the handle. This protects from situations where you have a handle that has
36//! a valid index of a record, but the payload in this record has been replaced.
37//!
38//! Contiguous memory block increases efficiency of memory operations - the CPU will
39//! load portions of data into its cache piece by piece, it will be free from any
40//! indirections that might cause cache invalidation. This is the so called cache
41//! friendliness.
42
43use crate::{reflect::prelude::*, visitor::prelude::*, ComponentProvider};
44use std::cell::UnsafeCell;
45use std::{
46    any::{Any, TypeId},
47    fmt::Debug,
48    future::Future,
49    marker::PhantomData,
50    ops::{Index, IndexMut},
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/// Pool allows to create as many objects as you want in contiguous memory
64/// block. It allows to create and delete objects much faster than if they'll
65/// be allocated on heap. Also since objects stored in contiguous memory block
66/// they can be effectively accessed because such memory layout is cache-friendly.
67#[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// Zero - non-borrowed.
185// Negative values - amount of mutable borrows, positive - amount of immutable borrows.
186#[derive(Default, Debug)]
187struct RefCounter(pub UnsafeCell<isize>);
188
189unsafe impl Sync for RefCounter {}
190unsafe impl Send for RefCounter {}
191
192impl RefCounter {
193    unsafe fn get(&self) -> isize {
194        *self.0.get()
195    }
196
197    unsafe fn increment(&self) {
198        *self.0.get() += 1;
199    }
200
201    unsafe fn decrement(&self) {
202        *self.0.get() -= 1;
203    }
204}
205
206#[derive(Debug)]
207struct PoolRecord<T, P = Option<T>>
208where
209    T: Sized,
210    P: PayloadContainer<Element = T>,
211{
212    ref_counter: RefCounter,
213    // Generation number, used to keep info about lifetime. The handle is valid
214    // only if record it points to is of the same generation as the pool record.
215    // Notes: Zero is unknown generation used for None handles.
216    generation: u32,
217    // Actual payload.
218    payload: Payload<P>,
219}
220
221impl<T, P> PartialEq for PoolRecord<T, P>
222where
223    T: PartialEq,
224    P: PayloadContainer<Element = T> + PartialEq,
225{
226    #[inline]
227    fn eq(&self, other: &Self) -> bool {
228        self.generation == other.generation && self.payload.get() == other.payload.get()
229    }
230}
231
232impl<T, P> Default for PoolRecord<T, P>
233where
234    P: PayloadContainer<Element = T> + 'static,
235{
236    #[inline]
237    fn default() -> Self {
238        Self {
239            ref_counter: Default::default(),
240            generation: INVALID_GENERATION,
241            payload: Payload::new_empty(),
242        }
243    }
244}
245
246impl<T, P> Visit for PoolRecord<T, P>
247where
248    T: Visit + 'static,
249    P: PayloadContainer<Element = T> + Visit,
250{
251    #[inline]
252    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
253        let mut region = visitor.enter_region(name)?;
254
255        self.generation.visit("Generation", &mut region)?;
256        self.payload.get_mut().visit("Payload", &mut region)?;
257
258        Ok(())
259    }
260}
261
262impl<T> Clone for Handle<T> {
263    #[inline]
264    fn clone(&self) -> Handle<T> {
265        *self
266    }
267}
268
269impl<T, P> Visit for Pool<T, P>
270where
271    T: Visit + 'static,
272    P: PayloadContainer<Element = T> + Default + Visit + 'static,
273{
274    #[inline]
275    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
276        let mut region = visitor.enter_region(name)?;
277        self.records.visit("Records", &mut region)?;
278        self.free_stack.visit("FreeStack", &mut region)?;
279        Ok(())
280    }
281}
282
283impl<T, P> Default for Pool<T, P>
284where
285    T: 'static,
286    P: PayloadContainer<Element = T> + 'static,
287{
288    #[inline]
289    fn default() -> Self {
290        Self::new()
291    }
292}
293
294#[derive(Debug)]
295pub struct Ticket<T> {
296    index: u32,
297    marker: PhantomData<T>,
298}
299
300impl<T> Drop for Ticket<T> {
301    fn drop(&mut self) {
302        panic!(
303            "An object at index {} must be returned to a pool it was taken from! \
304            Call Pool::forget_ticket if you don't need the object anymore.",
305            self.index
306        )
307    }
308}
309
310impl<T: Clone> Clone for PoolRecord<T> {
311    #[inline]
312    fn clone(&self) -> Self {
313        Self {
314            ref_counter: Default::default(),
315            generation: self.generation,
316            payload: self.payload.clone(),
317        }
318    }
319}
320
321impl<T: Clone> Clone for Pool<T> {
322    #[inline]
323    fn clone(&self) -> Self {
324        Self {
325            records: self.records.clone(),
326            free_stack: self.free_stack.clone(),
327        }
328    }
329}
330
331impl<T, P> Pool<T, P>
332where
333    P: PayloadContainer<Element = T> + 'static,
334{
335    #[inline]
336    pub fn new() -> Self {
337        Pool {
338            records: Vec::new(),
339            free_stack: Vec::new(),
340        }
341    }
342
343    #[inline]
344    pub fn with_capacity(capacity: u32) -> Self {
345        let capacity = usize::try_from(capacity).expect("capacity overflowed usize");
346        Pool {
347            records: Vec::with_capacity(capacity),
348            free_stack: Vec::new(),
349        }
350    }
351
352    fn records_len(&self) -> u32 {
353        u32::try_from(self.records.len()).expect("Number of records overflowed u32")
354    }
355
356    fn records_get(&self, index: u32) -> Option<&PoolRecord<T, P>> {
357        let index = usize::try_from(index).expect("Index overflowed usize");
358        self.records.get(index)
359    }
360
361    fn records_get_mut(&mut self, index: u32) -> Option<&mut PoolRecord<T, P>> {
362        let index = usize::try_from(index).expect("Index overflowed usize");
363        self.records.get_mut(index)
364    }
365
366    #[inline]
367    #[must_use]
368    pub fn spawn(&mut self, payload: T) -> Handle<T> {
369        self.spawn_with(|_| payload)
370    }
371
372    /// Tries to put an object in the pool at given position. Returns `Err(payload)` if a corresponding
373    /// entry is occupied.
374    ///
375    /// # Performance
376    ///
377    /// The method has O(n) complexity in worst case, where `n` - amount of free records in the pool.
378    /// In typical uses cases `n` is very low. It should be noted that if a pool is filled entirely
379    /// and you trying to put an object at the end of pool, the method will have O(1) complexity.
380    ///
381    /// # Panics
382    ///
383    /// Panics if the index is occupied or reserved (e.g. by [`take_reserve`]).
384    ///
385    /// [`take_reserve`]: Pool::take_reserve
386    #[inline]
387    pub fn spawn_at(&mut self, index: u32, payload: T) -> Result<Handle<T>, T> {
388        self.spawn_at_internal(index, INVALID_GENERATION, payload)
389    }
390
391    /// Tries to put an object in the pool at given handle. Returns `Err(payload)` if a corresponding
392    /// entry is occupied.
393    ///
394    /// # Performance
395    ///
396    /// The method has O(n) complexity in worst case, where `n` - amount of free records in the pool.
397    /// In typical uses cases `n` is very low. It should be noted that if a pool is filled entirely
398    /// and you trying to put an object at the end of pool, the method will have O(1) complexity.
399    ///
400    /// # Panics
401    ///
402    /// Panics if the index is occupied or reserved (e.g. by [`take_reserve`]).
403    ///
404    /// [`take_reserve`]: Pool::take_reserve
405    #[inline]
406    pub fn spawn_at_handle(&mut self, handle: Handle<T>, payload: T) -> Result<Handle<T>, T> {
407        self.spawn_at_internal(handle.index, handle.generation, payload)
408    }
409
410    fn spawn_at_internal(
411        &mut self,
412        index: u32,
413        desired_generation: u32,
414        payload: T,
415    ) -> Result<Handle<T>, T> {
416        let index_usize = usize::try_from(index).expect("index overflowed usize");
417        match self.records.get_mut(index_usize) {
418            Some(record) => match record.payload.as_ref() {
419                Some(_) => Err(payload),
420                None => {
421                    let position = self
422                        .free_stack
423                        .iter()
424                        .rposition(|i| *i == index)
425                        .expect("free_stack must contain the index of the empty record (most likely attempting to spawn at a reserved index)!");
426
427                    self.free_stack.remove(position);
428
429                    let generation = if desired_generation == INVALID_GENERATION {
430                        record.generation + 1
431                    } else {
432                        desired_generation
433                    };
434
435                    record.generation = generation;
436                    record.payload = Payload::new(payload);
437
438                    Ok(Handle::new(index, generation))
439                }
440            },
441            None => {
442                // Spawn missing records to fill gaps.
443                for i in self.records_len()..index {
444                    self.records.push(PoolRecord {
445                        ref_counter: Default::default(),
446                        generation: 1,
447                        payload: Payload::new_empty(),
448                    });
449                    self.free_stack.push(i);
450                }
451
452                let generation = if desired_generation == INVALID_GENERATION {
453                    1
454                } else {
455                    desired_generation
456                };
457
458                self.records.push(PoolRecord {
459                    ref_counter: Default::default(),
460                    generation,
461                    payload: Payload::new(payload),
462                });
463
464                Ok(Handle::new(index, generation))
465            }
466        }
467    }
468
469    #[inline]
470    #[must_use]
471    /// Construct a value with the handle it would be given.
472    /// Note: Handle is _not_ valid until function has finished executing.
473    pub fn spawn_with<F: FnOnce(Handle<T>) -> T>(&mut self, callback: F) -> Handle<T> {
474        if let Some(free_index) = self.free_stack.pop() {
475            let record = self
476                .records_get_mut(free_index)
477                .expect("free stack contained invalid index");
478
479            if record.payload.is_some() {
480                panic!(
481                    "Attempt to spawn an object at pool record with payload! Record index is {free_index}"
482                );
483            }
484
485            let generation = record.generation + 1;
486            let handle = Handle {
487                index: free_index,
488                generation,
489                type_marker: PhantomData,
490            };
491
492            let payload = callback(handle);
493
494            record.generation = generation;
495            record.payload.replace(payload);
496            handle
497        } else {
498            // No free records, create new one
499            let generation = 1;
500
501            let handle = Handle {
502                index: self.records.len() as u32,
503                generation,
504                type_marker: PhantomData,
505            };
506
507            let payload = callback(handle);
508
509            let record = PoolRecord {
510                ref_counter: Default::default(),
511                generation,
512                payload: Payload::new(payload),
513            };
514
515            self.records.push(record);
516
517            handle
518        }
519    }
520
521    #[inline]
522    /// Asynchronously construct a value with the handle it would be given.
523    /// Note: Handle is _not_ valid until function has finished executing.
524    pub async fn spawn_with_async<F, Fut>(&mut self, callback: F) -> Handle<T>
525    where
526        F: FnOnce(Handle<T>) -> Fut,
527        Fut: Future<Output = T>,
528    {
529        if let Some(free_index) = self.free_stack.pop() {
530            let record = self
531                .records_get_mut(free_index)
532                .expect("free stack contained invalid index");
533
534            if record.payload.is_some() {
535                panic!(
536                    "Attempt to spawn an object at pool record with payload! Record index is {free_index}"
537                );
538            }
539
540            let generation = record.generation + 1;
541            let handle = Handle {
542                index: free_index,
543                generation,
544                type_marker: PhantomData,
545            };
546
547            let payload = callback(handle).await;
548
549            record.generation = generation;
550            record.payload.replace(payload);
551            handle
552        } else {
553            // No free records, create new one
554            let generation = 1;
555
556            let handle = Handle {
557                index: self.records.len() as u32,
558                generation,
559                type_marker: PhantomData,
560            };
561
562            let payload = callback(handle).await;
563
564            let record = PoolRecord {
565                generation,
566                ref_counter: Default::default(),
567                payload: Payload::new(payload),
568            };
569
570            self.records.push(record);
571
572            handle
573        }
574    }
575
576    /// Generates a set of handles that could be used to spawn a set of objects. This method does not
577    /// modify the pool and the generated handles could be used together with [`Self::spawn_at_handle`]
578    /// method.
579    #[inline]
580    pub fn generate_free_handles(&self, amount: usize) -> Vec<Handle<T>> {
581        let mut free_handles = Vec::with_capacity(amount);
582        free_handles.extend(
583            self.free_stack
584                .iter()
585                .take(amount)
586                .map(|i| Handle::new(*i, self.records[*i as usize].generation + 1)),
587        );
588        if free_handles.len() < amount {
589            let remainder = amount - free_handles.len();
590            free_handles.extend(
591                (self.records.len()..self.records.len() + remainder)
592                    .map(|i| Handle::new(i as u32, 1)),
593            );
594        }
595        free_handles
596    }
597
598    /// Borrows shared reference to an object by its handle.
599    ///
600    /// # Panics
601    ///
602    /// Panics if handle is out of bounds or generation of handle does not match with
603    /// generation of pool record at handle index (in other words it means that object
604    /// at handle's index is different than the object was there before).
605    #[inline]
606    #[must_use]
607    pub fn borrow(&self, handle: Handle<T>) -> &T {
608        if let Some(record) = self.records_get(handle.index) {
609            if record.generation == handle.generation {
610                if let Some(payload) = record.payload.as_ref() {
611                    payload
612                } else {
613                    panic!("Attempt to borrow destroyed object at {handle:?} handle.");
614                }
615            } else {
616                panic!(
617                    "Attempt to use dangling handle {:?}. Record has generation {}!",
618                    handle, record.generation
619                );
620            }
621        } else {
622            panic!(
623                "Attempt to borrow object using out-of-bounds handle {:?}! Record count is {}",
624                handle,
625                self.records.len()
626            );
627        }
628    }
629
630    /// Borrows mutable reference to an object by its handle.
631    ///
632    /// # Panics
633    ///
634    /// Panics if handle is out of bounds or generation of handle does not match with
635    /// generation of pool record at handle index (in other words it means that object
636    /// at handle's index is different than the object was there before).
637    ///
638    /// # Example
639    ///
640    /// ```
641    /// use fyrox_core::pool::Pool;
642    /// let mut pool = Pool::<u32>::new();
643    /// let a = pool.spawn(1);
644    /// let a = pool.borrow_mut(a);
645    /// *a = 11;
646    /// ```
647    #[inline]
648    #[must_use]
649    pub fn borrow_mut(&mut self, handle: Handle<T>) -> &mut T {
650        let record_count = self.records.len();
651        if let Some(record) = self.records_get_mut(handle.index) {
652            if record.generation == handle.generation {
653                if let Some(payload) = record.payload.as_mut() {
654                    payload
655                } else {
656                    panic!("Attempt to borrow destroyed object at {handle:?} handle.");
657                }
658            } else {
659                panic!("Attempt to borrow object using dangling handle {:?}. Record has {} generation!", handle, record.generation);
660            }
661        } else {
662            panic!(
663                "Attempt to borrow object using out-of-bounds handle {handle:?}! Record count is {record_count}"
664            );
665        }
666    }
667
668    /// Borrows shared reference to an object by its handle.
669    ///
670    /// Returns None if handle is out of bounds or generation of handle does not match with
671    /// generation of pool record at handle index (in other words it means that object
672    /// at handle's index is different than the object was there before).
673    #[inline]
674    #[must_use]
675    pub fn try_borrow(&self, handle: Handle<T>) -> Option<&T> {
676        self.records_get(handle.index).and_then(|r| {
677            if r.generation == handle.generation {
678                r.payload.as_ref()
679            } else {
680                None
681            }
682        })
683    }
684
685    /// Borrows mutable reference to an object by its handle.
686    ///
687    /// Returns None if handle is out of bounds or generation of handle does not match with
688    /// generation of pool record at handle index (in other words it means that object
689    /// at handle's index is different than the object was there before).
690    #[inline]
691    #[must_use]
692    pub fn try_borrow_mut(&mut self, handle: Handle<T>) -> Option<&mut T> {
693        self.records_get_mut(handle.index).and_then(|r| {
694            if r.generation == handle.generation {
695                r.payload.as_mut()
696            } else {
697                None
698            }
699        })
700    }
701
702    /// Borrows mutable references of objects at the same time. This method will succeed only
703    /// if handles are unique (not equal). Borrowing multiple mutable references at the same
704    /// time is useful in case if you need to mutate some objects at the same time.
705    ///
706    /// # Panics
707    ///
708    /// See [`borrow_mut`](Self::borrow_mut).
709    ///
710    /// # Example
711    ///
712    /// ```
713    /// use fyrox_core::pool::Pool;
714    /// let mut pool = Pool::<u32>::new();
715    /// let a = pool.spawn(1);
716    /// let b = pool.spawn(2);
717    /// let (a, b) = pool.borrow_two_mut((a, b));
718    /// *a = 11;
719    /// *b = 22;
720    /// ```
721    #[inline]
722    #[must_use = "Handle set must not be ignored"]
723    pub fn borrow_two_mut(&mut self, handles: (Handle<T>, Handle<T>)) -> (&mut T, &mut T) {
724        // Prevent giving two mutable references to same record.
725        assert_ne!(handles.0.index, handles.1.index);
726        unsafe {
727            let this = self as *mut Self;
728            ((*this).borrow_mut(handles.0), (*this).borrow_mut(handles.1))
729        }
730    }
731
732    /// Borrows mutable references of objects at the same time. This method will succeed only
733    /// if handles are unique (not equal). Borrowing multiple mutable references at the same
734    /// time is useful in case if you need to mutate some objects at the same time.
735    ///
736    /// # Panics
737    ///
738    /// See [`borrow_mut`](Self::borrow_mut).
739    ///
740    /// # Example
741    ///
742    /// ```
743    /// use fyrox_core::pool::Pool;
744    /// let mut pool = Pool::<u32>::new();
745    /// let a = pool.spawn(1);
746    /// let b = pool.spawn(2);
747    /// let c = pool.spawn(3);
748    /// let (a, b, c) = pool.borrow_three_mut((a, b, c));
749    /// *a = 11;
750    /// *b = 22;
751    /// *c = 33;
752    /// ```
753    #[inline]
754    #[must_use = "Handle set must not be ignored"]
755    pub fn borrow_three_mut(
756        &mut self,
757        handles: (Handle<T>, Handle<T>, Handle<T>),
758    ) -> (&mut T, &mut T, &mut T) {
759        // Prevent giving mutable references to same record.
760        assert_ne!(handles.0.index, handles.1.index);
761        assert_ne!(handles.0.index, handles.2.index);
762        assert_ne!(handles.1.index, handles.2.index);
763        unsafe {
764            let this = self as *mut Self;
765            (
766                (*this).borrow_mut(handles.0),
767                (*this).borrow_mut(handles.1),
768                (*this).borrow_mut(handles.2),
769            )
770        }
771    }
772
773    /// Borrows mutable references of objects at the same time. This method will succeed only
774    /// if handles are unique (not equal). Borrowing multiple mutable references at the same
775    /// time is useful in case if you need to mutate some objects at the same time.
776    ///
777    /// # Panics
778    ///
779    /// See [`borrow_mut`](Self::borrow_mut).
780    ///
781    /// # Example
782    ///
783    /// ```
784    /// use fyrox_core::pool::Pool;
785    /// let mut pool = Pool::<u32>::new();
786    /// let a = pool.spawn(1);
787    /// let b = pool.spawn(2);
788    /// let c = pool.spawn(3);
789    /// let d = pool.spawn(4);
790    /// let (a, b, c, d) = pool.borrow_four_mut((a, b, c, d));
791    /// *a = 11;
792    /// *b = 22;
793    /// *c = 33;
794    /// *d = 44;
795    /// ```
796    #[inline]
797    #[must_use = "Handle set must not be ignored"]
798    pub fn borrow_four_mut(
799        &mut self,
800        handles: (Handle<T>, Handle<T>, Handle<T>, Handle<T>),
801    ) -> (&mut T, &mut T, &mut T, &mut T) {
802        // Prevent giving mutable references to same record.
803        // This is kinda clunky since const generics are not stabilized yet.
804        assert_ne!(handles.0.index, handles.1.index);
805        assert_ne!(handles.0.index, handles.2.index);
806        assert_ne!(handles.0.index, handles.3.index);
807        assert_ne!(handles.1.index, handles.2.index);
808        assert_ne!(handles.1.index, handles.3.index);
809        assert_ne!(handles.2.index, handles.3.index);
810        unsafe {
811            let this = self as *mut Self;
812            (
813                (*this).borrow_mut(handles.0),
814                (*this).borrow_mut(handles.1),
815                (*this).borrow_mut(handles.2),
816                (*this).borrow_mut(handles.3),
817            )
818        }
819    }
820
821    /// Tries to borrow two objects when a handle to the second object stored in the first object.
822    #[inline]
823    pub fn try_borrow_dependant_mut<F>(
824        &mut self,
825        handle: Handle<T>,
826        func: F,
827    ) -> (Option<&mut T>, Option<&mut T>)
828    where
829        F: FnOnce(&T) -> Handle<T>,
830    {
831        let this = unsafe { &mut *(self as *mut Pool<T, P>) };
832        let first = self.try_borrow_mut(handle);
833        if let Some(first_object) = first.as_ref() {
834            let second_handle = func(first_object);
835            if second_handle != handle {
836                return (first, this.try_borrow_mut(second_handle));
837            }
838        }
839
840        (first, None)
841    }
842
843    /// Moves object out of the pool using the given handle. All handles to the object will become invalid.
844    ///
845    /// # Panics
846    ///
847    /// Panics if the given handle is invalid.
848    #[inline]
849    pub fn free(&mut self, handle: Handle<T>) -> T {
850        let index = usize::try_from(handle.index).expect("index overflowed usize");
851        if let Some(record) = self.records.get_mut(index) {
852            if record.generation == handle.generation {
853                // Remember this index as free
854                self.free_stack.push(handle.index);
855                // Return current payload.
856                if let Some(payload) = record.payload.take() {
857                    payload
858                } else {
859                    panic!("Attempt to double free object at handle {handle:?}!");
860                }
861            } else {
862                panic!(
863                    "Attempt to free object using dangling handle {:?}! Record generation is {}",
864                    handle, record.generation
865                );
866            }
867        } else {
868            panic!("Attempt to free destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len());
869        }
870    }
871
872    /// Tries to move object out of the pool using the given handle. Returns None if given handle
873    /// is invalid. After object is moved out if the pool, all handles to the object will become
874    /// invalid.
875    #[inline]
876    pub fn try_free(&mut self, handle: Handle<T>) -> Option<T> {
877        let index = usize::try_from(handle.index).expect("index overflowed usize");
878        self.records.get_mut(index).and_then(|record| {
879            if record.generation == handle.generation {
880                if let Some(payload) = record.payload.take() {
881                    self.free_stack.push(handle.index);
882                    Some(payload)
883                } else {
884                    None
885                }
886            } else {
887                None
888            }
889        })
890    }
891
892    /// Moves an object out of the pool using the given handle with a promise that the object will be returned back.
893    /// Returns pair (ticket, value). The ticket must be used to put the value back!
894    ///
895    /// # Motivation
896    ///
897    /// This method is useful when you need to take temporary ownership of an object, do something
898    /// with it and then put it back while preserving all handles to it and being able to put new objects into
899    /// the pool without overriding the payload at its handle.
900    ///
901    /// # Notes
902    ///
903    /// All handles to the object will be temporarily invalid until the object is returned to the pool! The pool record will
904    /// be reserved for a further [`put_back`] call, which means if you lose the ticket you will have an empty
905    /// "unusable" pool record forever.
906    ///
907    /// # Panics
908    ///
909    /// Panics if the given handle is invalid.
910    ///
911    /// [`put_back`]: Pool::put_back
912    #[inline]
913    pub fn take_reserve(&mut self, handle: Handle<T>) -> (Ticket<T>, T) {
914        if let Some(record) = self.records_get_mut(handle.index) {
915            if record.generation == handle.generation {
916                if let Some(payload) = record.payload.take() {
917                    let ticket = Ticket {
918                        index: handle.index,
919                        marker: PhantomData,
920                    };
921                    (ticket, payload)
922                } else {
923                    panic!("Attempt to take already taken object at handle {handle:?}!");
924                }
925            } else {
926                panic!(
927                    "Attempt to take object using dangling handle {:?}! Record generation is {}",
928                    handle, record.generation
929                );
930            }
931        } else {
932            panic!("Attempt to take destroyed object using out-of-bounds handle {:?}! Record count is {}", handle, self.records.len());
933        }
934    }
935
936    /// Does the same as [`take_reserve`] but returns an option, instead of panicking.
937    ///
938    /// [`take_reserve`]: Pool::take_reserve
939    #[inline]
940    pub fn try_take_reserve(&mut self, handle: Handle<T>) -> Option<(Ticket<T>, T)> {
941        if let Some(record) = self.records_get_mut(handle.index) {
942            if record.generation == handle.generation {
943                if let Some(payload) = record.payload.take() {
944                    let ticket = Ticket {
945                        index: handle.index,
946                        marker: PhantomData,
947                    };
948                    Some((ticket, payload))
949                } else {
950                    None
951                }
952            } else {
953                None
954            }
955        } else {
956            None
957        }
958    }
959
960    /// Returns the value back into the pool using the given ticket. See [`take_reserve`] for more
961    /// information.
962    ///
963    /// [`take_reserve`]: Pool::take_reserve
964    #[inline]
965    pub fn put_back(&mut self, ticket: Ticket<T>, value: T) -> Handle<T> {
966        let record = self
967            .records_get_mut(ticket.index)
968            .expect("Ticket index was invalid");
969        let old = record.payload.replace(value);
970        assert!(old.is_none());
971        let handle = Handle::new(ticket.index, record.generation);
972        std::mem::forget(ticket);
973        handle
974    }
975
976    /// Forgets that value at ticket was reserved and makes it usable again.
977    /// Useful when you don't need to put value back by ticket, but just make
978    /// pool record usable again.
979    #[inline]
980    pub fn forget_ticket(&mut self, ticket: Ticket<T>) {
981        self.free_stack.push(ticket.index);
982        std::mem::forget(ticket);
983    }
984
985    /// Returns total capacity of pool. Capacity has nothing about real amount of objects in pool!
986    #[inline]
987    #[must_use]
988    pub fn get_capacity(&self) -> u32 {
989        u32::try_from(self.records.len()).expect("records.len() overflowed u32")
990    }
991
992    /// Destroys all objects in pool. All handles to objects will become invalid.
993    ///
994    /// # Remarks
995    ///
996    /// Use this method cautiously if objects in pool have cross "references" (handles)
997    /// to each other. This method will make all produced handles invalid and any further
998    /// calls for [`borrow`](Self::borrow) or [`borrow_mut`](Self::borrow_mut) will raise panic.
999    #[inline]
1000    pub fn clear(&mut self) {
1001        self.records.clear();
1002        self.free_stack.clear();
1003    }
1004
1005    #[inline]
1006    #[must_use]
1007    pub fn at_mut(&mut self, n: u32) -> Option<&mut T> {
1008        self.records_get_mut(n).and_then(|rec| rec.payload.as_mut())
1009    }
1010
1011    #[inline]
1012    #[must_use]
1013    pub fn at(&self, n: u32) -> Option<&T> {
1014        self.records_get(n)
1015            .and_then(|rec| rec.payload.get().as_ref())
1016    }
1017
1018    #[inline]
1019    #[must_use]
1020    pub fn handle_from_index(&self, n: u32) -> Handle<T> {
1021        if let Some(record) = self.records_get(n) {
1022            if record.generation != INVALID_GENERATION {
1023                return Handle::new(n, record.generation);
1024            }
1025        }
1026        Handle::NONE
1027    }
1028
1029    /// Returns the exact number of "alive" objects in the pool.
1030    ///
1031    /// Records that have been reserved (e.g. by [`take_reserve`]) are *not* counted.
1032    ///
1033    /// It iterates through the entire pool to count the live objects so the complexity is `O(n)`.
1034    ///
1035    /// See also [`total_count`].
1036    ///
1037    /// # Example
1038    ///
1039    /// ```
1040    /// use fyrox_core::pool::Pool;
1041    /// let mut pool = Pool::<u32>::new();
1042    /// pool.spawn(123);
1043    /// pool.spawn(321);
1044    /// assert_eq!(pool.alive_count(), 2);
1045    /// ```
1046    ///
1047    /// [`take_reserve`]: Pool::take_reserve
1048    /// [`total_count`]: Pool::total_count
1049    #[inline]
1050    #[must_use]
1051    pub fn alive_count(&self) -> u32 {
1052        let cnt = self.iter().count();
1053        u32::try_from(cnt).expect("alive_count overflowed u32")
1054    }
1055
1056    /// Returns the number of allocated objects in the pool.
1057    ///
1058    /// It also counts records that have been reserved (e.g. by [`take_reserve`]).
1059    ///
1060    /// This method is `O(1)`.
1061    ///
1062    /// See also [`alive_count`].
1063    ///
1064    /// [`take_reserve`]: Pool::take_reserve
1065    /// [`alive_count`]: Pool::alive_count
1066    #[inline]
1067    pub fn total_count(&self) -> u32 {
1068        let free = u32::try_from(self.free_stack.len()).expect("free stack length overflowed u32");
1069        self.records_len() - free
1070    }
1071
1072    #[inline]
1073    pub fn replace(&mut self, handle: Handle<T>, payload: T) -> Option<T> {
1074        let index_usize = usize::try_from(handle.index).expect("index overflowed usize");
1075        if let Some(record) = self.records.get_mut(index_usize) {
1076            if record.generation == handle.generation {
1077                self.free_stack.retain(|i| *i != handle.index);
1078
1079                record.payload.replace(payload)
1080            } else {
1081                panic!("Attempt to replace object in pool using dangling handle! Handle is {:?}, but pool record has {} generation", handle, record.generation);
1082            }
1083        } else {
1084            None
1085        }
1086    }
1087
1088    /// Returns a reference to the first element in the pool (if any).
1089    pub fn first_ref(&self) -> Option<&T> {
1090        self.iter().next()
1091    }
1092
1093    /// Returns a reference to the first element in the pool (if any).
1094    pub fn first_mut(&mut self) -> Option<&mut T> {
1095        self.iter_mut().next()
1096    }
1097
1098    /// Checks if given handle "points" to some object.
1099    ///
1100    /// # Example
1101    ///
1102    /// ```
1103    /// use fyrox_core::pool::Pool;
1104    /// let mut pool = Pool::<u32>::new();
1105    /// let handle = pool.spawn(123);
1106    /// assert_eq!(pool.is_valid_handle(handle), true)
1107    /// ```
1108    #[inline]
1109    pub fn is_valid_handle(&self, handle: Handle<T>) -> bool {
1110        if let Some(record) = self.records_get(handle.index) {
1111            record.payload.is_some() && record.generation == handle.generation
1112        } else {
1113            false
1114        }
1115    }
1116
1117    /// Creates new pool iterator that iterates over filled records in pool.
1118    ///
1119    /// # Example
1120    ///
1121    /// ```
1122    /// use fyrox_core::pool::Pool;
1123    /// let mut pool = Pool::<u32>::new();
1124    /// pool.spawn(123);
1125    /// pool.spawn(321);
1126    /// let mut iter = pool.iter();
1127    /// assert_eq!(*iter.next().unwrap(), 123);
1128    /// assert_eq!(*iter.next().unwrap(), 321);
1129    /// ```
1130    #[must_use]
1131    #[inline]
1132    pub fn iter(&self) -> PoolIterator<T, P> {
1133        unsafe {
1134            PoolIterator {
1135                ptr: self.records.as_ptr(),
1136                end: self.records.as_ptr().add(self.records.len()),
1137                marker: PhantomData,
1138            }
1139        }
1140    }
1141
1142    /// Creates new pair iterator that iterates over filled records using pair (handle, payload)
1143    /// Can be useful when there is a need to iterate over pool records and know a handle of
1144    /// that record.
1145    #[inline]
1146    pub fn pair_iter(&self) -> PoolPairIterator<T, P> {
1147        PoolPairIterator {
1148            pool: self,
1149            current: 0,
1150        }
1151    }
1152
1153    /// Creates new pool iterator that iterates over filled records in pool allowing
1154    /// to modify record payload.
1155    ///
1156    /// # Example
1157    ///
1158    /// ```
1159    /// use fyrox_core::pool::Pool;
1160    /// let mut pool = Pool::<u32>::new();
1161    /// pool.spawn(123);
1162    /// pool.spawn(321);
1163    /// let mut iter = pool.iter_mut();
1164    /// assert_eq!(*iter.next().unwrap(), 123);
1165    /// assert_eq!(*iter.next().unwrap(), 321);
1166    /// ```
1167    #[must_use]
1168    #[inline]
1169    pub fn iter_mut(&mut self) -> PoolIteratorMut<T, P> {
1170        unsafe {
1171            PoolIteratorMut {
1172                ptr: self.records.as_mut_ptr(),
1173                end: self.records.as_mut_ptr().add(self.records.len()),
1174                marker: PhantomData,
1175            }
1176        }
1177    }
1178
1179    /// Creates new pair iterator that iterates over filled records using pair (handle, payload)
1180    /// Can be useful when there is a need to iterate over pool records and know a handle of
1181    /// that record.
1182    #[inline]
1183    pub fn pair_iter_mut(&mut self) -> PoolPairIteratorMut<T, P> {
1184        unsafe {
1185            PoolPairIteratorMut {
1186                current: 0,
1187                ptr: self.records.as_mut_ptr(),
1188                end: self.records.as_mut_ptr().add(self.records.len()),
1189                marker: PhantomData,
1190            }
1191        }
1192    }
1193
1194    /// Retains pool records selected by `pred`. Useful when you need to remove all pool records
1195    /// by some criteria.
1196    #[inline]
1197    pub fn retain<F>(&mut self, mut pred: F)
1198    where
1199        F: FnMut(&T) -> bool,
1200    {
1201        for (i, record) in self.records.iter_mut().enumerate() {
1202            if record.generation == INVALID_GENERATION {
1203                continue;
1204            }
1205
1206            let retain = if let Some(payload) = record.payload.as_ref() {
1207                pred(payload)
1208            } else {
1209                continue;
1210            };
1211
1212            if !retain {
1213                self.free_stack.push(i as u32);
1214                record.payload.take(); // and Drop
1215            }
1216        }
1217    }
1218
1219    /// Begins multi-borrow that allows you to borrow as many (`N`) **unique** references to the pool
1220    /// elements as you need. See [`MultiBorrowContext::try_get`] for more info.
1221    #[inline]
1222    pub fn begin_multi_borrow(&mut self) -> MultiBorrowContext<T, P> {
1223        MultiBorrowContext::new(self)
1224    }
1225
1226    /// Removes all elements from the pool.
1227    #[inline]
1228    pub fn drain(&mut self) -> impl Iterator<Item = T> + '_ {
1229        self.free_stack.clear();
1230        self.records.drain(..).filter_map(|mut r| r.payload.take())
1231    }
1232
1233    fn end(&self) -> *const PoolRecord<T, P> {
1234        unsafe { self.records.as_ptr().add(self.records.len()) }
1235    }
1236
1237    fn begin(&self) -> *const PoolRecord<T, P> {
1238        self.records.as_ptr()
1239    }
1240
1241    #[inline]
1242    pub fn handle_of(&self, ptr: &T) -> Handle<T> {
1243        let begin = self.begin() as usize;
1244        let end = self.end() as usize;
1245        let val = ptr as *const T as usize;
1246        if val >= begin && val < end {
1247            let record_size = std::mem::size_of::<PoolRecord<T>>();
1248            let record_location = (val - offset_of!(PoolRecord<T>, payload)) - begin;
1249            if record_location % record_size == 0 {
1250                let index = record_location / record_size;
1251                let index = u32::try_from(index).expect("Index overflowed u32");
1252                return self.handle_from_index(index);
1253            }
1254        }
1255        Handle::NONE
1256    }
1257}
1258
1259impl<T, P> Pool<T, P>
1260where
1261    T: ComponentProvider,
1262    P: PayloadContainer<Element = T> + 'static,
1263{
1264    /// Tries to mutably borrow an object and fetch its component of specified type.
1265    #[inline]
1266    pub fn try_get_component_of_type<C>(&self, handle: Handle<T>) -> Option<&C>
1267    where
1268        C: 'static,
1269    {
1270        self.try_borrow(handle)
1271            .and_then(|n| n.query_component_ref(TypeId::of::<C>()))
1272            .and_then(|c| c.downcast_ref())
1273    }
1274
1275    /// Tries to mutably borrow an object and fetch its component of specified type.
1276    #[inline]
1277    pub fn try_get_component_of_type_mut<C>(&mut self, handle: Handle<T>) -> Option<&mut C>
1278    where
1279        C: 'static,
1280    {
1281        self.try_borrow_mut(handle)
1282            .and_then(|n| n.query_component_mut(TypeId::of::<C>()))
1283            .and_then(|c| c.downcast_mut())
1284    }
1285}
1286
1287impl<T> FromIterator<T> for Pool<T>
1288where
1289    T: 'static,
1290{
1291    #[inline]
1292    fn from_iter<C: IntoIterator<Item = T>>(iter: C) -> Self {
1293        let iter = iter.into_iter();
1294        let (lower_bound, upper_bound) = iter.size_hint();
1295        let lower_bound = u32::try_from(lower_bound).expect("lower_bound overflowed u32");
1296        let upper_bound =
1297            upper_bound.map(|b| u32::try_from(b).expect("upper_bound overflowed u32"));
1298        let mut pool = Self::with_capacity(upper_bound.unwrap_or(lower_bound));
1299        for v in iter {
1300            let _ = pool.spawn(v);
1301        }
1302        pool
1303    }
1304}
1305
1306impl<T, P> Index<Handle<T>> for Pool<T, P>
1307where
1308    T: 'static,
1309    P: PayloadContainer<Element = T> + 'static,
1310{
1311    type Output = T;
1312
1313    #[inline]
1314    fn index(&self, index: Handle<T>) -> &Self::Output {
1315        self.borrow(index)
1316    }
1317}
1318
1319impl<T, P> IndexMut<Handle<T>> for Pool<T, P>
1320where
1321    T: 'static,
1322    P: PayloadContainer<Element = T> + 'static,
1323{
1324    #[inline]
1325    fn index_mut(&mut self, index: Handle<T>) -> &mut Self::Output {
1326        self.borrow_mut(index)
1327    }
1328}
1329
1330impl<'a, T, P> IntoIterator for &'a Pool<T, P>
1331where
1332    P: PayloadContainer<Element = T> + 'static,
1333{
1334    type Item = &'a T;
1335    type IntoIter = PoolIterator<'a, T, P>;
1336
1337    #[inline]
1338    fn into_iter(self) -> Self::IntoIter {
1339        self.iter()
1340    }
1341}
1342
1343impl<'a, T, P> IntoIterator for &'a mut Pool<T, P>
1344where
1345    P: PayloadContainer<Element = T> + 'static,
1346{
1347    type Item = &'a mut T;
1348    type IntoIter = PoolIteratorMut<'a, T, P>;
1349
1350    #[inline]
1351    fn into_iter(self) -> Self::IntoIter {
1352        self.iter_mut()
1353    }
1354}
1355
1356pub struct PoolIterator<'a, T, P>
1357where
1358    P: PayloadContainer<Element = T>,
1359{
1360    ptr: *const PoolRecord<T, P>,
1361    end: *const PoolRecord<T, P>,
1362    marker: PhantomData<&'a T>,
1363}
1364
1365impl<'a, T, P> Iterator for PoolIterator<'a, T, P>
1366where
1367    P: PayloadContainer<Element = T> + 'static,
1368{
1369    type Item = &'a T;
1370
1371    #[inline]
1372    fn next(&mut self) -> Option<Self::Item> {
1373        unsafe {
1374            while self.ptr != self.end {
1375                let current = &*self.ptr;
1376                if let Some(payload) = current.payload.as_ref() {
1377                    self.ptr = self.ptr.offset(1);
1378                    return Some(payload);
1379                }
1380                self.ptr = self.ptr.offset(1);
1381            }
1382
1383            None
1384        }
1385    }
1386}
1387
1388pub struct PoolPairIterator<'a, T, P: PayloadContainer<Element = T>> {
1389    pool: &'a Pool<T, P>,
1390    current: usize,
1391}
1392
1393impl<'a, T, P> Iterator for PoolPairIterator<'a, T, P>
1394where
1395    P: PayloadContainer<Element = T>,
1396{
1397    type Item = (Handle<T>, &'a T);
1398
1399    #[inline]
1400    fn next(&mut self) -> Option<Self::Item> {
1401        loop {
1402            match self.pool.records.get(self.current) {
1403                Some(record) => {
1404                    if let Some(payload) = record.payload.as_ref() {
1405                        let handle = Handle::new(self.current as u32, record.generation);
1406                        self.current += 1;
1407                        return Some((handle, payload));
1408                    }
1409                    self.current += 1;
1410                }
1411                None => return None,
1412            }
1413        }
1414    }
1415}
1416
1417pub struct PoolIteratorMut<'a, T, P>
1418where
1419    P: PayloadContainer<Element = T>,
1420{
1421    ptr: *mut PoolRecord<T, P>,
1422    end: *mut PoolRecord<T, P>,
1423    marker: PhantomData<&'a mut T>,
1424}
1425
1426impl<'a, T, P> Iterator for PoolIteratorMut<'a, T, P>
1427where
1428    P: PayloadContainer<Element = T> + 'static,
1429{
1430    type Item = &'a mut T;
1431
1432    #[inline]
1433    fn next(&mut self) -> Option<Self::Item> {
1434        unsafe {
1435            while self.ptr != self.end {
1436                let current = &mut *self.ptr;
1437                if let Some(payload) = current.payload.as_mut() {
1438                    self.ptr = self.ptr.offset(1);
1439                    return Some(payload);
1440                }
1441                self.ptr = self.ptr.offset(1);
1442            }
1443
1444            None
1445        }
1446    }
1447}
1448
1449pub struct PoolPairIteratorMut<'a, T, P>
1450where
1451    P: PayloadContainer<Element = T>,
1452{
1453    ptr: *mut PoolRecord<T, P>,
1454    end: *mut PoolRecord<T, P>,
1455    marker: PhantomData<&'a mut T>,
1456    current: usize,
1457}
1458
1459impl<'a, T, P> Iterator for PoolPairIteratorMut<'a, T, P>
1460where
1461    P: PayloadContainer<Element = T> + 'static,
1462{
1463    type Item = (Handle<T>, &'a mut T);
1464
1465    #[inline]
1466    fn next(&mut self) -> Option<Self::Item> {
1467        unsafe {
1468            while self.ptr != self.end {
1469                let current = &mut *self.ptr;
1470                if let Some(payload) = current.payload.as_mut() {
1471                    let handle = Handle::new(self.current as u32, current.generation);
1472                    self.ptr = self.ptr.offset(1);
1473                    self.current += 1;
1474                    return Some((handle, payload));
1475                }
1476                self.ptr = self.ptr.offset(1);
1477                self.current += 1;
1478            }
1479
1480            None
1481        }
1482    }
1483}
1484
1485#[cfg(test)]
1486mod test {
1487    use crate::{
1488        pool::{AtomicHandle, Handle, Pool, PoolRecord, INVALID_GENERATION},
1489        visitor::{Visit, Visitor},
1490    };
1491
1492    #[test]
1493    fn pool_sanity_tests() {
1494        let mut pool: Pool<String> = Pool::new();
1495        let foobar_handle = pool.spawn(String::from("Foobar"));
1496        assert_eq!(foobar_handle.index, 0);
1497        assert_ne!(foobar_handle.generation, INVALID_GENERATION);
1498        let foobar_handle_copy = foobar_handle;
1499        assert_eq!(foobar_handle.index, foobar_handle_copy.index);
1500        assert_eq!(foobar_handle.generation, foobar_handle_copy.generation);
1501        let baz_handle = pool.spawn(String::from("Baz"));
1502        assert_eq!(pool.borrow(foobar_handle), "Foobar");
1503        assert_eq!(pool.borrow(baz_handle), "Baz");
1504        pool.free(foobar_handle);
1505        assert!(!pool.is_valid_handle(foobar_handle_copy));
1506        assert!(pool.is_valid_handle(baz_handle));
1507        let at_foobar_index = pool.spawn(String::from("AtFoobarIndex"));
1508        assert_eq!(at_foobar_index.index, 0);
1509        assert_ne!(at_foobar_index.generation, INVALID_GENERATION);
1510        assert_eq!(pool.borrow(at_foobar_index), "AtFoobarIndex");
1511        let bar_handle = pool.spawn_with(|_handle| String::from("Bar"));
1512        assert_ne!(bar_handle.index, 0);
1513        assert_ne!(bar_handle.generation, INVALID_GENERATION);
1514        assert_eq!(pool.borrow(bar_handle), "Bar");
1515    }
1516
1517    #[test]
1518    fn pool_iterator_mut_test() {
1519        let mut pool: Pool<String> = Pool::new();
1520        let foobar = pool.spawn("Foobar".to_string());
1521        let d = pool.spawn("Foo".to_string());
1522        pool.free(d);
1523        let baz = pool.spawn("Baz".to_string());
1524        for s in pool.iter() {
1525            println!("{s}");
1526        }
1527        for s in pool.iter_mut() {
1528            println!("{s}");
1529        }
1530        for s in &pool {
1531            println!("{s}");
1532        }
1533        for s in &mut pool {
1534            println!("{s}");
1535        }
1536        pool.free(foobar);
1537        pool.free(baz);
1538    }
1539
1540    #[test]
1541    fn handle_of() {
1542        #[allow(dead_code)]
1543        struct Value {
1544            data: String,
1545        }
1546
1547        let mut pool = Pool::<Value>::new();
1548        let foobar = pool.spawn(Value {
1549            data: "Foobar".to_string(),
1550        });
1551        let bar = pool.spawn(Value {
1552            data: "Bar".to_string(),
1553        });
1554        let baz = pool.spawn(Value {
1555            data: "Baz".to_string(),
1556        });
1557        assert_eq!(pool.handle_of(pool.borrow(foobar)), foobar);
1558        assert_eq!(pool.handle_of(pool.borrow(bar)), bar);
1559        assert_eq!(pool.handle_of(pool.borrow(baz)), baz);
1560    }
1561
1562    #[derive(Debug, Eq, PartialEq)]
1563    struct Payload;
1564
1565    #[test]
1566    fn pool_test_spawn_at() {
1567        let mut pool = Pool::<Payload>::new();
1568
1569        assert_eq!(pool.spawn_at(2, Payload), Ok(Handle::new(2, 1)));
1570        assert_eq!(pool.spawn_at(2, Payload), Err(Payload));
1571        assert_eq!(pool.records[0].payload.as_ref(), None);
1572        assert_eq!(pool.records[1].payload.as_ref(), None);
1573        assert_ne!(pool.records[2].payload.as_ref(), None);
1574
1575        assert_eq!(pool.spawn_at(2, Payload), Err(Payload));
1576
1577        pool.free(Handle::new(2, 1));
1578
1579        assert_eq!(pool.spawn_at(2, Payload), Ok(Handle::new(2, 2)));
1580
1581        assert_eq!(pool.spawn(Payload), Handle::new(1, 2));
1582        assert_eq!(pool.spawn(Payload), Handle::new(0, 2));
1583    }
1584
1585    #[test]
1586    fn pool_test_try_free() {
1587        let mut pool = Pool::<Payload>::new();
1588
1589        assert_eq!(pool.try_free(Handle::NONE), None);
1590        assert_eq!(pool.free_stack.len(), 0);
1591
1592        let handle = pool.spawn(Payload);
1593        assert_eq!(pool.try_free(handle), Some(Payload));
1594        assert_eq!(pool.free_stack.len(), 1);
1595        assert_eq!(pool.try_free(handle), None);
1596        assert_eq!(pool.free_stack.len(), 1);
1597    }
1598
1599    #[test]
1600    fn visit_for_pool_record() {
1601        let mut p = PoolRecord::<u32>::default();
1602        let mut visitor = Visitor::default();
1603
1604        assert!(p.visit("name", &mut visitor).is_ok());
1605    }
1606
1607    #[test]
1608    fn visit_for_pool() {
1609        let mut p = Pool::<u32>::default();
1610        let mut visitor = Visitor::default();
1611
1612        assert!(p.visit("name", &mut visitor).is_ok());
1613    }
1614
1615    #[test]
1616    fn default_for_pool() {
1617        assert_eq!(Pool::default(), Pool::<u32>::new());
1618    }
1619
1620    #[test]
1621    fn pool_with_capacity() {
1622        let p = Pool::<u32>::with_capacity(1);
1623        assert_eq!(p.records, Vec::with_capacity(1));
1624        assert_eq!(p.free_stack, Vec::new())
1625    }
1626
1627    #[test]
1628    fn pool_try_borrow() {
1629        let mut pool = Pool::<Payload>::new();
1630        let a = pool.spawn(Payload);
1631        let b = Handle::<Payload>::default();
1632
1633        assert_eq!(pool.try_borrow(a), Some(&Payload));
1634        assert_eq!(pool.try_borrow(b), None);
1635    }
1636
1637    #[test]
1638    fn pool_borrow_two_mut() {
1639        let mut pool = Pool::<u32>::new();
1640        let a = pool.spawn(1);
1641        let b = pool.spawn(2);
1642        let (a, b) = pool.borrow_two_mut((a, b));
1643
1644        assert_eq!(a, &mut 1);
1645        assert_eq!(b, &mut 2);
1646    }
1647
1648    #[test]
1649    fn pool_borrow_three_mut() {
1650        let mut pool = Pool::<u32>::new();
1651        let a = pool.spawn(1);
1652        let b = pool.spawn(2);
1653        let c = pool.spawn(3);
1654        let (a, b, c) = pool.borrow_three_mut((a, b, c));
1655
1656        assert_eq!(a, &mut 1);
1657        assert_eq!(b, &mut 2);
1658        assert_eq!(c, &mut 3);
1659    }
1660
1661    #[test]
1662    fn pool_borrow_four_mut() {
1663        let mut pool = Pool::<u32>::new();
1664        let a = pool.spawn(1);
1665        let b = pool.spawn(2);
1666        let c = pool.spawn(3);
1667        let d = pool.spawn(4);
1668        let (a, b, c, d) = pool.borrow_four_mut((a, b, c, d));
1669
1670        assert_eq!(a, &mut 1);
1671        assert_eq!(b, &mut 2);
1672        assert_eq!(c, &mut 3);
1673        assert_eq!(d, &mut 4);
1674    }
1675
1676    #[test]
1677    fn pool_try_borrow_dependant_mut() {
1678        let mut pool = Pool::<u32>::new();
1679        let a = pool.spawn(42);
1680        let b = pool.spawn(5);
1681
1682        assert_eq!(
1683            pool.try_borrow_dependant_mut(a, |_| b),
1684            (Some(&mut 42), Some(&mut 5))
1685        );
1686
1687        assert_eq!(
1688            pool.try_borrow_dependant_mut(a, |_| a),
1689            (Some(&mut 42), None)
1690        );
1691    }
1692
1693    #[test]
1694    fn pool_try_take_reserve() {
1695        let mut pool = Pool::<u32>::new();
1696
1697        let a = Handle::<u32>::default();
1698        assert!(pool.try_take_reserve(a).is_none());
1699
1700        let b = pool.spawn(42);
1701
1702        let (ticket, payload) = pool.try_take_reserve(b).unwrap();
1703        assert_eq!(ticket.index, 0);
1704        assert_eq!(payload, 42);
1705
1706        assert!(pool.try_take_reserve(a).is_none());
1707        assert!(pool.try_take_reserve(b).is_none());
1708
1709        pool.forget_ticket(ticket);
1710    }
1711
1712    #[test]
1713    fn pool_put_back() {
1714        let mut pool = Pool::<u32>::new();
1715        let a = pool.spawn(42);
1716        let (ticket, value) = pool.take_reserve(a);
1717        let b = pool.put_back(ticket, value);
1718
1719        assert_eq!(a, b);
1720    }
1721
1722    #[test]
1723    fn pool_forget_ticket() {
1724        let mut pool = Pool::<u32>::new();
1725        let a = pool.spawn(42);
1726        let (ticket, _) = pool.take_reserve(a);
1727
1728        pool.forget_ticket(ticket);
1729
1730        let b = pool.spawn(42);
1731
1732        assert_eq!(a.index, b.index);
1733        assert_ne!(a.generation, b.generation);
1734    }
1735
1736    #[test]
1737    fn pool_get_capacity() {
1738        let mut pool = Pool::<u32>::new();
1739        let _ = pool.spawn(42);
1740        let _ = pool.spawn(5);
1741
1742        assert_eq!(pool.get_capacity(), 2);
1743    }
1744
1745    #[test]
1746    fn pool_clear() {
1747        let mut pool = Pool::<u32>::new();
1748        let _ = pool.spawn(42);
1749
1750        assert!(!pool.records.is_empty());
1751
1752        pool.clear();
1753
1754        assert!(pool.records.is_empty());
1755        assert!(pool.free_stack.is_empty());
1756    }
1757
1758    #[test]
1759    fn pool_at_mut() {
1760        let mut pool = Pool::<u32>::new();
1761        let _ = pool.spawn(42);
1762
1763        assert_eq!(pool.at_mut(0), Some(&mut 42));
1764        assert_eq!(pool.at_mut(1), None);
1765    }
1766
1767    #[test]
1768    fn pool_at() {
1769        let mut pool = Pool::<u32>::new();
1770        let _ = pool.spawn(42);
1771
1772        assert_eq!(pool.at(0), Some(&42));
1773        assert_eq!(pool.at(1), None);
1774    }
1775
1776    #[test]
1777    fn pool_handle_from_index() {
1778        let mut pool = Pool::<u32>::new();
1779        let a = pool.spawn(42);
1780
1781        assert_eq!(pool.handle_from_index(0), a);
1782        assert_eq!(pool.handle_from_index(1), Handle::NONE);
1783    }
1784
1785    #[test]
1786    fn pool_alive_count() {
1787        let mut pool = Pool::<u32>::new();
1788        let a = pool.spawn(42);
1789        let _ = pool.spawn(5);
1790        let (ticket, _) = pool.take_reserve(a);
1791        pool.forget_ticket(ticket);
1792
1793        assert_eq!(pool.alive_count(), 1);
1794    }
1795
1796    #[test]
1797    fn pool_total_count() {
1798        let mut pool = Pool::<u32>::new();
1799        let a = pool.spawn(42);
1800        let _ = pool.spawn(5);
1801        let (ticket, _) = pool.take_reserve(a);
1802
1803        assert_eq!(pool.total_count(), 2);
1804
1805        pool.forget_ticket(ticket);
1806    }
1807
1808    #[test]
1809    fn pool_replace() {
1810        let mut pool = Pool::<u32>::new();
1811        let a = pool.spawn(42);
1812        let b = Handle::<u32>::new(1, 1);
1813
1814        assert_eq!(pool.replace(a, 5), Some(42));
1815        assert_eq!(pool.replace(b, 5), None);
1816    }
1817
1818    #[test]
1819    fn pool_pair_iter() {
1820        let pool = Pool::<u32>::new();
1821
1822        let iter = pool.pair_iter();
1823
1824        assert_eq!(iter.pool, &pool);
1825        assert_eq!(iter.current, 0);
1826    }
1827
1828    #[test]
1829    fn pool_pair_iter_mut() {
1830        let mut pool = Pool::<u32>::new();
1831        let _ = pool.spawn(42);
1832
1833        let iter = pool.pair_iter_mut();
1834
1835        assert_eq!(iter.current, 0);
1836        assert_eq!(iter.ptr, pool.records.as_mut_ptr());
1837    }
1838
1839    #[test]
1840    fn index_for_pool() {
1841        let mut pool = Pool::<u32>::new();
1842        let a = pool.spawn(42);
1843        let b = pool.spawn(5);
1844
1845        assert_eq!(pool[a], 42);
1846        assert_eq!(pool[b], 5);
1847    }
1848
1849    #[test]
1850    fn index_mut_for_pool() {
1851        let mut pool = Pool::<u32>::new();
1852        let a = pool.spawn(42);
1853        let b = pool.spawn(5);
1854
1855        pool[a] = 15;
1856
1857        assert_eq!(pool[a], 15);
1858        assert_eq!(pool[b], 5);
1859    }
1860
1861    #[test]
1862    fn test_atomic_handle() {
1863        let handle = AtomicHandle::new(123, 321);
1864        assert!(handle.is_some());
1865        assert_eq!(handle.index(), 123);
1866        assert_eq!(handle.generation(), 321);
1867
1868        let handle = AtomicHandle::default();
1869        assert!(handle.is_none());
1870    }
1871
1872    #[test]
1873    fn test_generate_free_handles() {
1874        let mut pool = Pool::<u32>::new();
1875
1876        let _ = pool.spawn(42);
1877        let b = pool.spawn(5);
1878        let _ = pool.spawn(228);
1879
1880        pool.free(b);
1881
1882        let h0 = Handle::new(1, 2);
1883        let h1 = Handle::new(3, 1);
1884        let h2 = Handle::new(4, 1);
1885        let h3 = Handle::new(5, 1);
1886        let h4 = Handle::new(6, 1);
1887
1888        let free_handles = pool.generate_free_handles(5);
1889        assert_eq!(free_handles, [h0, h1, h2, h3, h4]);
1890
1891        // Spawn something on the generated handles.
1892        for (i, handle) in free_handles.into_iter().enumerate() {
1893            let instance_handle = pool.spawn_at_handle(handle, i as u32);
1894            assert_eq!(instance_handle, Ok(handle));
1895        }
1896
1897        assert_eq!(pool[h0], 0);
1898        assert_eq!(pool[h1], 1);
1899        assert_eq!(pool[h2], 2);
1900        assert_eq!(pool[h3], 3);
1901        assert_eq!(pool[h4], 4);
1902    }
1903}