world.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include "world.h"
  2. #include "../systems/owner_registry.h"
  3. #include "../systems/troop_count_registry.h"
  4. #include "component.h"
  5. #include "core/entity.h"
  6. #include "core/system.h"
  7. #include <algorithm>
  8. #include <memory>
  9. #include <mutex>
  10. #include <utility>
  11. #include <vector>
  12. namespace Engine::Core {
  13. World::World() = default;
  14. World::~World() = default;
  15. void World::on_component_changed(EntityID entity_id,
  16. std::type_index component_type, bool added) {
  17. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  18. if (added) {
  19. m_component_index[component_type].insert(entity_id);
  20. } else {
  21. auto it = m_component_index.find(component_type);
  22. if (it != m_component_index.end()) {
  23. it->second.erase(entity_id);
  24. if (it->second.empty()) {
  25. m_component_index.erase(it);
  26. }
  27. }
  28. }
  29. }
  30. void World::setup_entity_callback(Entity *entity) {
  31. entity->set_component_change_callback(
  32. [this](EntityID entity_id, std::type_index component_type, bool added) {
  33. this->on_component_changed(entity_id, component_type, added);
  34. });
  35. }
  36. auto World::create_entity() -> Entity * {
  37. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  38. EntityID const id = m_next_entity_id++;
  39. auto entity = std::make_unique<Entity>(id);
  40. auto *ptr = entity.get();
  41. setup_entity_callback(ptr);
  42. m_entities[id] = std::move(entity);
  43. return ptr;
  44. }
  45. auto World::create_entity_with_id(EntityID entity_id) -> Entity * {
  46. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  47. if (entity_id == NULL_ENTITY) {
  48. return nullptr;
  49. }
  50. auto entity = std::make_unique<Entity>(entity_id);
  51. auto *ptr = entity.get();
  52. setup_entity_callback(ptr);
  53. m_entities[entity_id] = std::move(entity);
  54. if (entity_id >= m_next_entity_id) {
  55. m_next_entity_id = entity_id + 1;
  56. }
  57. return ptr;
  58. }
  59. void World::destroy_entity(EntityID entity_id) {
  60. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  61. auto it = m_entities.find(entity_id);
  62. for (auto &[type, entity_set] : m_component_index) {
  63. entity_set.erase(entity_id);
  64. }
  65. if (it != m_entities.end()) {
  66. m_entities.erase(it);
  67. } else {
  68. m_entities.erase(entity_id);
  69. }
  70. }
  71. void World::clear() {
  72. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  73. m_entities.clear();
  74. m_component_index.clear();
  75. m_next_entity_id = 1;
  76. }
  77. auto World::get_entity(EntityID entity_id) -> Entity * {
  78. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  79. auto it = m_entities.find(entity_id);
  80. return it != m_entities.end() ? it->second.get() : nullptr;
  81. }
  82. void World::add_system(std::unique_ptr<System> system) {
  83. m_systems.push_back(std::move(system));
  84. }
  85. void World::update(float delta_time) {
  86. for (auto &system : m_systems) {
  87. system->update(this, delta_time);
  88. }
  89. }
  90. auto World::get_units_owned_by(int owner_id) const -> std::vector<Entity *> {
  91. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  92. std::vector<Entity *> result;
  93. result.reserve(m_entities.size());
  94. for (const auto &[entity_id, entity] : m_entities) {
  95. auto *unit = entity->get_component<UnitComponent>();
  96. if (unit == nullptr) {
  97. continue;
  98. }
  99. if (unit->owner_id == owner_id) {
  100. result.push_back(entity.get());
  101. }
  102. }
  103. return result;
  104. }
  105. auto World::get_units_not_owned_by(int owner_id) const
  106. -> std::vector<Entity *> {
  107. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  108. std::vector<Entity *> result;
  109. result.reserve(m_entities.size());
  110. for (const auto &[entity_id, entity] : m_entities) {
  111. auto *unit = entity->get_component<UnitComponent>();
  112. if (unit == nullptr) {
  113. continue;
  114. }
  115. if (unit->owner_id != owner_id) {
  116. result.push_back(entity.get());
  117. }
  118. }
  119. return result;
  120. }
  121. auto World::get_allied_units(int owner_id) const -> std::vector<Entity *> {
  122. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  123. std::vector<Entity *> result;
  124. result.reserve(m_entities.size());
  125. auto &owner_registry = Game::Systems::OwnerRegistry::instance();
  126. for (const auto &[entity_id, entity] : m_entities) {
  127. auto *unit = entity->get_component<UnitComponent>();
  128. if (unit == nullptr) {
  129. continue;
  130. }
  131. if (unit->owner_id == owner_id ||
  132. owner_registry.are_allies(owner_id, unit->owner_id)) {
  133. result.push_back(entity.get());
  134. }
  135. }
  136. return result;
  137. }
  138. auto World::get_enemy_units(int owner_id) const -> std::vector<Entity *> {
  139. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  140. std::vector<Entity *> result;
  141. result.reserve(m_entities.size());
  142. auto &owner_registry = Game::Systems::OwnerRegistry::instance();
  143. for (const auto &[entity_id, entity] : m_entities) {
  144. auto *unit = entity->get_component<UnitComponent>();
  145. if (unit == nullptr) {
  146. continue;
  147. }
  148. if (owner_registry.are_enemies(owner_id, unit->owner_id)) {
  149. result.push_back(entity.get());
  150. }
  151. }
  152. return result;
  153. }
  154. auto World::count_troops_for_player(int owner_id) -> int {
  155. return Game::Systems::TroopCountRegistry::instance().get_troop_count(
  156. owner_id);
  157. }
  158. auto World::get_next_entity_id() const -> EntityID {
  159. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  160. return m_next_entity_id;
  161. }
  162. void World::set_next_entity_id(EntityID next_id) {
  163. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  164. m_next_entity_id = std::max(next_id, m_next_entity_id);
  165. }
  166. } // namespace Engine::Core