| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- export module Core.Components;
- export import Core.Utility;
- export import Core.New;
- import Core.HashMap;
- import Core.List;
- import Core.Meta;
- export namespace Core {
- using Entity = size_t;
- template<Moveable T>
- class Components final {
- HashMap<Entity, size_t> entityToIndex{};
- List<Entity> indexToEntity{};
- List<T> components{};
- public:
- template<typename R>
- struct Node final {
- Entity entity;
- R& component;
- };
- template<typename C>
- class Iterator final {
- using EntityIterator = decltype(C().indexToEntity.begin());
- using ComponentIterator = decltype(C().components.begin());
- using Component = decltype(*ComponentIterator());
- EntityIterator entityIterator{};
- ComponentIterator componentIterator{};
- public:
- Iterator(EntityIterator e, ComponentIterator c) noexcept :
- entityIterator(e), componentIterator(c) {
- }
- Iterator& operator++() noexcept {
- ++entityIterator;
- ++componentIterator;
- return *this;
- }
- bool operator!=(const Iterator& other) const noexcept {
- return entityIterator != other.entityIterator;
- }
- Node<Component> operator*() const noexcept {
- return {*entityIterator, *componentIterator};
- }
- };
- template<typename C>
- struct IteratorAdapter final {
- C& c;
- Iterator<C> begin() noexcept {
- return Iterator<C>(
- c.indexToEntity.begin(), c.components.begin());
- }
- Iterator<C> end() noexcept {
- return Iterator<C>(c.indexToEntity.end(), c.components.end());
- }
- };
- template<typename... Args>
- bool put(T*& t, Entity e, Args&&... args) noexcept {
- size_t index = components.getLength();
- size_t* indexP = nullptr;
- if(!entityToIndex.tryEmplace(indexP, e, index)) {
- return false;
- }
- indexToEntity.add(e);
- t = &components.put(Core::forward<Args>(args)...);
- return true;
- }
- template<typename... Args>
- bool add(Entity e, Args&&... args) noexcept {
- T* t = nullptr;
- return put(t, e, Core::forward<Args>(args)...);
- }
- bool remove(Entity e) noexcept {
- size_t* indexP = entityToIndex.search(e);
- if(indexP == nullptr) {
- return false;
- }
- size_t lastIndex = components.getLength() - 1;
- size_t index = *indexP;
- entityToIndex.remove(e);
- components.removeBySwap(index);
- if(index == lastIndex) {
- indexToEntity.removeBySwap(index);
- return true;
- }
- Entity other = indexToEntity[lastIndex];
- indexToEntity.removeBySwap(index);
- entityToIndex.add(other, index);
- return true;
- }
- T* search(Entity e) noexcept {
- return const_cast<T*>(
- static_cast<const Components*>(this)->search(e));
- }
- const T* search(Entity e) const noexcept {
- const size_t* index = entityToIndex.search(e);
- if(index == nullptr) {
- return nullptr;
- }
- return &(components[*index]);
- }
- auto begin() noexcept {
- return components.begin();
- }
- auto begin() const noexcept {
- return components.begin();
- }
- auto end() noexcept {
- return components.end();
- }
- auto end() const noexcept {
- return components.end();
- }
- IteratorAdapter<Components> entities() noexcept {
- return {*this};
- }
- IteratorAdapter<const Components> entities() const noexcept {
- return {*this};
- }
- };
- }
|