#ifndef COMPONENTS_H #define COMPONENTS_H #include "data/HashMap.h" #include "utils/Types.h" typedef uint32 Entity; template<typename T> class Components final { HashMap<Entity, int> entityToIndex; List<Entity> indexToEntity; List<T> components; public: template<typename R> struct Node { const Entity& entity; R& component; }; template<typename C, typename R> 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<R> operator*() const { return {components.indexToEntity[index], components.components[index]}; } }; template<typename C, typename R> struct EntityIteratorAdapter { C& components; EntityIterator<C, R> begin() { return EntityIterator<C, R>(components, 0); } EntityIterator<C, R> end() { return EntityIterator<C, R>(components, components.components.getLength()); } }; template<typename... Args> void add(Entity e, Args&&... args) { int index = components.getLength(); if(entityToIndex.tryEmplace(e, index)) { return; } components.add(std::forward<Args>(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<Components, T> entities() { return {*this}; } EntityIteratorAdapter<const Components, const T> entities() const { return {*this}; } }; #endif