Components.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #ifndef CORE_COMPONENTS_HPP
  2. #define CORE_COMPONENTS_HPP
  3. #include "core/data/HashMap.hpp"
  4. namespace Core {
  5. using Entity = int;
  6. template<typename T>
  7. class Components final {
  8. HashMap<Entity, i64> entityToIndex{};
  9. List<Entity> indexToEntity{};
  10. List<T> components{};
  11. public:
  12. template<typename R>
  13. struct Node final {
  14. const Entity& entity;
  15. R& component;
  16. };
  17. template<typename C, typename R>
  18. class EntityIterator final {
  19. C& components;
  20. i64 index;
  21. public:
  22. EntityIterator(C& components_, i64 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 final {
  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. check_return Error put(T*& t, Entity ent, Args&&... args) {
  50. i64 index = components.getLength();
  51. i64* indexP = nullptr;
  52. CORE_RETURN_ERROR(entityToIndex.tryEmplace(indexP, ent, index));
  53. Error e = Error::NONE;
  54. if(checkError(e, indexToEntity.add(ent))) {
  55. (void)entityToIndex.remove(ent);
  56. return e;
  57. }
  58. if(checkError(e, components.put(t, Core::forward<Args>(args)...))) {
  59. (void)entityToIndex.remove(ent);
  60. (void)indexToEntity.removeLast();
  61. }
  62. return e;
  63. }
  64. template<typename... Args>
  65. check_return Error add(Entity e, Args&&... args) {
  66. T* t = nullptr;
  67. return put(t, e, Core::forward<Args>(args)...);
  68. }
  69. check_return Error remove(Entity ent) {
  70. i64* indexP = entityToIndex.search(ent);
  71. if(indexP == nullptr) {
  72. return Error::NOT_FOUND;
  73. }
  74. i64 lastIndex = components.getLength() - 1;
  75. i64 index = *indexP;
  76. CORE_RETURN_ERROR(entityToIndex.remove(ent));
  77. CORE_RETURN_ERROR(components.removeBySwap(index));
  78. if(index == lastIndex) {
  79. return indexToEntity.removeBySwap(index);
  80. }
  81. Entity other = indexToEntity[lastIndex];
  82. CORE_RETURN_ERROR(indexToEntity.removeBySwap(index));
  83. return entityToIndex.add(other, index);
  84. }
  85. T* search(Entity e) {
  86. i64* index = entityToIndex.search(e);
  87. if(index == nullptr) {
  88. return nullptr;
  89. }
  90. return &(components[*index]);
  91. }
  92. const T* search(Entity e) const {
  93. const i64* index = entityToIndex.search(e);
  94. if(index == nullptr) {
  95. return nullptr;
  96. }
  97. return &(components[*index]);
  98. }
  99. auto begin() {
  100. return components.begin();
  101. }
  102. auto begin() const {
  103. return components.begin();
  104. }
  105. auto end() {
  106. return components.end();
  107. }
  108. auto end() const {
  109. return components.end();
  110. }
  111. EntityIteratorAdapter<Components, T> entities() {
  112. return {*this};
  113. }
  114. EntityIteratorAdapter<const Components, const T> entities() const {
  115. return {*this};
  116. }
  117. };
  118. }
  119. #endif