Components.cppm 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. module;
  2. export module Core.Components;
  3. import Core.HashMap;
  4. import Core.List;
  5. import Core.Meta;
  6. export namespace Core {
  7. using Entity = size_t;
  8. template<typename T>
  9. class Components final {
  10. HashMap<Entity, size_t> entityToIndex{};
  11. List<Entity> indexToEntity{};
  12. List<T> components{};
  13. public:
  14. template<typename R>
  15. struct Node final {
  16. Entity entity;
  17. R& component;
  18. };
  19. template<typename C>
  20. class Iterator final {
  21. using EntityIterator = decltype(C().indexToEntity.begin());
  22. using ComponentIterator = decltype(C().components.begin());
  23. using Component = decltype(*ComponentIterator());
  24. EntityIterator entityIterator{};
  25. ComponentIterator componentIterator{};
  26. public:
  27. Iterator(EntityIterator e, ComponentIterator c) :
  28. entityIterator(e), componentIterator(c) {
  29. }
  30. Iterator& operator++() {
  31. ++entityIterator;
  32. ++componentIterator;
  33. return *this;
  34. }
  35. bool operator!=(const Iterator& other) const {
  36. return entityIterator != other.entityIterator;
  37. }
  38. Node<Component> operator*() const {
  39. return {*entityIterator, *componentIterator};
  40. }
  41. };
  42. template<typename C>
  43. struct IteratorAdapter final {
  44. C& c;
  45. Iterator<C> begin() {
  46. return Iterator<C>(
  47. c.indexToEntity.begin(), c.components.begin());
  48. }
  49. Iterator<C> end() {
  50. return Iterator<C>(c.indexToEntity.end(), c.components.end());
  51. }
  52. };
  53. template<typename... Args>
  54. bool put(T*& t, Entity e, Args&&... args) {
  55. size_t index = components.getLength();
  56. size_t* indexP = nullptr;
  57. if(!entityToIndex.tryEmplace(indexP, e, index)) {
  58. return false;
  59. }
  60. indexToEntity.add(e);
  61. t = &components.put(Core::forward<Args>(args)...);
  62. return true;
  63. }
  64. template<typename... Args>
  65. bool add(Entity e, Args&&... args) {
  66. T* t = nullptr;
  67. return put(t, e, Core::forward<Args>(args)...);
  68. }
  69. bool remove(Entity e) {
  70. size_t* indexP = entityToIndex.search(e);
  71. if(indexP == nullptr) {
  72. return false;
  73. }
  74. size_t lastIndex = components.getLength() - 1;
  75. size_t index = *indexP;
  76. entityToIndex.remove(e);
  77. components.removeBySwap(index);
  78. if(index == lastIndex) {
  79. indexToEntity.removeBySwap(index);
  80. return true;
  81. }
  82. Entity other = indexToEntity[lastIndex];
  83. indexToEntity.removeBySwap(index);
  84. entityToIndex.add(other, index);
  85. return true;
  86. }
  87. T* search(Entity e) {
  88. return const_cast<T*>(
  89. static_cast<const Components*>(this)->search(e));
  90. }
  91. const T* search(Entity e) const {
  92. const size_t* index = entityToIndex.search(e);
  93. if(index == nullptr) {
  94. return nullptr;
  95. }
  96. return &(components[*index]);
  97. }
  98. auto begin() {
  99. return components.begin();
  100. }
  101. auto begin() const {
  102. return components.begin();
  103. }
  104. auto end() {
  105. return components.end();
  106. }
  107. auto end() const {
  108. return components.end();
  109. }
  110. IteratorAdapter<Components> entities() {
  111. return {*this};
  112. }
  113. IteratorAdapter<const Components> entities() const {
  114. return {*this};
  115. }
  116. };
  117. }