world.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #pragma once
  2. #include "entity.h"
  3. #include "system.h"
  4. #include <memory>
  5. #include <mutex>
  6. #include <typeindex>
  7. #include <unordered_map>
  8. #include <unordered_set>
  9. #include <vector>
  10. namespace Engine::Core {
  11. class World {
  12. public:
  13. World();
  14. ~World();
  15. World(const World &) = delete;
  16. World(World &&) = delete;
  17. auto operator=(const World &) -> World & = delete;
  18. auto operator=(World &&) -> World & = delete;
  19. auto create_entity() -> Entity *;
  20. auto create_entity_with_id(EntityID entity_id) -> Entity *;
  21. void destroy_entity(EntityID entity_id);
  22. auto get_entity(EntityID entity_id) -> Entity *;
  23. void clear();
  24. void add_system(std::unique_ptr<System> system);
  25. void update(float delta_time);
  26. auto systems() -> std::vector<std::unique_ptr<System>> & { return m_systems; }
  27. template <typename T> auto get_system() -> T * {
  28. for (auto &system : m_systems) {
  29. if (auto *ptr = dynamic_cast<T *>(system.get())) {
  30. return ptr;
  31. }
  32. }
  33. return nullptr;
  34. }
  35. template <typename T> auto get_entities_with() -> std::vector<Entity *> {
  36. const std::lock_guard<std::recursive_mutex> lock(m_entity_mutex);
  37. std::type_index const type_idx = std::type_index(typeid(T));
  38. auto it = m_component_index.find(type_idx);
  39. if (it == m_component_index.end()) {
  40. return {};
  41. }
  42. std::vector<Entity *> result;
  43. result.reserve(it->second.size());
  44. for (EntityID entity_id : it->second) {
  45. auto entity_it = m_entities.find(entity_id);
  46. if (entity_it != m_entities.end()) {
  47. result.push_back(entity_it->second.get());
  48. }
  49. }
  50. return result;
  51. }
  52. auto get_units_owned_by(int owner_id) const -> std::vector<Entity *>;
  53. auto get_units_not_owned_by(int owner_id) const -> std::vector<Entity *>;
  54. auto get_allied_units(int owner_id) const -> std::vector<Entity *>;
  55. auto get_enemy_units(int owner_id) const -> std::vector<Entity *>;
  56. static auto count_troops_for_player(int owner_id) -> int;
  57. auto get_entities() const
  58. -> const std::unordered_map<EntityID, std::unique_ptr<Entity>> & {
  59. return m_entities;
  60. }
  61. auto get_next_entity_id() const -> EntityID;
  62. void set_next_entity_id(EntityID next_id);
  63. auto get_entity_mutex() -> std::recursive_mutex & { return m_entity_mutex; }
  64. private:
  65. void on_component_changed(EntityID entity_id, std::type_index component_type,
  66. bool added);
  67. void setup_entity_callback(Entity *entity);
  68. EntityID m_next_entity_id = 1;
  69. std::unordered_map<EntityID, std::unique_ptr<Entity>> m_entities;
  70. std::vector<std::unique_ptr<System>> m_systems;
  71. mutable std::recursive_mutex m_entity_mutex;
  72. std::unordered_map<std::type_index, std::unordered_set<EntityID>>
  73. m_component_index;
  74. };
  75. } // namespace Engine::Core