performance improvements

This commit is contained in:
Michele Caini
2018-07-09 15:17:09 +02:00
parent 0e68bb3d2c
commit 7f8ab67e9e
2 changed files with 44 additions and 40 deletions

View File

@@ -44,10 +44,10 @@ class Registry {
using signal_type = SigH<void(Registry &, const Entity)>;
using traits_type = entt_traits<Entity>;
template<typename... Component>
template<typename handler_family::family_type(*Type)(), typename... Component>
static void creating(Registry &registry, const Entity entity) {
if(registry.has<Component...>(entity)) {
registry.handlers[handler_family::type<Component...>()]->construct(entity);
registry.handlers[Type()]->construct(entity);
}
}
@@ -74,6 +74,35 @@ class Registry {
Tag tag;
};
template<typename Comp, std::size_t Pivot, typename... Component, std::size_t... Indexes>
void connect(std::index_sequence<Indexes...>) {
auto &cpool = pools[component_family::type<Comp>()];
std::get<1>(cpool).sink().template connect<&Registry::creating<&handler_family::type<Component...>, std::tuple_element_t<(Indexes < Pivot ? Indexes : (Indexes+1)), std::tuple<Component...>>...>>();
std::get<2>(cpool).sink().template connect<&Registry::destroying<Component...>>();
}
template<typename... Component, std::size_t... Indexes>
void connect(std::index_sequence<Indexes...>) {
using accumulator_type = int[];
accumulator_type accumulator = { (assure<Component>(), connect<Component, Indexes, Component...>(std::make_index_sequence<sizeof...(Component)-1>{}), 0)... };
(void)accumulator;
}
template<typename Comp, std::size_t Pivot, typename... Component, std::size_t... Indexes>
void disconnect(std::index_sequence<Indexes...>) {
auto &cpool = pools[component_family::type<Comp>()];
std::get<1>(cpool).sink().template disconnect<&Registry::creating<&handler_family::type<Component...>, std::tuple_element_t<(Indexes < Pivot ? Indexes : (Indexes+1)), std::tuple<Component...>>...>>();
std::get<2>(cpool).sink().template disconnect<&Registry::destroying<Component...>>();
}
template<typename... Component, std::size_t... Indexes>
void disconnect(std::index_sequence<Indexes...>) {
using accumulator_type = int[];
// if a set exists, pools have already been created for it
accumulator_type accumulator = { (disconnect<Component, Indexes, Component...>(std::make_index_sequence<sizeof...(Component)-1>{}), 0)... };
(void)accumulator;
}
template<typename Component>
inline bool managed() const ENTT_NOEXCEPT {
const auto ctype = component_family::type<Component>();
@@ -1335,22 +1364,13 @@ public:
}
if(!handlers[htype]) {
connect<Component...>(std::make_index_sequence<sizeof...(Component)>{});
handlers[htype] = std::make_unique<SparseSet<entity_type>>();
auto &handler = handlers[htype];
auto &handler = *handlers[htype];
for(auto entity: view<Component...>()) {
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<Component...>>();
std::get<2>(cpool).sink().template connect<&Registry::destroying<Component...>>();
};
using accumulator_type = int[];
accumulator_type accumulator = { (assure<Component>(), connect(component_family::type<Component>()), 0)... };
(void)accumulator;
}
}
@@ -1372,19 +1392,8 @@ public:
template<typename... Component>
void discard() {
if(contains<Component...>()) {
const auto htype = handler_family::type<Component...>();
auto disconnect = [this](const auto ctype) {
auto &cpool = pools[ctype];
std::get<1>(cpool).sink().template disconnect<&Registry::creating<Component...>>();
std::get<2>(cpool).sink().template disconnect<&Registry::destroying<Component...>>();
};
// if a set exists, pools have already been created for it
using accumulator_type = int[];
accumulator_type accumulator = { (disconnect(component_family::type<Component>()), 0)... };
handlers[htype].reset();
(void)accumulator;
disconnect<Component...>(std::make_index_sequence<sizeof...(Component)>{});
handlers[handler_family::type<Component...>()].reset();
}
}

View File

@@ -590,26 +590,21 @@ class View final {
template<typename Comp, typename Func, std::size_t... Indexes>
void each(const pool_type<Comp> &cpool, Func func, std::index_sequence<Indexes...>) const {
const auto other = unchecked(&cpool);
std::array<underlying_iterator_type, sizeof...(Component)> data{{cpool.view_type::cbegin(), std::get<Indexes>(other)->cbegin()...}};
std::array<underlying_iterator_type, sizeof...(Indexes)> data{{std::get<Indexes>(other)->cbegin()...}};
const auto extent = std::min({ pool<Component>().extent()... });
auto raw = std::make_tuple(pool<Component>().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<component_iterator_type<Component>>(raw)++)...);
}
while(begin != end && std::min({ (*(std::get<Indexes>(data)++) == *begin)... })) {
func(*(begin++), *(std::get<component_iterator_type<Component>>(raw)++)...);
}
const auto extent = std::min({ pool<Component>().extent()... });
auto it = std::get<component_iterator_type<Comp>>(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<component_iterator_type<Comp>>(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); })) {