#pragma once #include #include #include "iPoolable.h" //see below //This class borrows liberally from Robert Nystroms excellent ObjectPool //http://gameprogrammingpatterns.com/object-pool.html template class Pool{ static_assert(std::is_base_of::value, "Type must implement iPoolable!"); mutable iPoolable* _head = nullptr; //linked list of unused objects std::array _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(_head); //get the head of the list _head = nextObject->getNext(); // Update the head of the list nextObject->onTakenFromPool(); //notify the object return nextObject; } template 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 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 ... */ };