#pragma once #include #include #include #include #include #include class Component; class Entity; using ComponentID = std::size_t; inline ComponentID getComponentTypeID() { static ComponentID lastID = 0; return lastID++; } template inline ComponentID getComponentTypeID() noexcept { static ComponentID typeID = getComponentTypeID(); return typeID; } constexpr std::size_t maxComponents = 32; using ComponentBitSet = std::bitset; using ComponentArray = std::array; class Component { public: Entity* entity; virtual void init() {} virtual void update() {} virtual void draw() {} virtual ~Component() {} }; class Entity { public: void update() { for (auto& c : components) c->update(); } void draw() { for (auto& c : components) c->draw(); } bool isActive() const { return this->active; } void destroy() { this->active = false; } template bool hasComponent() const { return componentBitSet[getComponentTypeID()]; } template T& addComponent(TArgs&&...mArgs) { T* c(new T(std::forward(mArgs)...)); c->entity = this; std::unique_ptr uPtr{ c }; this->components.emplace_back(std::move(uPtr)); componentArray[getComponentTypeID()] = c; componentBitSet[getComponentTypeID()] = true; c->init(); return *c; }; template T& getComponent() const { auto ptr(componentArray[getComponentTypeID()]); return *static_cast(ptr); } private: bool active = true; std::vector> components; ComponentArray componentArray; ComponentBitSet componentBitSet; }; class Manager { public: void update() { for (auto& e : entities) e->update(); } void draw() { for (auto& e : entities) e->draw(); } void refresh() { entities.erase(std::remove_if(std::begin(entities), std::end(entities), [](const std::unique_ptr& mEntity) { return !mEntity->isActive(); }), std::end(entities)); } Entity& addEntity() { Entity* e = new Entity(); std::unique_ptr uPtr{ e }; entities.emplace_back(std::move(uPtr)); return *e; } private: std::vector> entities; };