1
0
Эх сурвалжийг харах

group: decouple constructing and setting prev/next links

Michele Caini 3 жил өмнө
parent
commit
645edfb2b8

+ 17 - 3
src/entt/entity/group.hpp

@@ -136,7 +136,7 @@ class group_handler<owned_t<Owned...>, get_t<Get...>, exclude_t<Exclude...>> fin
     }
     }
 
 
 public:
 public:
-    group_handler(Owned &...opool, Get &...gpool, Exclude &...epool, const void *prev, const void *next)
+    group_handler(Owned &...opool, Get &...gpool, Exclude &...epool)
         : owning_group_descriptor{
         : owning_group_descriptor{
             sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude),
             sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude),
             +[](const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Owned::value_type>::value()) || ...); },
             +[](const id_type ctype) noexcept { return ((ctype == entt::type_hash<typename Owned::value_type>::value()) || ...); },
@@ -145,8 +145,8 @@ public:
           pools{&opool..., &gpool...},
           pools{&opool..., &gpool...},
           filter{&epool...},
           filter{&epool...},
           len{} {
           len{} {
-        std::apply([this, prev, next](auto *...cpool) { ((cpool->on_construct().before(next).template connect<&group_handler::push_on_construct>(*this), cpool->on_destroy().before(prev).template connect<&group_handler::remove_if>(*this)), ...); }, pools);
-        std::apply([this, prev, next](auto *...cpool) { ((cpool->on_construct().before(prev).template connect<&group_handler::remove_if>(*this), cpool->on_destroy().before(next).template connect<&group_handler::push_on_destroy>(*this)), ...); }, filter);
+        std::apply([this](auto *...cpool) { ((cpool->on_construct().template connect<&group_handler::push_on_construct>(*this), cpool->on_destroy().template connect<&group_handler::remove_if>(*this)), ...); }, pools);
+        std::apply([this](auto *...cpool) { ((cpool->on_construct().template connect<&group_handler::remove_if>(*this), cpool->on_destroy().template connect<&group_handler::push_on_destroy>(*this)), ...); }, filter);
 
 
         // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
         // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
         for(auto *first = std::get<0>(pools)->data(), *last = first + std::get<0>(pools)->size(); first != last; ++first) {
         for(auto *first = std::get<0>(pools)->data(), *last = first + std::get<0>(pools)->size(); first != last; ++first) {
@@ -154,6 +154,20 @@ public:
         }
         }
     }
     }
 
 
+    void previous(const void *elem) {
+        if(elem) {
+            std::apply([this, elem](auto *...cpool) { ((cpool->on_destroy().disconnect(this), cpool->on_destroy().before(elem).template connect<&group_handler::remove_if>(*this)), ...); }, pools);
+            std::apply([this, elem](auto *...cpool) { ((cpool->on_construct().disconnect(this), cpool->on_construct().before(elem).template connect<&group_handler::remove_if>(*this)), ...); }, filter);
+        }
+    }
+
+    void next(const void *elem) {
+        if(elem) {
+            std::apply([this, elem](auto *...cpool) { ((cpool->on_construct().disconnect(this), cpool->on_construct().before(elem).template connect<&group_handler::push_on_construct>(*this)), ...); }, pools);
+            std::apply([this, elem](auto *...cpool) { ((cpool->on_destroy().disconnect(this), cpool->on_destroy().before(elem).template connect<&group_handler::push_on_destroy>(*this)), ...); }, filter);
+        }
+    }
+
     [[nodiscard]] std::size_t length() const noexcept {
     [[nodiscard]] std::size_t length() const noexcept {
         return len;
         return len;
     }
     }

+ 8 - 6
src/entt/entity/registry.hpp

@@ -1222,9 +1222,10 @@ public:
                 return {*std::static_pointer_cast<handler_type>(it->second)};
                 return {*std::static_pointer_cast<handler_type>(it->second)};
             }
             }
 
 
-            constexpr auto hsize = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude);
+            auto handler = std::allocate_shared<handler_type>(get_allocator(), assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()...);
+            owning_groups.emplace(type_hash<handler_type>::value(), handler);
 
 
-            ENTT_ASSERT(std::all_of(owning_groups.cbegin(), owning_groups.cend(), [hsize](const auto &data) {
+            ENTT_ASSERT(std::all_of(owning_groups.cbegin(), owning_groups.cend(), [hsize = handler->size](const auto &data) {
                             const auto overlapping = (0u + ... + data.second->owned(type_hash<std::remove_const_t<Owned>>::value()));
                             const auto overlapping = (0u + ... + data.second->owned(type_hash<std::remove_const_t<Owned>>::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 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()));
                             return !overlapping || ((sz == hsize) || (sz == data.second->size));
                             return !overlapping || ((sz == hsize) || (sz == data.second->size));
@@ -1236,18 +1237,19 @@ public:
 
 
             for(auto &&data: owning_groups) {
             for(auto &&data: owning_groups) {
                 if((data.second->owned(type_hash<std::remove_const_t<Owned>>::value()) || ...)) {
                 if((data.second->owned(type_hash<std::remove_const_t<Owned>>::value()) || ...)) {
-                    if(const auto sz = data.second->size; sz < hsize && (prev == nullptr || prev->size < sz)) {
+                    if(const auto sz = data.second->size; sz < handler->size && (prev == nullptr || prev->size < sz)) {
                         prev = data.second.get();
                         prev = data.second.get();
                     }
                     }
 
 
-                    if(const auto sz = data.second->size; sz > hsize && (next == nullptr || next->size > sz)) {
+                    if(const auto sz = data.second->size; sz > handler->size && (next == nullptr || next->size > sz)) {
                         next = data.second.get();
                         next = data.second.get();
                     }
                     }
                 }
                 }
             }
             }
 
 
-            auto handler = std::allocate_shared<handler_type>(get_allocator(), assure<std::remove_const_t<Owned>>()..., assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()..., prev, next);
-            owning_groups.emplace(type_hash<handler_type>::value(), handler);
+            handler->previous(prev);
+            handler->next(next);
+
             return {*handler};
             return {*handler};
         }
         }
     }
     }