#ifndef COMPONENTS_H #define COMPONENTS_H #include "data/HashMap.h" #include "utils/Types.h" typedef uint32 Entity; template class Components final { HashMap entityToIndex; List indexToEntity; List components; public: template struct Node { const Entity& entity; R& component; }; template class EntityIterator final { C& components; int index; public: EntityIterator(C& components_, int index_) : components(components_), index(index_) { } EntityIterator& operator++() { index++; return *this; } bool operator!=(const EntityIterator& other) const { return index != other.index; } Node operator*() const { return {components.indexToEntity[index], components.components[index]}; } }; template struct EntityIteratorAdapter { C& components; EntityIterator begin() { return EntityIterator(components, 0); } EntityIterator end() { return EntityIterator(components, components.components.getLength()); } }; template void add(Entity e, Args&&... args) { int index = components.getLength(); if(entityToIndex.tryEmplace(e, index)) { return; } components.add(std::forward(args)...); indexToEntity.add(e); } void remove(Entity e) { int* indexP = entityToIndex.search(e); if(indexP == nullptr) { return; } int lastIndex = components.getLength() - 1; int index = *indexP; entityToIndex.remove(e); components.removeBySwap(index); if(index == lastIndex) { indexToEntity.removeBySwap(index); return; } Entity other = indexToEntity[lastIndex]; indexToEntity.removeBySwap(index); entityToIndex.add(other, index); } T* search(Entity e) { int* index = entityToIndex.search(e); if(index == nullptr) { return nullptr; } return &(components[*index]); } const T* search(Entity e) const { const int* index = entityToIndex.search(e); if(index == nullptr) { return nullptr; } return &(components[*index]); } T* begin() { return components.begin(); } const T* begin() const { return components.begin(); } T* end() { return components.end(); } const T* end() const { return components.end(); } EntityIteratorAdapter entities() { return {*this}; } EntityIteratorAdapter entities() const { return {*this}; } }; #endif