Components.h 2.9 KB

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