Browse Source

registry/group: prepare to get rid of group_data

Michele Caini 3 years ago
parent
commit
d2fa68813f
2 changed files with 25 additions and 28 deletions
  1. 18 10
      src/entt/entity/group.hpp
  2. 7 18
      src/entt/entity/registry.hpp

+ 18 - 10
src/entt/entity/group.hpp

@@ -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) {

+ 7 - 18
src/entt/entity/registry.hpp

@@ -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();
     }