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::{
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/// 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 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 number, used to keep info about lifetime. The handle is valid
207    // only if record it points to is of the same generation as the pool record.
208    // Notes: Zero is unknown generation used for None handles.
209    generation: u32,
210    // Actual payload.
211    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    /// Tries to put an object in the pool at given position. Returns `Err(payload)` if a corresponding
366    /// entry is occupied.
367    ///
368    /// # Performance
369    ///
370    /// The method has O(n) complexity in worst case, where `n` - amount of free records in the pool.
371    /// In typical uses cases `n` is very low. It should be noted that if a pool is filled entirely
372    /// and you trying to put an object at the end of pool, the method will have O(1) complexity.
373    ///
374    /// # Panics
375    ///
376    /// Panics if the index is occupied or reserved (e.g. by [`take_reserve`]).
377    ///
378    /// [`take_reserve`]: Pool::take_reserve
379    #[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    /// Tries to put an object in the pool at given handle. Returns `Err(payload)` if a corresponding
385    /// entry is occupied.
386    ///
387    /// # Performance
388    ///
389    /// The method has O(n) complexity in worst case, where `n` - amount of free records in the pool.
390    /// In typical uses cases `n` is very low. It should be noted that if a pool is filled entirely
391    /// and you trying to put an object at the end of pool, the method will have O(1) complexity.
392    ///
393    /// # Panics
394    ///
395    /// Panics if the index is occupied or reserved (e.g. by [`take_reserve`]).
396    ///
397    /// [`take_reserve`]: Pool::take_reserve
398    #[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                // Spawn missing records to fill gaps.
436                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    /// Construct a value with the handle it would be given.
465    /// Note: Handle is _not_ valid until function has finished executing.
466    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            // No free records, create new one
492            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    /// Asynchronously construct a value with the handle it would be given.
516    /// Note: Handle is _not_ valid until function has finished executing.
517    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            // No free records, create new one
547            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    /// Generates a set of handles that could be used to spawn a set of objects. This method does not
570    /// modify the pool and the generated handles could be used together with [`Self::spawn_at_handle`]
571    /// method.
572    #[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    /// Borrows shared reference to an object by its handle.
592    ///
593    /// # Panics
594    ///
595    /// Panics if handle is out of bounds or generation of handle does not match with
596    /// generation of pool record at handle index (in other words it means that object
597    /// at handle's index is different than the object was there before).
598    #[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    /// Borrows mutable reference to an object by its handle.
624    ///
625    /// # Panics
626    ///
627    /// Panics if handle is out of bounds or generation of handle does not match with
628    /// generation of pool record at handle index (in other words it means that object
629    /// at handle's index is different than the object was there before).
630    ///
631    /// # Example
632    ///
633    /// ```
634    /// use fyrox_core::pool::Pool;
635    /// let mut pool = Pool::<u32>::new();
636    /// let a = pool.spawn(1);
637    /// let a = pool.borrow_mut(a);
638    /// *a = 11;
639    /// ```
640    #[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    /// Borrows shared reference to an object by its handle.
662    ///
663    /// Returns None if handle is out of bounds or generation of handle does not match with
664    /// generation of pool record at handle index (in other words it means that object
665    /// at handle's index is different than the object was there before).
666    #[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    /// Borrows mutable reference to an object by its handle.
679    ///
680    /// Returns None if handle is out of bounds or generation of handle does not match with
681    /// generation of pool record at handle index (in other words it means that object
682    /// at handle's index is different than the object was there before).
683    #[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    /// Borrows mutable references of objects at the same time. This method will succeed only
696    /// if handles are unique (not equal). Borrowing multiple mutable references at the same
697    /// time is useful in case if you need to mutate some objects at the same time.
698    ///
699    /// # Panics
700    ///
701    /// See [`borrow_mut`](Self::borrow_mut).
702    ///
703    /// # Example
704    ///
705    /// ```
706    /// use fyrox_core::pool::Pool;
707    /// let mut pool = Pool::<u32>::new();
708    /// let a = pool.spawn(1);
709    /// let b = pool.spawn(2);
710    /// let (a, b) = pool.borrow_two_mut((a, b));
711    /// *a = 11;
712    /// *b = 22;
713    /// ```
714    #[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        // Prevent giving two mutable references to same record.
718        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    /// Borrows mutable references of objects at the same time. This method will succeed only
726    /// if handles are unique (not equal). Borrowing multiple mutable references at the same
727    /// time is useful in case if you need to mutate some objects at the same time.
728    ///
729    /// # Panics
730    ///
731    /// See [`borrow_mut`](Self::borrow_mut).
732    ///
733    /// # Example
734    ///
735    /// ```
736    /// use fyrox_core::pool::Pool;
737    /// let mut pool = Pool::<u32>::new();
738    /// let a = pool.spawn(1);
739    /// let b = pool.spawn(2);
740    /// let c = pool.spawn(3);
741    /// let (a, b, c) = pool.borrow_three_mut((a, b, c));
742    /// *a = 11;
743    /// *b = 22;
744    /// *c = 33;
745    /// ```
746    #[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        // Prevent giving mutable references to same record.
753        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    /// Borrows mutable references of objects at the same time. This method will succeed only
767    /// if handles are unique (not equal). Borrowing multiple mutable references at the same
768    /// time is useful in case if you need to mutate some objects at the same time.
769    ///
770    /// # Panics
771    ///
772    /// See [`borrow_mut`](Self::borrow_mut).
773    ///
774    /// # Example
775    ///
776    /// ```
777    /// use fyrox_core::pool::Pool;
778    /// let mut pool = Pool::<u32>::new();
779    /// let a = pool.spawn(1);
780    /// let b = pool.spawn(2);
781    /// let c = pool.spawn(3);
782    /// let d = pool.spawn(4);
783    /// let (a, b, c, d) = pool.borrow_four_mut((a, b, c, d));
784    /// *a = 11;
785    /// *b = 22;
786    /// *c = 33;
787    /// *d = 44;
788    /// ```
789    #[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        // Prevent giving mutable references to same record.
796        // This is kinda clunky since const generics are not stabilized yet.
797        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    /// Tries to borrow two objects when a handle to the second object stored in the first object.
815    #[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    /// Moves object out of the pool using the given handle. All handles to the object will become invalid.
837    ///
838    /// # Panics
839    ///
840    /// Panics if the given handle is invalid.
841    #[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                // Remember this index as free
847                self.free_stack.push(handle.index);
848                // Return current payload.
849                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    /// Tries to move object out of the pool using the given handle. Returns None if given handle
866    /// is invalid. After object is moved out if the pool, all handles to the object will become
867    /// invalid.
868    #[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    /// Moves an object out of the pool using the given handle with a promise that the object will be returned back.
886    /// Returns pair (ticket, value). The ticket must be used to put the value back!
887    ///
888    /// # Motivation
889    ///
890    /// This method is useful when you need to take temporary ownership of an object, do something
891    /// with it and then put it back while preserving all handles to it and being able to put new objects into
892    /// the pool without overriding the payload at its handle.
893    ///
894    /// # Notes
895    ///
896    /// All handles to the object will be temporarily invalid until the object is returned to the pool! The pool record will
897    /// be reserved for a further [`put_back`] call, which means if you lose the ticket you will have an empty
898    /// "unusable" pool record forever.
899    ///
900    /// # Panics
901    ///
902    /// Panics if the given handle is invalid.
903    ///
904    /// [`put_back`]: Pool::put_back
905    #[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    /// Does the same as [`take_reserve`] but returns an option, instead of panicking.
930    ///
931    /// [`take_reserve`]: Pool::take_reserve
932    #[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    /// Returns the value back into the pool using the given ticket. See [`take_reserve`] for more
954    /// information.
955    ///
956    /// [`take_reserve`]: Pool::take_reserve
957    #[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    /// Forgets that value at ticket was reserved and makes it usable again.
970    /// Useful when you don't need to put value back by ticket, but just make
971    /// pool record usable again.
972    #[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    /// Returns total capacity of pool. Capacity has nothing about real amount of objects in pool!
979    #[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    /// Destroys all objects in pool. All handles to objects will become invalid.
986    ///
987    /// # Remarks
988    ///
989    /// Use this method cautiously if objects in pool have cross "references" (handles)
990    /// to each other. This method will make all produced handles invalid and any further
991    /// calls for [`borrow`](Self::borrow) or [`borrow_mut`](Self::borrow_mut) will raise panic.
992    #[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    /// Returns the exact number of "alive" objects in the pool.
1023    ///
1024    /// Records that have been reserved (e.g. by [`take_reserve`]) are *not* counted.
1025    ///
1026    /// It iterates through the entire pool to count the live objects so the complexity is `O(n)`.
1027    ///
1028    /// See also [`total_count`].
1029    ///
1030    /// # Example
1031    ///
1032    /// ```
1033    /// use fyrox_core::pool::Pool;
1034    /// let mut pool = Pool::<u32>::new();
1035    /// pool.spawn(123);
1036    /// pool.spawn(321);
1037    /// assert_eq!(pool.alive_count(), 2);
1038    /// ```
1039    ///
1040    /// [`take_reserve`]: Pool::take_reserve
1041    /// [`total_count`]: Pool::total_count
1042    #[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    /// Returns the number of allocated objects in the pool.
1050    ///
1051    /// It also counts records that have been reserved (e.g. by [`take_reserve`]).
1052    ///
1053    /// This method is `O(1)`.
1054    ///
1055    /// See also [`alive_count`].
1056    ///
1057    /// [`take_reserve`]: Pool::take_reserve
1058    /// [`alive_count`]: Pool::alive_count
1059    #[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    /// Returns a reference to the first element in the pool (if any).
1082    pub fn first_ref(&self) -> Option<&T> {
1083        self.iter().next()
1084    }
1085
1086    /// Returns a reference to the first element in the pool (if any).
1087    pub fn first_mut(&mut self) -> Option<&mut T> {
1088        self.iter_mut().next()
1089    }
1090
1091    /// Checks if given handle "points" to some object.
1092    ///
1093    /// # Example
1094    ///
1095    /// ```
1096    /// use fyrox_core::pool::Pool;
1097    /// let mut pool = Pool::<u32>::new();
1098    /// let handle = pool.spawn(123);
1099    /// assert_eq!(pool.is_valid_handle(handle), true)
1100    /// ```
1101    #[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    /// Creates new pool iterator that iterates over filled records in pool.
1111    ///
1112    /// # Example
1113    ///
1114    /// ```
1115    /// use fyrox_core::pool::Pool;
1116    /// let mut pool = Pool::<u32>::new();
1117    /// pool.spawn(123);
1118    /// pool.spawn(321);
1119    /// let mut iter = pool.iter();
1120    /// assert_eq!(*iter.next().unwrap(), 123);
1121    /// assert_eq!(*iter.next().unwrap(), 321);
1122    /// ```
1123    #[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    /// Creates new pair iterator that iterates over filled records using pair (handle, payload)
1136    /// Can be useful when there is a need to iterate over pool records and know a handle of
1137    /// that record.
1138    #[inline]
1139    pub fn pair_iter(&self) -> PoolPairIterator<T, P> {
1140        PoolPairIterator {
1141            pool: self,
1142            current: 0,
1143        }
1144    }
1145
1146    /// Creates new pool iterator that iterates over filled records in pool allowing
1147    /// to modify record payload.
1148    ///
1149    /// # Example
1150    ///
1151    /// ```
1152    /// use fyrox_core::pool::Pool;
1153    /// let mut pool = Pool::<u32>::new();
1154    /// pool.spawn(123);
1155    /// pool.spawn(321);
1156    /// let mut iter = pool.iter_mut();
1157    /// assert_eq!(*iter.next().unwrap(), 123);
1158    /// assert_eq!(*iter.next().unwrap(), 321);
1159    /// ```
1160    #[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    /// Creates new pair iterator that iterates over filled records using pair (handle, payload)
1173    /// Can be useful when there is a need to iterate over pool records and know a handle of
1174    /// that record.
1175    #[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    /// Retains pool records selected by `pred`. Useful when you need to remove all pool records
1188    /// by some criteria.
1189    #[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(); // and Drop
1208            }
1209        }
1210    }
1211
1212    /// Begins multi-borrow that allows you to borrow as many (`N`) **unique** references to the pool
1213    /// elements as you need. See [`MultiBorrowContext::try_get`] for more info.
1214    #[inline]
1215    pub fn begin_multi_borrow(&mut self) -> MultiBorrowContext<T, P> {
1216        MultiBorrowContext::new(self)
1217    }
1218
1219    /// Removes all elements from the pool.
1220    #[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    /// Tries to mutably borrow an object and fetch its component of specified type.
1258    #[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    /// Tries to mutably borrow an object and fetch its component of specified type.
1269    #[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        // Spawn something on the generated handles.
1885        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}