123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- #ifndef CORE_COMPONENTS_HPP
- #define CORE_COMPONENTS_HPP
- #include "data/HashMap.hpp"
- namespace Core {
- using Entity = int;
- template<typename T>
- class Components final {
- HashMap<Entity, int> entityToIndex{};
- List<Entity> indexToEntity{};
- List<T> components{};
- public:
- template<typename R>
- struct Node final {
- 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 final {
- 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>
- check_return Error put(T*& t, Entity ent, Args&&... args) {
- int index = components.getLength();
- int* indexP = nullptr;
- CORE_RETURN_ERROR(entityToIndex.tryEmplace(indexP, ent, index));
- Error e = Error::NONE;
- if(checkError(e, indexToEntity.add(ent))) {
- (void)entityToIndex.remove(ent);
- return e;
- }
- if(checkError(e, components.put(t, Core::forward<Args>(args)...))) {
- (void)entityToIndex.remove(ent);
- (void)indexToEntity.removeLast();
- }
- return e;
- }
- template<typename... Args>
- check_return Error add(Entity e, Args&&... args) {
- T* t = nullptr;
- return put(t, e, Core::forward<Args>(args)...);
- }
- check_return Error remove(Entity ent) {
- int* indexP = entityToIndex.search(ent);
- if(indexP == nullptr) {
- return Error::NOT_FOUND;
- }
- int lastIndex = components.getLength() - 1;
- int index = *indexP;
- CORE_RETURN_ERROR(entityToIndex.remove(ent));
- CORE_RETURN_ERROR(components.removeBySwap(index));
- if(index == lastIndex) {
- return indexToEntity.removeBySwap(index);
- }
- Entity other = indexToEntity[lastIndex];
- CORE_RETURN_ERROR(indexToEntity.removeBySwap(index));
- return 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]);
- }
- auto begin() {
- return components.begin();
- }
- auto begin() const {
- return components.begin();
- }
- auto end() {
- return components.end();
- }
- auto end() const {
- return components.end();
- }
- EntityIteratorAdapter<Components, T> entities() {
- return {*this};
- }
- EntityIteratorAdapter<const Components, const T> entities() const {
- return {*this};
- }
- };
- }
- #endif
|