From 7f8ab67e9ea31d8073e1809da409f37ecc8b690c Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Mon, 9 Jul 2018 15:17:09 +0200 Subject: [PATCH] performance improvements --- src/entt/entity/registry.hpp | 63 ++++++++++++++++++++---------------- src/entt/entity/view.hpp | 21 +++++------- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 9949eb3e4..fabe4f482 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -44,10 +44,10 @@ class Registry { using signal_type = SigH; using traits_type = entt_traits; - template + template static void creating(Registry ®istry, const Entity entity) { if(registry.has(entity)) { - registry.handlers[handler_family::type()]->construct(entity); + registry.handlers[Type()]->construct(entity); } } @@ -74,6 +74,35 @@ class Registry { Tag tag; }; + template + void connect(std::index_sequence) { + auto &cpool = pools[component_family::type()]; + std::get<1>(cpool).sink().template connect<&Registry::creating<&handler_family::type, std::tuple_element_t<(Indexes < Pivot ? Indexes : (Indexes+1)), std::tuple>...>>(); + std::get<2>(cpool).sink().template connect<&Registry::destroying>(); + } + + template + void connect(std::index_sequence) { + using accumulator_type = int[]; + accumulator_type accumulator = { (assure(), connect(std::make_index_sequence{}), 0)... }; + (void)accumulator; + } + + template + void disconnect(std::index_sequence) { + auto &cpool = pools[component_family::type()]; + std::get<1>(cpool).sink().template disconnect<&Registry::creating<&handler_family::type, std::tuple_element_t<(Indexes < Pivot ? Indexes : (Indexes+1)), std::tuple>...>>(); + std::get<2>(cpool).sink().template disconnect<&Registry::destroying>(); + } + + template + void disconnect(std::index_sequence) { + using accumulator_type = int[]; + // if a set exists, pools have already been created for it + accumulator_type accumulator = { (disconnect(std::make_index_sequence{}), 0)... }; + (void)accumulator; + } + template inline bool managed() const ENTT_NOEXCEPT { const auto ctype = component_family::type(); @@ -1335,22 +1364,13 @@ public: } if(!handlers[htype]) { + connect(std::make_index_sequence{}); handlers[htype] = std::make_unique>(); - auto &handler = handlers[htype]; + auto &handler = *handlers[htype]; for(auto entity: view()) { - handler->construct(entity); + handler.construct(entity); } - - auto connect = [this](const auto ctype) { - auto &cpool = pools[ctype]; - std::get<1>(cpool).sink().template connect<&Registry::creating>(); - std::get<2>(cpool).sink().template connect<&Registry::destroying>(); - }; - - using accumulator_type = int[]; - accumulator_type accumulator = { (assure(), connect(component_family::type()), 0)... }; - (void)accumulator; } } @@ -1372,19 +1392,8 @@ public: template void discard() { if(contains()) { - const auto htype = handler_family::type(); - - auto disconnect = [this](const auto ctype) { - auto &cpool = pools[ctype]; - std::get<1>(cpool).sink().template disconnect<&Registry::creating>(); - std::get<2>(cpool).sink().template disconnect<&Registry::destroying>(); - }; - - // if a set exists, pools have already been created for it - using accumulator_type = int[]; - accumulator_type accumulator = { (disconnect(component_family::type()), 0)... }; - handlers[htype].reset(); - (void)accumulator; + disconnect(std::make_index_sequence{}); + handlers[handler_family::type()].reset(); } } diff --git a/src/entt/entity/view.hpp b/src/entt/entity/view.hpp index 47b0c59af..214f862af 100644 --- a/src/entt/entity/view.hpp +++ b/src/entt/entity/view.hpp @@ -590,26 +590,21 @@ class View final { template void each(const pool_type &cpool, Func func, std::index_sequence) const { const auto other = unchecked(&cpool); - std::array data{{cpool.view_type::cbegin(), std::get(other)->cbegin()...}}; + std::array data{{std::get(other)->cbegin()...}}; + const auto extent = std::min({ pool().extent()... }); auto raw = std::make_tuple(pool().cbegin()...); const auto end = cpool.view_type::cend(); - std::size_t pos{}; + auto begin = cpool.view_type::cbegin(); // we can directly use the raw iterators if pools are ordered - while(!pos && data[0] != end) { - for(pos = data.size() - 1; pos && *(data[pos]++) == *data[pos-1]; --pos); - - if(!pos) { - func(*(data[0]++), *(std::get>(raw)++)...); - } + while(begin != end && std::min({ (*(std::get(data)++) == *begin)... })) { + func(*(begin++), *(std::get>(raw)++)...); } - const auto extent = std::min({ pool().extent()... }); - auto it = std::get>(raw); - // fallback to visit what remains using indirections - for(; data[0] != end; ++data[0], ++it) { - const auto entity = *data[0]; + while(begin != end) { + const auto entity = *(begin++); + const auto it = std::get>(raw)++; const auto sz = size_type(entity & traits_type::entity_mask); if(sz < extent && std::all_of(other.cbegin(), other.cend(), [entity](const view_type *view) { return view->fast(entity); })) {