performance improvements
This commit is contained in:
@@ -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 ®istry, 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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); })) {
|
||||
|
||||
Reference in New Issue
Block a user