143 lines
4.0 KiB
C++
143 lines
4.0 KiB
C++
#ifndef ENTITY_ADMIN_H
|
|
#define ENTITY_ADMIN_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <QPoint>
|
|
#include <QSize>
|
|
#include <QVector2D>
|
|
|
|
#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 <typename... Ts, typename Func>
|
|
void forEach(Func&& f);
|
|
|
|
template <typename... Ts, typename Func>
|
|
void forEach(Func&& f) const;
|
|
|
|
template <typename... Ts>
|
|
bool hasAll(entt::entity entity);
|
|
|
|
template <typename T>
|
|
T& get(entt::entity entity);
|
|
|
|
template <typename T>
|
|
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 <typename T, typename... Args>
|
|
void addComponent(entt::entity entity, Args&&... args);
|
|
|
|
template <typename T>
|
|
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,
|
|
int level, const std::string& schematicId, bool isEnemy);
|
|
|
|
entt::entity spawnStation(QPoint anchor, QSize footprint,
|
|
const std::vector<QPoint>& 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 <typename T, typename... Args>
|
|
void add(entt::entity entity, Args&&... args);
|
|
|
|
entt::registry m_registry;
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Template implementations
|
|
// ---------------------------------------------------------------------------
|
|
|
|
template <typename... Ts, typename Func>
|
|
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<Ts...>())
|
|
{
|
|
f(entity, m_registry.get<Ts>(entity)...);
|
|
}
|
|
}
|
|
|
|
template <typename... Ts, typename Func>
|
|
void EntityAdmin::forEach(Func&& f) const
|
|
{
|
|
entt::registry& reg = const_cast<entt::registry&>(m_registry);
|
|
for (entt::entity entity : reg.view<Ts...>())
|
|
{
|
|
f(entity, reg.get<Ts>(entity)...);
|
|
}
|
|
}
|
|
|
|
template <typename... Ts>
|
|
bool EntityAdmin::hasAll(entt::entity entity)
|
|
{
|
|
return m_registry.all_of<Ts...>(entity);
|
|
}
|
|
|
|
template <typename T>
|
|
T& EntityAdmin::get(entt::entity entity)
|
|
{
|
|
return m_registry.get<T>(entity);
|
|
}
|
|
|
|
template <typename T>
|
|
const T& EntityAdmin::get(entt::entity entity) const
|
|
{
|
|
return m_registry.get<T>(entity);
|
|
}
|
|
|
|
template <typename T, typename... Args>
|
|
void EntityAdmin::addComponent(entt::entity entity, Args&&... args)
|
|
{
|
|
m_registry.emplace<T>(entity, std::forward<Args>(args)...);
|
|
}
|
|
|
|
template <typename T>
|
|
void EntityAdmin::removeComponent(entt::entity entity)
|
|
{
|
|
m_registry.remove<T>(entity);
|
|
}
|
|
|
|
template <typename T, typename... Args>
|
|
void EntityAdmin::add(entt::entity entity, Args&&... args)
|
|
{
|
|
m_registry.emplace<T>(entity, std::forward<Args>(args)...);
|
|
}
|
|
|
|
#endif // ENTITY_ADMIN_H
|