| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- #ifndef ENTT_REGISTRY_HPP
- #define ENTT_REGISTRY_HPP
- #include <cassert>
- #include <memory>
- #include <vector>
- #include <utility>
- #include <cstddef>
- #include <iterator>
- #include <algorithm>
- #include "component_pool.hpp"
- namespace entt {
- template<typename...>
- class View;
- template<template<typename...> class Pool, typename Entity, typename... Components, typename Type, typename... Types>
- class View<Pool<Entity, Components...>, Type, Types...> final {
- using pool_type = Pool<Entity, Components...>;
- using entity_type = typename pool_type::entity_type;
- class ViewIterator {
- bool valid() const noexcept {
- using accumulator_type = bool[];
- bool check = pool.template has<Type>(entities[pos-1]);
- accumulator_type accumulator = { true, (check = check && pool.template has<Types>(entities[pos-1]))... };
- (void)accumulator;
- return check;
- }
- public:
- using value_type = entity_type;
- using difference_type = std::ptrdiff_t;
- using reference = entity_type &;
- using pointer = entity_type *;
- using iterator_category = std::input_iterator_tag;
- ViewIterator(pool_type &pool, const entity_type *entities, typename pool_type::size_type pos) noexcept
- : pool{pool}, entities{entities}, pos{pos}
- {
- if(this->pos) { while(!valid() && --this->pos); }
- }
- ViewIterator & operator++() noexcept {
- if(pos) { while(--pos && !valid()); }
- return *this;
- }
- ViewIterator operator++(int) noexcept {
- ViewIterator orig = *this;
- return this->operator++(), orig;
- }
- bool operator==(const ViewIterator &other) const noexcept {
- return other.entities == entities && other.pos == pos;
- }
- bool operator!=(const ViewIterator &other) const noexcept {
- return !(*this == other);
- }
- value_type operator*() const noexcept {
- return *(entities+pos-1);
- }
- private:
- pool_type &pool;
- const entity_type *entities;
- std::uint32_t pos;
- };
- template<typename Comp>
- void prefer() noexcept {
- auto sz = pool.template size<Comp>();
- if(sz < size) {
- entities = pool.template entities<Comp>();
- size = sz;
- }
- }
- public:
- using iterator_type = ViewIterator;
- using size_type = typename pool_type::size_type;
- explicit View(pool_type &pool) noexcept
- : entities{pool.template entities<Type>()},
- size{pool.template size<Type>()},
- pool{pool}
- {
- using accumulator_type = int[];
- accumulator_type accumulator = { 0, (prefer<Types>(), 0)... };
- (void)accumulator;
- }
- iterator_type begin() const noexcept {
- return ViewIterator{pool, entities, size};
- }
- iterator_type end() const noexcept {
- return ViewIterator{pool, entities, 0};
- }
- void reset() noexcept {
- using accumulator_type = int[];
- entities = pool.template entities<Type>();
- size = pool.template size<Type>();
- accumulator_type accumulator = { 0, (prefer<Types>(), 0)... };
- (void)accumulator;
- }
- private:
- const entity_type *entities;
- size_type size;
- pool_type &pool;
- };
- template<template<typename...> class Pool, typename Entity, typename... Components, typename Type>
- class View<Pool<Entity, Components...>, Type> final {
- using pool_type = Pool<Entity, Components...>;
- using entity_type = typename pool_type::entity_type;
- struct ViewIterator {
- using value_type = entity_type;
- using difference_type = std::ptrdiff_t;
- using reference = entity_type &;
- using pointer = entity_type *;
- using iterator_category = std::input_iterator_tag;
- ViewIterator(const entity_type *entities, typename pool_type::size_type pos) noexcept
- : entities{entities}, pos{pos}
- {}
- ViewIterator & operator++() noexcept {
- --pos;
- return *this;
- }
- ViewIterator operator++(int) noexcept {
- ViewIterator orig = *this;
- return this->operator++(), orig;
- }
- bool operator==(const ViewIterator &other) const noexcept {
- return other.entities == entities && other.pos == pos;
- }
- bool operator!=(const ViewIterator &other) const noexcept {
- return !(*this == other);
- }
- value_type operator*() const noexcept {
- return *(entities+pos-1);
- }
- private:
- const entity_type *entities;
- typename pool_type::size_type pos;
- };
- public:
- using iterator_type = ViewIterator;
- using size_type = typename pool_type::size_type;
- explicit View(pool_type &pool) noexcept: pool{pool} {}
- iterator_type begin() const noexcept {
- return ViewIterator{pool.template entities<Type>(), pool.template size<Type>()};
- }
- iterator_type end() const noexcept {
- return ViewIterator{pool.template entities<Type>(), 0};
- }
- size_type size() const noexcept {
- return pool.template size<Type>();
- }
- private:
- pool_type &pool;
- };
- template<typename>
- class Registry;
- template<template<typename...> class Pool, typename Entity, typename... Components>
- class Registry<Pool<Entity, Components...>> final {
- using pool_type = Pool<Entity, Components...>;
- public:
- static_assert(sizeof...(Components) > 1, "!");
- using entity_type = typename pool_type::entity_type;
- using size_type = std::size_t;
- private:
- template<typename Comp>
- void destroy(entity_type entity) {
- if(pool.template has<Comp>(entity)) {
- pool.template destroy<Comp>(entity);
- }
- }
- template<typename Comp>
- void clone(entity_type from, entity_type to) {
- if(pool.template has<Comp>(from)) {
- pool.template construct<Comp>(to, pool.template get<Comp>(from));
- }
- }
- template<typename Comp>
- void sync(entity_type from, entity_type to) {
- bool src = pool.template has<Comp>(from);
- bool dst = pool.template has<Comp>(to);
- if(src && dst) {
- copy<Comp>(from, to);
- } else if(src) {
- clone<Comp>(from, to);
- } else if(dst) {
- destroy(to);
- }
- }
- public:
- template<typename... Comp>
- using view_type = View<pool_type, Comp...>;
- template<typename... Args>
- Registry(Args&&... args)
- : count{0}, pool{std::forward<Args>(args)...}
- {}
- Registry(const Registry &) = delete;
- Registry(Registry &&) = delete;
- Registry & operator=(const Registry &) = delete;
- Registry & operator=(Registry &&) = delete;
- size_type size() const noexcept {
- return count - available.size();
- }
- size_type capacity() const noexcept {
- return count;
- }
- template<typename Comp>
- bool empty() const noexcept {
- return pool.template empty<Comp>();
- }
- bool empty() const noexcept {
- return available.size() == count;
- }
- template<typename... Comp>
- entity_type create() noexcept {
- using accumulator_type = int[];
- auto entity = create();
- accumulator_type accumulator = { 0, (assign<Comp>(entity), 0)... };
- (void)accumulator;
- return entity;
- }
- entity_type create() noexcept {
- entity_type entity;
- if(available.empty()) {
- entity = count++;
- } else {
- entity = available.back();
- available.pop_back();
- }
- return entity;
- }
- void destroy(entity_type entity) {
- using accumulator_type = int[];
- accumulator_type accumulator = { 0, (destroy<Components>(entity), 0)... };
- (void)accumulator;
- available.push_back(entity);
- }
- template<typename Comp, typename... Args>
- Comp & assign(entity_type entity, Args... args) {
- return pool.template construct<Comp>(entity, args...);
- }
- template<typename Comp>
- void remove(entity_type entity) {
- pool.template destroy<Comp>(entity);
- }
- template<typename... Comp>
- bool has(entity_type entity) const noexcept {
- using accumulator_type = bool[];
- bool all = true;
- accumulator_type accumulator = { true, (all = all && pool.template has<Comp>(entity))... };
- (void)accumulator;
- return all;
- }
- template<typename Comp>
- const Comp & get(entity_type entity) const noexcept {
- return pool.template get<Comp>(entity);
- }
- template<typename Comp>
- Comp & get(entity_type entity) noexcept {
- return pool.template get<Comp>(entity);
- }
- template<typename Comp, typename... Args>
- Comp & replace(entity_type entity, Args... args) {
- return (pool.template get<Comp>(entity) = Comp{args...});
- }
- template<typename Comp, typename... Args>
- Comp & accomodate(entity_type entity, Args... args) {
- return (pool.template has<Comp>(entity)
- ? this->template replace<Comp>(entity, std::forward<Args>(args)...)
- : this->template assign<Comp>(entity, std::forward<Args>(args)...));
- }
- entity_type clone(entity_type from) {
- auto to = create();
- using accumulator_type = int[];
- accumulator_type accumulator = { 0, (clone<Components>(from, to), 0)... };
- (void)accumulator;
- return to;
- }
- template<typename Comp>
- Comp & copy(entity_type from, entity_type to) {
- return (pool.template get<Comp>(to) = pool.template get<Comp>(from));
- }
- void copy(entity_type from, entity_type to) {
- using accumulator_type = int[];
- accumulator_type accumulator = { 0, (sync<Components>(from, to), 0)... };
- (void)accumulator;
- }
- template<typename Comp>
- void reset(entity_type entity) {
- if(pool.template has<Comp>(entity)) {
- pool.template destroy<Comp>(entity);
- }
- }
- template<typename Comp>
- void reset() {
- pool.template reset<Comp>();
- }
- void reset() {
- available.clear();
- count = 0;
- pool.reset();
- }
- template<typename... Comp>
- view_type<Comp...> view() {
- return view_type<Comp...>{pool};
- }
- private:
- std::vector<entity_type> available;
- entity_type count;
- pool_type pool;
- };
- template<typename Entity, typename... Components>
- using StandardRegistry = Registry<ComponentPool<Entity, Components...>>;
- template<typename... Components>
- using DefaultRegistry = Registry<ComponentPool<std::uint32_t, Components...>>;
- }
- #endif // ENTT_REGISTRY_HPP
|