Components.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #ifndef COMPONENTS_H
  2. #define COMPONENTS_H
  3. #include "data/HashMap.h"
  4. #include "utils/Types.h"
  5. typedef uint32 Entity;
  6. template<typename T>
  7. class Components final {
  8. HashMap<Entity, int> entityToIndex;
  9. List<Entity> indexToEntity;
  10. List<T> components;
  11. public:
  12. template<typename R>
  13. struct Node {
  14. const Entity& entity;
  15. R& component;
  16. };
  17. template<typename C, typename R>
  18. class EntityIterator final {
  19. C& components;
  20. int index;
  21. public:
  22. EntityIterator(C& components_, int index_)
  23. : components(components_), index(index_) {
  24. }
  25. EntityIterator& operator++() {
  26. index++;
  27. return *this;
  28. }
  29. bool operator!=(const EntityIterator& other) const {
  30. return index != other.index;
  31. }
  32. Node<R> operator*() const {
  33. return {components.indexToEntity[index],
  34. components.components[index]};
  35. }
  36. };
  37. template<typename C, typename R>
  38. struct EntityIteratorAdapter {
  39. C& components;
  40. EntityIterator<C, R> begin() {
  41. return EntityIterator<C, R>(components, 0);
  42. }
  43. EntityIterator<C, R> end() {
  44. return EntityIterator<C, R>(components,
  45. components.components.getLength());
  46. }
  47. };
  48. template<typename... Args>
  49. void add(Entity e, Args&&... args) {
  50. int index = components.getLength();
  51. if(entityToIndex.tryEmplace(e, index)) {
  52. return;
  53. }
  54. components.add(std::forward<Args>(args)...);
  55. indexToEntity.add(e);
  56. }
  57. void remove(Entity e) {
  58. int* indexP = entityToIndex.search(e);
  59. if(indexP == nullptr) {
  60. return;
  61. }
  62. int lastIndex = components.getLength() - 1;
  63. int index = *indexP;
  64. entityToIndex.remove(e);
  65. components.removeBySwap(index);
  66. if(index == lastIndex) {
  67. indexToEntity.removeBySwap(index);
  68. return;
  69. }
  70. Entity other = indexToEntity[lastIndex];
  71. indexToEntity.removeBySwap(index);
  72. entityToIndex.add(other, index);
  73. }
  74. T* search(Entity e) {
  75. int* index = entityToIndex.search(e);
  76. if(index == nullptr) {
  77. return nullptr;
  78. }
  79. return &(components[*index]);
  80. }
  81. const T* search(Entity e) const {
  82. const int* index = entityToIndex.search(e);
  83. if(index == nullptr) {
  84. return nullptr;
  85. }
  86. return &(components[*index]);
  87. }
  88. T* begin() {
  89. return components.begin();
  90. }
  91. const T* begin() const {
  92. return components.begin();
  93. }
  94. T* end() {
  95. return components.end();
  96. }
  97. const T* end() const {
  98. return components.end();
  99. }
  100. EntityIteratorAdapter<Components, T> entities() {
  101. return {*this};
  102. }
  103. EntityIteratorAdapter<const Components, const T> entities() const {
  104. return {*this};
  105. }
  106. };
  107. #endif