ulfben

C++ ObjectPool and interface (v 1.0)

Nov 30th, 2017
411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.80 KB | None | 0 0
  1. #pragma once
  2. #include <cassert>
  3. #include <array>
  4. #include "iPoolable.h" //see below
  5.  
  6. //This class borrows liberally from Robert Nystroms excellent ObjectPool
  7.     //http://gameprogrammingpatterns.com/object-pool.html
  8. template<class T, size_t POOL_SIZE = 32>
  9. class Pool{
  10.     static_assert(std::is_base_of<iPoolable, T>::value, "Type must implement iPoolable!");
  11.     mutable iPoolable* _head = nullptr; //linked list of unused objects
  12.     std::array<T, POOL_SIZE> _objects;
  13. public:
  14.     Pool(){            
  15.         _head = &_objects[0];              
  16.         for(size_t i = 0; i < POOL_SIZE - 1; ++i){ // Each object points to the next.  
  17.             _objects[i].setNext(&_objects[i + 1]);         
  18.         }      
  19.         _objects[POOL_SIZE - 1].setNext(nullptr); // The last one terminates the list.     
  20.     }
  21.     void recycle(T* object) const noexcept {
  22.         assert(object != nullptr);
  23.         object->onReturnToPool(); //notify the object
  24.         object->setNext(_head); //add the object to front of the list
  25.         _head = object;
  26.     }
  27.     T* getNext() const noexcept{
  28.         assert(_head != nullptr); // Make sure the pool isn't exhausted.               
  29.         T* nextObject = static_cast<T*>(_head); //get the head of the list
  30.         _head = nextObject->getNext();  // Update the head of the list 
  31.         nextObject->onTakenFromPool(); //notify the object
  32.         return nextObject;
  33.     }      
  34.     template<typename Function>
  35.     void apply(Function f) {       
  36.         std::for_each(_objects.begin(), _objects.end(), f);    
  37.     }  
  38.     ~Pool(){
  39.         //give objects a chance to clean up. (onReturnToPool must be noexcept!)
  40.         std::for_each(_objects.begin(), _objects.end(), std::mem_fn(&T::onReturnToPool));          
  41.     }
  42.     size_t static constexpr size() noexcept { return POOL_SIZE; }  
  43. }; //end Pool.h
  44.  
  45. //iPoolable.h
  46. #pragma once
  47. class iPoolable{
  48. public:
  49.     virtual iPoolable* getNext() const noexcept = 0;
  50.     virtual void setNext(iPoolable* next) noexcept = 0;
  51.    
  52.     //Optional: release resource handles, stop timers, clean up.
  53.     virtual void onReturnToPool() noexcept {};
  54.    
  55.     //Optional: re-aquire resources, start timers, re-initialize members.
  56.     virtual void onTakenFromPool() noexcept {};
  57.    
  58.     virtual ~iPoolable(){};
  59. };
  60.  
  61. //Poolable.h concrete class
  62. #pragma once
  63. #include "iPoolable.h"
  64. class Poolable : public iPoolable{
  65.     iPoolable* _next = nullptr;
  66. public:
  67.     void setNext(iPoolable* next) noexcept override{
  68.         _next = next;
  69.     }
  70.     iPoolable* getNext() const noexcept override{
  71.         return _next;
  72.     }      
  73.     virtual ~Poolable(){
  74.         _next = nullptr;
  75.     }  
  76. };
  77.  
  78. //Vector2D.h iPoolable implementation
  79. template<class T = float>
  80. class Vector2D : public iPoolable{
  81. public:    
  82.     union{
  83.         struct{
  84.             T x;
  85.             T y;
  86.         }; //struct of 2 float = 8 bytes       
  87.         iPoolable* _next; //pointer = 8 bytes
  88.     }; //union total = 8 bytes
  89.    
  90.     iPoolable* getNext() const noexcept override { return _next; }
  91.     void setNext(iPoolable* next) noexcept override { _next = next; }
  92.  
  93.     /* ... Vector2D interface ... */
  94. };
Add Comment
Please, Sign In to add comment