Jelajahi Sumber

group: auto init for non-owning groups

Michele Caini 3 tahun lalu
induk
melakukan
1a12dede6f
2 mengubah file dengan 27 tambahan dan 27 penghapusan
  1. 27 17
      src/entt/entity/group.hpp
  2. 0 10
      src/entt/entity/registry.hpp

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

@@ -172,20 +172,10 @@ class group_handler<owned_t<>, get_t<Get...>, exclude_t<Exclude...>>: public bas
     // nasty workaround for an issue with the toolset v141 that doesn't accept a fold expression here
     static_assert(!std::disjunction_v<std::is_const<Get>..., std::is_const<Exclude>...>, "Const storage type not allowed");
 
-public:
     using basic_common_type = std::common_type_t<typename Get::base_type..., typename Exclude::base_type...>;
-    using entity_type = typename basic_common_type::entity_type;
-
-    template<typename Alloc>
-    group_handler(const Alloc &alloc, Get &...gpool, Exclude &...epool)
-        : 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} {}
+    using underlying_type = typename basic_common_type::entity_type;
 
-    void push_on_construct(const entity_type entt) {
+    void push_on_construct(const underlying_type entt) {
         if(std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools)
            && std::apply([entt](auto *...cpool) { return (!cpool->contains(entt) && ...); }, filter)
            && !elem.contains(entt)) {
@@ -193,7 +183,7 @@ public:
         }
     }
 
-    void push_on_destroy(const entity_type entt) {
+    void push_on_destroy(const underlying_type entt) {
         if(std::apply([entt](auto *...cpool) { return (cpool->contains(entt) && ...); }, pools)
            && std::apply([entt](auto *...cpool) { return (0u + ... + cpool->contains(entt)) == 1u; }, filter)
            && !elem.contains(entt)) {
@@ -201,15 +191,35 @@ public:
         }
     }
 
-    void remove_if(const entity_type entt) {
+    void remove_if(const underlying_type entt) {
         elem.remove(entt);
     }
 
-    basic_common_type &group() noexcept {
+public:
+    using base_type = basic_common_type;
+    using entity_type = underlying_type;
+
+    template<typename Alloc>
+    group_handler(const Alloc &alloc, Get &...gpool, Exclude &...epool)
+        : 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} {
+        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);
+
+        for(const auto entity: static_cast<base_type &>(*std::get<0>(pools))) {
+            push_on_construct(entity);
+        }
+    }
+
+    base_type &group() noexcept {
         return elem;
     }
 
-    const basic_common_type &group() const noexcept {
+    const base_type &group() const noexcept {
         return elem;
     }
 
@@ -226,7 +236,7 @@ public:
 private:
     std::tuple<Get *...> pools;
     std::tuple<Exclude *...> filter;
-    basic_common_type elem;
+    base_type elem;
 };
 
 } // namespace internal

+ 0 - 10
src/entt/entity/registry.hpp

@@ -1212,16 +1212,6 @@ public:
 
         if constexpr(sizeof...(Owned) == 0u) {
             handler = std::allocate_shared<handler_type>(get_allocator(), get_allocator(), assure<std::remove_const_t<Get>>()..., assure<std::remove_const_t<Exclude>>()...);
-
-            (on_construct<std::remove_const_t<Get>>().template connect<&handler_type::push_on_construct>(*handler), ...);
-            (on_destroy<std::remove_const_t<Exclude>>().template connect<&handler_type::push_on_destroy>(*handler), ...);
-
-            (on_destroy<std::remove_const_t<Get>>().template connect<&handler_type::remove_if>(*handler), ...);
-            (on_construct<std::remove_const_t<Exclude>>().template connect<&handler_type::remove_if>(*handler), ...);
-
-            for(const auto entity: view<Get...>(exclude<Exclude...>)) {
-                handler->group().push(entity);
-            }
         } else {
             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>>()...);