#pragma once
#include <cassert>
#include <array>
#include "iPoolable.h" //see below
//This class borrows liberally from Robert Nystroms excellent ObjectPool
//http://gameprogrammingpatterns.com/object-pool.html
template<class T, size_t POOL_SIZE = 32>
class Pool{
static_assert(std::is_base_of<iPoolable, T>::value, "Type must implement iPoolable!");
mutable iPoolable* _head = nullptr; //linked list of unused objects
std::array<T, POOL_SIZE> _objects;
public:
Pool(){
_head = &_objects[0];
for(size_t i = 0; i < POOL_SIZE - 1; ++i){ // Each object points to the next.
_objects[i].setNext(&_objects[i + 1]);
}
_objects[POOL_SIZE - 1].setNext(nullptr); // The last one terminates the list.
}
void recycle(T* object) const noexcept {
assert(object != nullptr);
object->onReturnToPool(); //notify the object
object->setNext(_head); //add the object to front of the list
_head = object;
}
T* getNext() const noexcept{
assert(_head != nullptr); // Make sure the pool isn't exhausted.
T* nextObject = static_cast<T*>(_head); //get the head of the list
_head = nextObject->getNext(); // Update the head of the list
nextObject->onTakenFromPool(); //notify the object
return nextObject;
}
template<typename Function>
void apply(Function f) {
std::for_each(_objects.begin(), _objects.end(), f);
}
~Pool(){
//give objects a chance to clean up. (onReturnToPool must be noexcept!)
std::for_each(_objects.begin(), _objects.end(), std::mem_fn(&T::onReturnToPool));
}
size_t static constexpr size() noexcept { return POOL_SIZE; }
}; //end Pool.h
//iPoolable.h
#pragma once
class iPoolable{
public:
virtual iPoolable* getNext() const noexcept = 0;
virtual void setNext(iPoolable* next) noexcept = 0;
//Optional: release resource handles, stop timers, clean up.
virtual void onReturnToPool() noexcept {};
//Optional: re-aquire resources, start timers, re-initialize members.
virtual void onTakenFromPool() noexcept {};
virtual ~iPoolable(){};
};
//Poolable.h concrete class
#pragma once
#include "iPoolable.h"
class Poolable : public iPoolable{
iPoolable* _next = nullptr;
public:
void setNext(iPoolable* next) noexcept override{
_next = next;
}
iPoolable* getNext() const noexcept override{
return _next;
}
virtual ~Poolable(){
_next = nullptr;
}
};
//Vector2D.h iPoolable implementation
template<class T = float>
class Vector2D : public iPoolable{
public:
union{
struct{
T x;
T y;
}; //struct of 2 float = 8 bytes
iPoolable* _next; //pointer = 8 bytes
}; //union total = 8 bytes
iPoolable* getNext() const noexcept override { return _next; }
void setNext(iPoolable* next) noexcept override { _next = next; }
/* ... Vector2D interface ... */
};
Comments
0 B
|0 👍
/0 👎
0 B
|0 👍
/0 👎