Pool.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * 2D Game Engine
  3. * Pool.h:
  4. * Based on pikuma.com 2D game engine in C++ and Lua course
  5. * Copyright (c) 2021 986-Studio. All rights reserved.
  6. *
  7. * Created by Manoël Trapier on 11/02/2021.
  8. */
  9. #ifndef GAMEENGINE_POOL_H
  10. #define GAMEENGINE_POOL_H
  11. #include <vector>
  12. class IPool
  13. {
  14. public:
  15. virtual ~IPool() = default;
  16. virtual void removeEntityFromPool(uint32_t entityId) = 0;
  17. };
  18. template <typename T> class Pool:public IPool
  19. {
  20. private:
  21. std::vector<T> data;
  22. public:
  23. Pool(int size = 100) { this->resize(size); }
  24. virtual ~Pool() = default;
  25. bool isEmpty() const { return this->data.empty(); }
  26. uint32_t getSize() { return this->data.size(); }
  27. void resize(uint32_t size) { this->data.resize(size); }
  28. void clear() { this->data.clear(); }
  29. //void add(T object) { this->data.push_back(object); }
  30. void set(uint32_t index, T object) { this->data[index] = object; }
  31. T& get(uint32_t index) { return this->data[index]; }
  32. void remove(uint32_t index) { /* Just ignore */ }
  33. T& operator[](uint32_t index) { return this->data[index]; }
  34. void removeEntityFromPool(uint32_t entityId) { /* nothing to be done */ }
  35. };
  36. template <typename T> class PackedPool:public IPool
  37. {
  38. private:
  39. std::vector<T> data;
  40. uint32_t size;
  41. /* map of Entity id to Pool index */
  42. std::unordered_map<uint32_t, uint32_t> entityIdToIndex;
  43. /* map of Pool index to Entity id */
  44. std::unordered_map<uint32_t, uint32_t> indexToEntityId;
  45. public:
  46. PackedPool(uint32_t capacity = 100)
  47. {
  48. this->size = 0;
  49. this->data.resize(capacity);
  50. };
  51. virtual ~PackedPool() = default;
  52. bool isEmpty() const { return this->size == 0; }
  53. uint32_t getSize() { return this->size; }
  54. void resize(uint32_t size) { /* Nothing to be done here */ }
  55. void clear()
  56. {
  57. this->data.clear();
  58. this->indexToEntityId.clear();
  59. this->entityIdToIndex.clear();
  60. this->size = 0;
  61. }
  62. void set(uint32_t entityId, T object)
  63. {
  64. if (this->entityIdToIndex.find(entityId) != entityIdToIndex.end())
  65. {
  66. uint32_t index = this->entityIdToIndex[entityId];
  67. data[index] = object;
  68. }
  69. else
  70. {
  71. uint32_t index = size;
  72. this->entityIdToIndex.emplace(entityId, index);
  73. this->indexToEntityId.emplace(index, entityId);
  74. if (this->data.size() <= index)
  75. {
  76. this->data.resize(this->size * 2);
  77. }
  78. this->data[index] = object;
  79. this->size ++;
  80. }
  81. }
  82. void remove(uint32_t entityId)
  83. {
  84. uint32_t indexOfRemoved = this->entityIdToIndex[entityId];
  85. uint32_t indexOfLast = this->size - 1;
  86. uint32_t entityIdOfLastElement = this->indexToEntityId[indexOfLast];
  87. this->data[indexOfRemoved] = this->data[indexOfLast];
  88. this->entityIdToIndex[entityIdOfLastElement] = indexOfRemoved;
  89. this->indexToEntityId[indexOfRemoved] = entityIdOfLastElement;
  90. this->entityIdToIndex.erase(entityId);
  91. this->indexToEntityId.erase(indexOfLast);
  92. this->size --;
  93. }
  94. void removeEntityFromPool(uint32_t entityId)
  95. {
  96. if (this->entityIdToIndex.find(entityId) != this->entityIdToIndex.end())
  97. {
  98. this->remove(entityId);
  99. }
  100. }
  101. T& get(uint32_t entityId)
  102. {
  103. uint32_t indexOfEntity = this->entityIdToIndex[entityId];
  104. return this->data[indexOfEntity];
  105. }
  106. T& operator[](uint32_t index)
  107. {
  108. return this->get(index);
  109. }
  110. };
  111. template <typename T> class MyPackedPool:public IPool
  112. {
  113. private:
  114. std::vector<T> data;
  115. uint32_t size;
  116. /* map of Entity id to Pool index */
  117. std::vector<uint32_t> entityIdToIndex;
  118. /* map of Pool index to Entity id */
  119. std::vector<uint32_t> indexToEntityId;
  120. public:
  121. MyPackedPool(uint32_t capacity = 100)
  122. {
  123. this->size = 0;
  124. this->data.resize(capacity);
  125. this->entityIdToIndex.resize(capacity);
  126. this->indexToEntityId.resize(capacity);
  127. };
  128. virtual ~MyPackedPool() = default;
  129. bool isEmpty() const { return this->size == 0; }
  130. uint32_t getSize() { return this->size; }
  131. void resize(uint32_t size) { /* Nothing to be done here */ }
  132. void clear()
  133. {
  134. this->data.clear();
  135. this->indexToEntityId.clear();
  136. this->entityIdToIndex.clear();
  137. this->size = 0;
  138. }
  139. void set(uint32_t entityId, T object)
  140. {
  141. uint32_t index = this->size;
  142. if (this->data.size() <= index)
  143. {
  144. this->data.resize(this->size * 2);
  145. }
  146. if (this->entityIdToIndex.size() <= entityId)
  147. {
  148. this->entityIdToIndex.resize(entityId + 1);
  149. }
  150. if (this->indexToEntityId.size() <= this->size)
  151. {
  152. this->indexToEntityId.resize(this->size + 1);
  153. }
  154. this->entityIdToIndex[entityId] = index;
  155. this->indexToEntityId[index] = entityId;
  156. this->data[index] = object;
  157. this->size ++;
  158. }
  159. void remove(uint32_t entityId)
  160. {
  161. uint32_t indexOfRemoved = this->entityIdToIndex[entityId];
  162. uint32_t indexOfLast = this->size - 1;
  163. uint32_t entityIdOfLastElement = this->indexToEntityId[indexOfLast];
  164. this->data[indexOfRemoved] = this->data[indexOfLast];
  165. this->entityIdToIndex[entityIdOfLastElement] = indexOfRemoved;
  166. this->indexToEntityId[indexOfRemoved] = entityIdOfLastElement;
  167. this->size --;
  168. }
  169. void removeEntityFromPool(uint32_t entityId)
  170. {
  171. }
  172. T& get(uint32_t entityId)
  173. {
  174. uint32_t indexOfEntity = this->entityIdToIndex[entityId];
  175. return this->data[indexOfEntity];
  176. }
  177. T& operator[](uint32_t index)
  178. {
  179. return this->get(index);
  180. }
  181. };
  182. #define PoolToUse PackedPool
  183. #endif /* GAMEENGINE_POOL_H */