diff --git a/TODO b/TODO index a457a9682..c2af00ac9 100644 --- a/TODO +++ b/TODO @@ -42,9 +42,7 @@ * Mission: get rid of named types - make it possible to use custom generators (eg for plugins) - - registry::ctx_variable can be removed - - dispatcher::wrapper_data can be removed - - emitter::handler_data can be removed + - registry::assure -> pool_type & - registry::group improve, reduce code - Make the following parts work across boundaries (define proper macros): * dispatcher diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index af4216d56..dd4d8af37 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -157,7 +157,6 @@ class basic_registry { void(* assure)(basic_registry &, const sparse_set &); void(* remove)(sparse_set &, basic_registry &, const Entity); void(* stomp)(basic_registry &, const Entity, const sparse_set &, const Entity); - ENTT_ID_TYPE runtime_type; }; struct group_data { @@ -168,19 +167,19 @@ class basic_registry { bool(* exclude)(const component) ENTT_NOEXCEPT; }; - struct ctx_variable { - std::unique_ptr value; - ENTT_ID_TYPE runtime_type; + struct basic_variable { + virtual ~basic_variable() = default; }; - template - static ENTT_ID_TYPE runtime_type() ENTT_NOEXCEPT { - if constexpr(is_named_type_v) { - return named_type_traits_v; - } else { - return Family::template type>; - } - } + template + struct variable_handler: basic_variable { + template + variable_handler(Args &&... args) + : value{std::forward(args)...} + {} + + Type value; + }; auto generate() { Entity entt; @@ -212,50 +211,30 @@ class basic_registry { template const pool_type * assure(Args &&... args) const { const auto ctype = to_integer(type()); - pool_data *pdata = nullptr; - if constexpr(is_named_type_v) { - const auto it = std::find_if(pools.begin(), pools.end(), [ctype](const auto &candidate) { - return candidate.runtime_type == ctype; - }); - - pdata = (it == pools.cend() ? &pools.emplace_back() : &(*it)); - } else { - if(!(ctype < pools.size())) { - pools.resize(ctype+1); - } else if(pools[ctype].pool && pools[ctype].runtime_type != ctype) { - pools.emplace_back(); - std::swap(pools[ctype], pools.back()); - } - - pdata = &pools[ctype]; + if(!(ctype < pools.size())) { + pools.resize(ctype+1); } - if constexpr(sizeof...(Args) != 0) { - ENTT_ASSERT(!pdata->pool || !pdata->pool->size()); - pdata->pool.reset(); - } + if(!pools[ctype].pool) { + pools[ctype].pool = std::make_unique>(std::forward(args)...); - if(!pdata->pool) { - pdata->runtime_type = ctype; - pdata->pool = std::make_unique>(std::forward(args)...); - - pdata->remove = [](sparse_set &cpool, basic_registry &owner, const Entity entt) { + pools[ctype].remove = [](sparse_set &cpool, basic_registry &owner, const Entity entt) { static_cast &>(cpool).remove(owner, entt); }; if constexpr(std::is_copy_constructible_v>) { - pdata->assure = [](basic_registry &other, const sparse_set &cpool) { + pools[ctype].assure = [](basic_registry &other, const sparse_set &cpool) { other.assure(static_cast &>(cpool)); }; - pdata->stomp = [](basic_registry &other, const Entity dst, const sparse_set &cpool, const Entity src) { + pools[ctype].stomp = [](basic_registry &other, const Entity dst, const sparse_set &cpool, const Entity src) { other.assign_or_replace(dst, static_cast &>(cpool).get(src)); }; } } - return static_cast *>(pdata->pool.get()); + return static_cast *>(pools[ctype].pool.get()); } template @@ -291,7 +270,7 @@ public: */ template static component type() ENTT_NOEXCEPT { - return component{runtime_type()}; + return component{component_family::template type>}; } /** @@ -302,10 +281,7 @@ public: */ template void prepare(Args &&... args) { - ENTT_ASSERT(std::none_of(pools.cbegin(), pools.cend(), [ctype = to_integer(type())](auto &&pdata) { - return pdata.pool && pdata.runtime_type == ctype; - })); - + ENTT_ASSERT(to_integer(type()) < pools.size() || !pools[to_integer(type())].pool); [[maybe_unused]] auto *cpool = assure(std::forward(args)...); ENTT_ASSERT(cpool->size() == 0); } @@ -1453,11 +1429,7 @@ public: std::vector *> selected(std::distance(first, last)); std::transform(first, last, selected.begin(), [this](const component ctype) { - auto it = std::find_if(pools.begin(), pools.end(), [ctype = to_integer(ctype)](const auto &pdata) { - return pdata.pool && pdata.runtime_type == ctype; - }); - - return it != pools.cend() && it->pool ? it->pool.get() : nullptr; + return to_integer(ctype) < pools.size() ? pools[to_integer(ctype)].pool.get() : nullptr; }); return { std::move(selected) }; @@ -1504,11 +1476,11 @@ public: other.entities = entities; if constexpr(sizeof...(Component) == 0) { - std::for_each(pools.cbegin(), pools.cend(), [&other](const auto &pdata) { - if(pdata.assure && ((pdata.runtime_type != to_integer(type())) && ...)) { + for(size_type pos{}; pos < pools.size(); ++pos) { + if(const auto &pdata = pools[pos]; pdata.assure && ((pos != to_integer(type())) && ...)) { pdata.assure(other, *pdata.pool); } - }); + } } else { static_assert(sizeof...(Exclude) == 0 && std::conjunction_v...>); (other.assure(*assure()), ...); @@ -1557,11 +1529,11 @@ public: template void stomp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t = {}) { if constexpr(sizeof...(Component) == 0) { - std::for_each(other.pools.cbegin(), other.pools.cend(), [this, dst, src](const auto &pdata) { - if(pdata.stomp && ((pdata.runtime_type != to_integer(type())) && ...) && pdata.pool->has(src)) { + for(size_type pos{}; pos < other.pools.size(); ++pos) { + if(const auto &pdata = other.pools[pos]; pdata.stomp && ((pos != to_integer(type())) && ...) && pdata.pool->has(src)) { pdata.stomp(*this, dst, *pdata.pool, src); } - }); + } } else { static_assert(sizeof...(Exclude) == 0 && std::conjunction_v...>); (assign_or_replace(dst, other.template get(src)), ...); @@ -1654,23 +1626,14 @@ public: */ template Type & set(Args &&... args) { - const auto ctype = runtime_type(); - auto it = std::find_if(vars.begin(), vars.end(), [ctype](const auto &candidate) { - return candidate.runtime_type == ctype; - }); + const auto vtype = context_family::type>; - if(it == vars.cend()) { - vars.push_back({ - decltype(ctx_variable::value){new Type{std::forward(args)...}, [](void *ptr) { delete static_cast(ptr); }}, - ctype - }); - - it = std::prev(vars.end()); - } else { - it->value.reset(new Type{std::forward(args)...}); + if(!(vtype < vars.size())) { + vars.resize(vtype+1); } - return *static_cast(it->value.get()); + vars[vtype] = std::make_unique>(std::forward(args)...); + return static_cast &>(*vars[vtype]).value; } /** @@ -1679,9 +1642,9 @@ public: */ template void unset() { - vars.erase(std::remove_if(vars.begin(), vars.end(), [](auto &var) { - return var.runtime_type == runtime_type(); - }), vars.end()); + if(const auto vtype = context_family::template type>; vtype < vars.size()) { + vars[vtype].reset(); + } } /** @@ -1709,11 +1672,8 @@ public: */ template const Type * try_ctx() const { - const auto it = std::find_if(vars.begin(), vars.end(), [](const auto &var) { - return var.runtime_type == runtime_type(); - }); - - return (it == vars.cend()) ? nullptr : static_cast(it->value.get()); + const auto vtype = context_family::type>; + return vtype < vars.size() && vars[vtype] ? &static_cast &>(*vars[vtype]).value : nullptr; } /*! @copydoc try_ctx */ @@ -1750,7 +1710,7 @@ public: private: mutable std::vector pools{}; std::vector groups{}; - std::vector vars{}; + std::vector> vars{}; std::vector entities{}; entity_type destroyed{null}; };