registry/group: prepare to get rid of group_data
This commit is contained in:
@@ -5,7 +5,9 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "../config/config.h"
|
||||
#include "../core/fwd.hpp"
|
||||
#include "../core/iterator.hpp"
|
||||
#include "../core/type_info.hpp"
|
||||
#include "../core/type_traits.hpp"
|
||||
#include "entity.hpp"
|
||||
#include "fwd.hpp"
|
||||
@@ -91,8 +93,10 @@ template<typename... Lhs, typename... Rhs>
|
||||
}
|
||||
|
||||
struct basic_group_handler {
|
||||
using size_type = std::size_t;
|
||||
const size_type size;
|
||||
const std::size_t size;
|
||||
bool (*const owned)(const id_type) noexcept;
|
||||
bool (*const get)(const id_type) noexcept;
|
||||
bool (*const exclude)(const id_type) noexcept;
|
||||
};
|
||||
|
||||
template<typename, typename, typename>
|
||||
@@ -115,10 +119,12 @@ public:
|
||||
using entity_type = underlying_type;
|
||||
|
||||
group_handler(Owned &...opool, Get &...gpool, Exclude &...epool)
|
||||
: basic_group_handler{sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude)},
|
||||
pools{&opool..., &gpool...},
|
||||
filter{&epool...},
|
||||
len{} {}
|
||||
: basic_group_handler{
|
||||
sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude),
|
||||
+[](const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Owned::value_type>::value()) || ...); },
|
||||
+[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Get::value_type>::value()) || ...); },
|
||||
+[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Exclude::value_type>::value()) || ...); }},
|
||||
pools{&opool..., &gpool...}, filter{&epool...}, len{} {}
|
||||
|
||||
template<bool Expected>
|
||||
void push_if(const entity_type entt) {
|
||||
@@ -156,10 +162,12 @@ public:
|
||||
|
||||
template<typename Alloc>
|
||||
group_handler(const Alloc &alloc, Get &...gpool, Exclude &...epool)
|
||||
: basic_group_handler{sizeof...(Get) + sizeof...(Exclude)},
|
||||
pools{&gpool...},
|
||||
filter{&epool...},
|
||||
elem{alloc} {}
|
||||
: basic_group_handler{
|
||||
sizeof...(Get) + sizeof...(Exclude),
|
||||
+[](const id_type) noexcept { return false; },
|
||||
+[](const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Get::value_type>::value()) || ...); },
|
||||
+[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Exclude::value_type>::value()) || ...); }},
|
||||
pools{&gpool...}, filter{&epool...}, elem{alloc} {}
|
||||
|
||||
template<bool Expected>
|
||||
void push_if(const entity_type entt) {
|
||||
|
||||
@@ -248,9 +248,6 @@ class basic_registry {
|
||||
|
||||
struct group_data {
|
||||
std::shared_ptr<internal::basic_group_handler> handler;
|
||||
bool (*owned)(const id_type) noexcept;
|
||||
bool (*get)(const id_type) noexcept;
|
||||
bool (*exclude)(const id_type) noexcept;
|
||||
};
|
||||
|
||||
// std::shared_ptr because of its type erased allocator which is useful here
|
||||
@@ -1217,18 +1214,14 @@ public:
|
||||
handler = static_cast<handler_type *>(it->second.handler.get());
|
||||
} else {
|
||||
group_data candidate = {
|
||||
std::allocate_shared<handler_type>(get_allocator(), assure<std::remove_const_t<Owned>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()...),
|
||||
[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == type_hash<std::remove_const_t<Owned>>::value()) || ... || (ctype == type_hash<std::remove_const_t<Other>>::value())); },
|
||||
[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == type_hash<std::remove_const_t<Get>>::value()) || ...); },
|
||||
[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == type_hash<std::remove_const_t<Exclude>>::value()) || ...); },
|
||||
};
|
||||
std::allocate_shared<handler_type>(get_allocator(), assure<std::remove_const_t<Owned>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()...)};
|
||||
|
||||
handler = static_cast<handler_type *>(candidate.handler.get());
|
||||
groups.emplace(type_hash<handler_type>::value(), std::move(candidate));
|
||||
|
||||
ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [size = handler->size](const auto &data) {
|
||||
const auto overlapping = (data.second.owned(type_hash<std::remove_const_t<Owned>>::value()) + ... + data.second.owned(type_hash<std::remove_const_t<Other>>::value()));
|
||||
const auto sz = overlapping + (0u + ... + data.second.get(type_hash<std::remove_const_t<Get>>::value())) + (0u + ... + data.second.exclude(type_hash<std::remove_const_t<Exclude>>::value()));
|
||||
const auto overlapping = (data.second.handler->owned(type_hash<std::remove_const_t<Owned>>::value()) + ... + data.second.handler->owned(type_hash<std::remove_const_t<Other>>::value()));
|
||||
const auto sz = overlapping + (0u + ... + data.second.handler->get(type_hash<std::remove_const_t<Get>>::value())) + (0u + ... + data.second.handler->exclude(type_hash<std::remove_const_t<Exclude>>::value()));
|
||||
return !overlapping || ((sz == size) || (sz == data.second.handler->size));
|
||||
}),
|
||||
"Conflicting groups");
|
||||
@@ -1240,7 +1233,7 @@ public:
|
||||
size_type next_len{};
|
||||
|
||||
for(auto &&data: groups) {
|
||||
if((data.second.owned(type_hash<std::remove_const_t<Owned>>::value()) || ... || data.second.owned(type_hash<std::remove_const_t<Other>>::value()))) {
|
||||
if((data.second.handler->owned(type_hash<std::remove_const_t<Owned>>::value()) || ... || data.second.handler->owned(type_hash<std::remove_const_t<Other>>::value()))) {
|
||||
if(const auto sz = data.second.handler->size; sz < handler->size && (prev == nullptr || prev_len < sz)) {
|
||||
prev = data.second.handler.get();
|
||||
prev_len = sz;
|
||||
@@ -1291,11 +1284,7 @@ public:
|
||||
handler = static_cast<handler_type *>(it->second.handler.get());
|
||||
} else {
|
||||
group_data candidate = {
|
||||
std::allocate_shared<handler_type>(get_allocator(), get_allocator(), assure<std::remove_const_t<Get>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...),
|
||||
[]([[maybe_unused]] const id_type ctype) noexcept { return false; },
|
||||
[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == type_hash<std::remove_const_t<Get>>::value()) || ... || (ctype == type_hash<std::remove_const_t<Other>>::value())); },
|
||||
[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == type_hash<std::remove_const_t<Exclude>>::value()) || ...); },
|
||||
};
|
||||
std::allocate_shared<handler_type>(get_allocator(), get_allocator(), assure<std::remove_const_t<Get>>(), assure<std::remove_const_t<Other>>()..., assure<std::remove_const_t<Exclude>>()...)};
|
||||
|
||||
handler = static_cast<handler_type *>(candidate.handler.get());
|
||||
groups.emplace(type_hash<handler_type>::value(), std::move(candidate));
|
||||
@@ -1337,7 +1326,7 @@ public:
|
||||
*/
|
||||
template<typename... Type>
|
||||
[[nodiscard]] bool owned() const {
|
||||
return std::any_of(groups.cbegin(), groups.cend(), [](auto &&data) { return (data.second.owned(type_hash<std::remove_const_t<Type>>::value()) || ...); });
|
||||
return std::any_of(groups.cbegin(), groups.cend(), [](auto &&data) { return (data.second.handler->owned(type_hash<std::remove_const_t<Type>>::value()) || ...); });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1350,7 +1339,7 @@ public:
|
||||
template<typename... Owned, typename... Get, typename... Exclude>
|
||||
[[nodiscard]] bool sortable(const basic_group<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> &) noexcept {
|
||||
constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
|
||||
auto pred = [size](const auto &data) { return (data.second.owned(type_hash<typename Owned::value_type>::value()) || ...) && (size < data.second.handler->size); };
|
||||
auto pred = [size](const auto &data) { return (data.second.handler->owned(type_hash<typename Owned::value_type>::value()) || ...) && (size < data.second.handler->size); };
|
||||
return std::find_if(groups.cbegin(), groups.cend(), std::move(pred)) == groups.cend();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user