#ifndef ENTITY_ADMIN_H #define ENTITY_ADMIN_H #include #include #include #include #include #include "Tick.h" #include "entt/entity/registry.hpp" class EntityAdmin { public: EntityAdmin() = default; EntityAdmin(const EntityAdmin&) = delete; EntityAdmin& operator=(const EntityAdmin&) = delete; // -- Queries / iteration ------------------------------------------------ template void forEach(Func&& f); template void forEach(Func&& f) const; template bool hasAll(entt::entity entity); template T& get(entt::entity entity); template const T& get(entt::entity entity) const; bool isValid(entt::entity entity) const; void destroy(entt::entity entity); void clear(); // -- Public component attachment ---------------------------------------- // Used by systems (e.g. ShipSystem) to attach optional components after // a factory method has created the base entity. template void addComponent(entt::entity entity, Args&&... args); template void removeComponent(entt::entity entity); // -- Factory methods ---------------------------------------------------- entt::entity spawnShip(QVector2D position, float hp, float maxHp, float maxSpeed_tpt, float mainAcceleration_tptt, float maneuveringAcceleration_tptt, float maxAngularAcceleration_rptt, float maxRotationSpeed_rpt, float sensorRange_tiles, const std::string& schematicId, bool isEnemy); entt::entity spawnStation(QPoint anchor, QSize footprint, const std::vector& bodyCells, float hp, float maxHp, bool isEnemy); entt::entity spawnScrap(QVector2D position, int amount, Tick despawnAt); entt::entity spawnHqProxy(QVector2D position, float hp, float maxHp); // Creates a bare entity for module child entities (weapons, salvage, repair). // Caller is responsible for attaching all required components. entt::entity createModuleEntity(); private: entt::entity createEntity(); template void add(entt::entity entity, Args&&... args); entt::registry m_registry; }; // --------------------------------------------------------------------------- // Template implementations // --------------------------------------------------------------------------- template void EntityAdmin::forEach(Func&& f) { // Avoid view.each() — MSVC 2017 ICEs on the extended_storage_iterator it instantiates. for (entt::entity entity : m_registry.view()) { f(entity, m_registry.get(entity)...); } } template void EntityAdmin::forEach(Func&& f) const { entt::registry& reg = const_cast(m_registry); for (entt::entity entity : reg.view()) { f(entity, reg.get(entity)...); } } template bool EntityAdmin::hasAll(entt::entity entity) { return m_registry.all_of(entity); } template T& EntityAdmin::get(entt::entity entity) { return m_registry.get(entity); } template const T& EntityAdmin::get(entt::entity entity) const { return m_registry.get(entity); } template void EntityAdmin::addComponent(entt::entity entity, Args&&... args) { m_registry.emplace(entity, std::forward(args)...); } template void EntityAdmin::removeComponent(entt::entity entity) { m_registry.remove(entity); } template void EntityAdmin::add(entt::entity entity, Args&&... args) { m_registry.emplace(entity, std::forward(args)...); } #endif // ENTITY_ADMIN_H