PGE API 0.4
PR00F's Game Engine full documentation
|
PR00F's Game Engine object pool for permanently allocating fixed number of game objects. More...
PR00F's Game Engine object pool for permanently allocating fixed number of game objects.
The aim of this class is to have a fixed number of objects being kept in contiguous memory area, and to be able to distinguish between them as they are free for use or busy (being used).
This way we just flag the preallocated objects, instead of actually creating or deleting them in memory which would be otherwise performance-expensive operation, especially when we are talking about resource-heavy objects such as PureObject3D or even higher-level game instances.
Thus, I expect this pool to be used for storing objects created and deleted with high frequency, such as bullets fired from weapons, particles, etc.
Since these virtual "create" and "delete" operations are expected to happen multiple times within 1 frame, I want them to have O(1) complexity.
Also, since they are in contiguous memory area, and usually higher-level logic iterates over them from begin to end, it is more cache-friendly than iterating over occasionally allocated objects that are placed here and there in memory.
The only downsides of having such preallocated object pool is that:
However, the advantages regarding performance are outweighing these small disadvantages.
Basically this class is based on this "Object Pool Pattern": https://gameprogrammingpatterns.com/object-pool.html .
Also, for iterators, I'm using Vincenzo Barbato's blIteratorAPI: https://github.com/navyenzo/blIteratorAPI . Note that you might need to define the _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING macro for the MSVC preprocessor, it comes from the way of how blIteratorAPI is implemented. It is safe to silence this warning.
Reminder: this class is NOT a memory pool neither a memory manager. This is an object pool with fixed number of objects, and after construction, no more memory allocation happens! For memory pool management, I would rather use an already existing solution from these:
Ideas on improving:
Definition at line 209 of file PgeObjectPool.h.
#include <PgeObjectPool.h>
Public Member Functions | |
CConsole & | getConsole () const |
PgeObjectPool () | |
This constructor should be used when parameters for initializing the pool is NOT available. | |
template<typename... Args> | |
PgeObjectPool (const std::string &poolName, const size_t &capacity, Args &&... pooledObjArgs) | |
Not only the memory pool is allocated for all pooled objects, but their non-default constructor is also called with the provided pooled object parameters, or their default constructor if that is available. | |
~PgeObjectPool () | |
PgeObjectPool (const PgeObjectPool &)=delete | |
PgeObjectPool & | operator= (const PgeObjectPool &)=delete |
PgeObjectPool (PgeObjectPool &&)=delete | |
PgeObjectPool && | operator= (PgeObjectPool &&)=delete |
void | deallocate () |
Frees up the allocated contiguous memory pool, capacity becomes zero, name becomes "unnamed pool". | |
const size_t & | count () const |
const size_t & | size () const |
Conventionally std containers have a size() member function returning the number of elements, NOT the capacity. | |
const size_t & | capacity () const |
size_t | capacityBytes () const |
bool | empty () const |
const std::string & | name () const |
template<typename... Args> | |
T * | create (Args &&... pooledObjArgs) |
Finds a free (usable) object in the pool, sets it flag as used and returns it. | |
void | remove (PgePooledObject &obj) |
Resets the free (usable) flag of this object, "returns it" into the pool so it can be reused again. | |
blIteratorAPI::blRawArrayWrapper< T >::iterator | erase (typename blIteratorAPI::blRawArrayWrapper< T >::iterator itPos) |
Resets the free (usable) flag of the pooled object pointed by the given iterator, "returns" the object into the pool so it can be reused again. | |
template<typename... Args> | |
void | reserve (const std::string &poolName, const size_t &capacity, Args &&... pooledObjArgs) |
Not only the memory pool is allocated for all pooled objects, but their non-default constructor is also called with the provided pooled object parameters, or their default constructor if that is available. | |
void | clear () |
Resets the free (usable) flag of all objects in the pool, "returns them" into the pool so they can be reused again. | |
T * | elems () |
const T * | elems () const |
blIteratorAPI::blRawArrayWrapper< T > | rawArrayWrapper () |
blIteratorAPI::blRawArrayWrapper< T >::iterator | begin () |
Gives iterator for beginning iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::iterator | end () |
Gives iterator for ending iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::const_iterator | cbegin () const |
Gives const iterator for beginning iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::const_iterator | cend () const |
Gives const iterator for ending iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::reverse_iterator | rbegin () |
Gives iterator for beginning reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::reverse_iterator | rend () |
Gives iterator for ending reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::const_reverse_iterator | crbegin () const |
Gives const iterator for beginning reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
blIteratorAPI::blRawArrayWrapper< T >::const_reverse_iterator | crend () const |
Gives const iterator for ending reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns. | |
![]() | |
PgeObjectPoolBase ()=default | |
virtual | ~PgeObjectPoolBase ()=default |
PgeObjectPoolBase (const PgeObjectPoolBase &)=default | |
PgeObjectPoolBase & | operator= (const PgeObjectPoolBase &)=default |
PgeObjectPoolBase (PgeObjectPoolBase &&)=default | |
PgeObjectPoolBase & | operator= (PgeObjectPoolBase &&)=default |
Static Public Member Functions | |
static const char * | getLoggerModuleName () |
Private Attributes | |
std::string | m_name {} |
size_t | m_count {0} |
size_t | m_capacity {0} |
T * | m_pool {nullptr} |
PgePooledObject * | m_firstAvailable {nullptr} |
blIteratorAPI::blRawArrayWrapper< T > | m_rawArrayWrapper |
|
inline |
This constructor should be used when parameters for initializing the pool is NOT available.
In this case, no memory is allocated, size remains 0, and later the pool needs to be initialized using reserve(). The name of the pool will be "unnamed pool".
Definition at line 236 of file PgeObjectPool.h.
|
inline |
Not only the memory pool is allocated for all pooled objects, but their non-default constructor is also called with the provided pooled object parameters, or their default constructor if that is available.
It is decided by the user if the pooled object can be properly initialized when the pool is allocated, or further initialization is needed later. In the latter case, either a default constructor must be available or default parameters should be passed to this constructor to be forwarded to the pooled object's non-default constructor to bring the pooled objects to a default state, and later the pooled objects can be properly initialized using the pool's create() function which can forward arbitrary parameters to the pooled object's init() function.
poolName | Name of this pool, for informative purpose. |
capacity | Number of pooled objects to be stored in this pool. Can be changed later with reserve() only if 0 is passed here. |
pooledObjArgs | Arguments to be forwarded to the constructor of the pooled objects. |
Definition at line 260 of file PgeObjectPool.h.
|
inline |
Definition at line 266 of file PgeObjectPool.h.
|
delete |
|
delete |
|
inline |
Gives iterator for beginning iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 556 of file PgeObjectPool.h.
|
inline |
Definition at line 327 of file PgeObjectPool.h.
|
inline |
Definition at line 335 of file PgeObjectPool.h.
|
inline |
Gives const iterator for beginning iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 578 of file PgeObjectPool.h.
|
inline |
Gives const iterator for ending iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 589 of file PgeObjectPool.h.
|
inline |
Resets the free (usable) flag of all objects in the pool, "returns them" into the pool so they can be reused again.
Complexity is O(n) (linear).
Definition at line 516 of file PgeObjectPool.h.
|
inline |
Definition at line 308 of file PgeObjectPool.h.
|
inline |
Gives const iterator for beginning reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 622 of file PgeObjectPool.h.
|
inline |
Finds a free (usable) object in the pool, sets it flag as used and returns it.
It also forwards arbitrary parameters to the pooled object's init() function. Complexity is O(1) (constant). Note: the returned object stays in the pool but marked as used, and the user can mark it as free by calling remove().
Definition at line 365 of file PgeObjectPool.h.
|
inline |
Gives const iterator for ending reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 633 of file PgeObjectPool.h.
|
inline |
Frees up the allocated contiguous memory pool, capacity becomes zero, name becomes "unnamed pool".
Capacity can be changed again to non-zero value using reserve().
Definition at line 280 of file PgeObjectPool.h.
|
inline |
Definition at line 528 of file PgeObjectPool.h.
|
inline |
Definition at line 537 of file PgeObjectPool.h.
|
inline |
Definition at line 343 of file PgeObjectPool.h.
|
inline |
Gives iterator for ending iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 567 of file PgeObjectPool.h.
|
inline |
Resets the free (usable) flag of the pooled object pointed by the given iterator, "returns" the object into the pool so it can be reused again.
Equivalent to: remove(*itPos). This function is for convenience, to mimic the erase() function of std containers, so it is easier to migrate code using an std::container to use PgeObjectPool. Complexity is O(1) (constant).
Note: the erased object stays in the pool's contiguous memory, just gets marked as free, so a future call to create() might return it again to the user.
itPos | Iterator to the element to be "erased". |
Definition at line 431 of file PgeObjectPool.h.
|
inline |
Definition at line 226 of file PgeObjectPool.h.
|
inlinestatic |
Definition at line 219 of file PgeObjectPool.h.
|
inline |
Definition at line 351 of file PgeObjectPool.h.
|
delete |
|
delete |
|
inline |
Definition at line 545 of file PgeObjectPool.h.
|
inline |
Gives iterator for beginning reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 600 of file PgeObjectPool.h.
|
inlinevirtual |
Resets the free (usable) flag of this object, "returns it" into the pool so it can be reused again.
Complexity is O(1) (constant).
Note: the removed object stays in the pool's contiguous memory, just gets marked as free, so a future call to create() might return it again to the user.
obj | The pooled object to be returned to the pool as free-to-use object. |
Implements PgeObjectPoolBase.
Definition at line 395 of file PgeObjectPool.h.
|
inline |
Gives iterator for ending reverse iterating over the contiguous memory area of pooled objects, the same area that elems() returns.
Note that iterating over this area iterating over both used and non-used pooled objects, thus you should filter for used pooled objects manually.
Definition at line 611 of file PgeObjectPool.h.
|
inline |
Not only the memory pool is allocated for all pooled objects, but their non-default constructor is also called with the provided pooled object parameters, or their default constructor if that is available.
Currently works only for zero-capacity pools.
Cannot be used to reduce the capacity of the container. To reduce the capacity of a non-zero capacity container to non-zero, or to increase the capacity, first use deallocate() to completely free up the used memory area, and then call reserve().
It is decided by the user if the pooled object can be properly initialized when the pool is allocated, or further initialization is needed later. In the latter case, either a default constructor must be available or default parameters should be passed to this function to be forwarded to the pooled object's non-default constructor to bring the pooled objects to a default state, and later the pooled objects can be properly initialized using the pool's create() function which can forward arbitrary parameters to the pooled objects init() function.
poolName | Name of this pool, for informative purpose. |
capacity | Number of pooled objects to be stored in this pool. Can be changed later only with reserve() if 0 is passed here. |
pooledObjArgs | Arguments to be forwarded to the constructor of the pooled objects. |
Definition at line 466 of file PgeObjectPool.h.
|
inline |
Conventionally std containers have a size() member function returning the number of elements, NOT the capacity.
Thus, size() is equivalent to count().
Definition at line 319 of file PgeObjectPool.h.
|
private |
Definition at line 640 of file PgeObjectPool.h.
|
private |
Definition at line 640 of file PgeObjectPool.h.
|
private |
Definition at line 642 of file PgeObjectPool.h.
|
private |
Definition at line 639 of file PgeObjectPool.h.
|
private |
Definition at line 641 of file PgeObjectPool.h.
|
private |
Definition at line 643 of file PgeObjectPool.h.