#ifndef COMPONENT_MANAGER_H #define COMPONENT_MANAGER_H #include #include #include #include #include #include #include #include "core/types.h" class ComponentManager { public: ~ComponentManager() = default; static PtrUnq &GetInstance(); FEntity newEntity() { FEntity entityID = nextEntityID++; activeEntities.insert(entityID); return entityID; } void removeEntity(FEntity entityID) { if (activeEntities.erase(entityID) > 0) { removeAllComponents(entityID); } } template void addComponent(FEntity entityID, const ComponentType component) { auto &componentMap = getComponentMap(); componentMap[entityID] = std::make_shared(std::move(component)); } template PtrShr getComponent(FEntity entityID) { auto &componentMap = getComponentMap(); auto it = componentMap.find(entityID); if (it != componentMap.end()) { return it->second; } return nullptr; } template void removeComponent(FEntity entityID) { auto &componentMap = getComponentMap(); componentMap.erase(entityID); } void removeAllComponents(FEntity entityID) { for (auto &pair : componentPools) { pair.second->remove(entityID); } } template auto begin() { return getComponentMap().begin(); } template auto end() { return getComponentMap().end(); } template TVector> view() { TVector> result; if constexpr (sizeof...(Components) == 0) return result; auto &baseMap = getComponentMap>>(); for (auto &[entityID, baseComp] : baseMap) { if ((getComponent(entityID) && ...)) { result.emplace_back(entityID, getComponent(entityID).get()...); } } return result; } private: ComponentManager() = default; ComponentManager(const ComponentManager &) = delete; ComponentManager &operator=(const ComponentManager &) = delete; struct IComponentPool { virtual ~IComponentPool() = default; virtual void remove(FEntity entityID) = 0; }; static PtrUnq Instance; std::unordered_map> componentPools; std::unordered_set activeEntities; FEntity nextEntityID = 0; template struct ComponentPool : IComponentPool { std::unordered_map> components; void remove(FEntity entityID) override { components.erase(entityID); } }; template std::unordered_map> &getComponentMap() { std::type_index typeIndex(typeid(ComponentType)); if (componentPools.find(typeIndex) == componentPools.end()) { componentPools[typeIndex] = std::make_unique>(); } return static_cast *>( componentPools[typeIndex].get()) ->components; } }; #endif // COMPONENT_MANAGER_H