Components.cppm 3.9 KB

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