Components.cppm 4.0 KB

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