#pragma once #include "Types.hpp" #include #include #include class IComponentArray { public: virtual ~IComponentArray() = default; virtual void EntityDestroyed(Entity entity) = 0; }; template class ComponentArray : public IComponentArray { public: void InsertData(Entity entity, T component) { assert(mEntityToIndexMap.find(entity) == mEntityToIndexMap.end() && "Component added to same entity more than once."); // Put new entry at end size_t newIndex = mSize; mEntityToIndexMap[entity] = newIndex; mIndexToEntityMap[newIndex] = entity; mComponentArray[newIndex] = component; ++mSize; } void RemoveData(Entity entity) { assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() && "Removing non-existent component."); // Copy element at end into deleted element's place to maintain density size_t indexOfRemovedEntity = mEntityToIndexMap[entity]; size_t indexOfLastElement = mSize - 1; mComponentArray[indexOfRemovedEntity] = mComponentArray[indexOfLastElement]; // Update map to point to moved spot Entity entityOfLastElement = mIndexToEntityMap[indexOfLastElement]; mEntityToIndexMap[entityOfLastElement] = indexOfRemovedEntity; mIndexToEntityMap[indexOfRemovedEntity] = entityOfLastElement; mEntityToIndexMap.erase(entity); mIndexToEntityMap.erase(indexOfLastElement); --mSize; } T& GetData(Entity entity) { assert(mEntityToIndexMap.find(entity) != mEntityToIndexMap.end() && "Retrieving non-existent component."); return mComponentArray[mEntityToIndexMap[entity]]; } void EntityDestroyed(Entity entity) override { if (mEntityToIndexMap.find(entity) != mEntityToIndexMap.end()) { RemoveData(entity); } } private: std::array mComponentArray{}; std::unordered_map mEntityToIndexMap{}; std::unordered_map mIndexToEntityMap{}; size_t mSize{}; };