Просмотр исходного кода

registry: component signals return only the entity

Michele Caini 5 лет назад
Родитель
Сommit
9da15826db

+ 8 - 8
src/entt/entity/observer.hpp

@@ -177,8 +177,8 @@ class basic_observer {
     template<typename... Reject, typename... Require, typename AnyOf>
     struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, AnyOf>> {
         template<std::size_t Index>
-        static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> &reg, const Entity entt) {
-            if(reg.template has<Require...>(entt) && !reg.template any<Reject...>(entt)) {
+        static void maybe_valid_if(basic_observer &obs, const Entity entt) {
+            if(obs.target->template has<Require...>(entt) && !obs.target->template any<Reject...>(entt)) {
                 if(auto *comp = obs.view.try_get(entt); !comp) {
                     obs.view.emplace(entt);
                 }
@@ -188,7 +188,7 @@ class basic_observer {
         }
 
         template<std::size_t Index>
-        static void discard_if(basic_observer &obs, const basic_registry<Entity> &, const Entity entt) {
+        static void discard_if(basic_observer &obs, const Entity entt) {
             if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
                 obs.view.erase(entt);
             }
@@ -213,12 +213,12 @@ class basic_observer {
     template<typename... Reject, typename... Require, typename... NoneOf, typename... AllOf>
     struct matcher_handler<matcher<type_list<Reject...>, type_list<Require...>, type_list<NoneOf...>, AllOf...>> {
         template<std::size_t Index, typename... Ignore>
-        static void maybe_valid_if(basic_observer &obs, const basic_registry<Entity> &reg, const Entity entt) {
-            if([&reg, entt]() {
+        static void maybe_valid_if(basic_observer &obs, const Entity entt) {
+            if([&obs, entt]() {
                 if constexpr(sizeof...(Ignore) == 0) {
-                    return reg.template has<AllOf..., Require...>(entt) && !reg.template any<NoneOf..., Reject...>(entt);
+                    return obs.target->template has<AllOf..., Require...>(entt) && !obs.target->template any<NoneOf..., Reject...>(entt);
                 } else {
-                    return reg.template has<AllOf..., Require...>(entt) && ((std::is_same_v<Ignore..., NoneOf> || !reg.template any<NoneOf>(entt)) && ...) && !reg.template any<Reject...>(entt);
+                    return obs.target->template has<AllOf..., Require...>(entt) && ((std::is_same_v<Ignore..., NoneOf> || !obs.target->template any<NoneOf>(entt)) && ...) && !obs.target->template any<Reject...>(entt);
                 }
             }())
             {
@@ -231,7 +231,7 @@ class basic_observer {
         }
 
         template<std::size_t Index>
-        static void discard_if(basic_observer &obs, const basic_registry<Entity> &, const Entity entt) {
+        static void discard_if(basic_observer &obs, const Entity entt) {
             if(auto *value = obs.view.try_get(entt); value && !(*value &= (~(1 << Index)))) {
                 obs.view.erase(entt);
             }

+ 48 - 43
src/entt/entity/registry.hpp

@@ -60,9 +60,9 @@ class basic_registry {
         }
 
         template<typename... Args>
-        decltype(auto) emplace(basic_registry &owner, const Entity entt, Args &&... args) {
+        decltype(auto) emplace(const Entity entt, Args &&... args) {
             storage<entity_type, Component>::emplace(entt, std::forward<Args>(args)...);
-            construction.publish(owner, entt);
+            construction.publish(entt);
 
             if constexpr(!is_eto_eligible_v<Component>) {
                 return this->get(entt);
@@ -70,57 +70,57 @@ class basic_registry {
         }
 
         template<typename It, typename... Args>
-        void insert(basic_registry &owner, It first, It last, Args &&... args) {
+        void insert(It first, It last, Args &&... args) {
             storage<entity_type, Component>::insert(first, last, std::forward<Args>(args)...);
 
             if(!construction.empty()) {
-                while(first != last) { construction.publish(owner, *(first++)); }
+                while(first != last) { construction.publish(*(first++)); }
             }
         }
 
-        void remove(basic_registry &owner, const Entity entt) {
-            destruction.publish(owner, entt);
+        void remove(const Entity entt) {
+            destruction.publish(entt);
             this->erase(entt);
         }
 
         template<typename It>
-        void remove(basic_registry &owner, It first, It last) {
+        void remove(It first, It last) {
             if(std::distance(first, last) == std::distance(this->begin(), this->end())) {
                 if(!destruction.empty()) {
-                    while(first != last) { destruction.publish(owner, *(first++)); }
+                    while(first != last) { destruction.publish(*(first++)); }
                 }
 
                 this->clear();
             } else {
-                while(first != last) { this->remove(owner, *(first++)); }
+                while(first != last) { this->remove(*(first++)); }
             }
         }
 
         template<typename... Func>
-        decltype(auto) patch(basic_registry &owner, const Entity entt, [[maybe_unused]] Func &&... func) {
+        decltype(auto) patch(const Entity entt, [[maybe_unused]] Func &&... func) {
             if constexpr(is_eto_eligible_v<Component>) {
-                update.publish(owner, entt);
+                update.publish(entt);
             } else {
                 (std::forward<Func>(func)(this->get(entt)), ...);
-                update.publish(owner, entt);
+                update.publish(entt);
                 return this->get(entt);
             }
         }
 
-        decltype(auto) replace(basic_registry &owner, const Entity entt, Component component) {
-            return patch(owner, entt, [&component](auto &&curr) { curr = std::move(component); });
+        decltype(auto) replace(const Entity entt, Component component) {
+            return patch(entt, [&component](auto &&curr) { curr = std::move(component); });
         }
 
     private:
-        sigh<void(basic_registry &, const Entity)> construction{};
-        sigh<void(basic_registry &, const Entity)> destruction{};
-        sigh<void(basic_registry &, const Entity)> update{};
+        sigh<void(const Entity)> construction{};
+        sigh<void(const Entity)> destruction{};
+        sigh<void(const Entity)> update{};
     };
 
     struct pool_data {
         id_type type_id{};
         std::unique_ptr<sparse_set<Entity>> pool{};
-        void(* remove)(sparse_set<Entity> &, basic_registry &, const Entity){};
+        void(* remove)(sparse_set<Entity> &, const Entity){};
     };
 
     template<typename...>
@@ -130,14 +130,19 @@ class basic_registry {
     struct group_handler<exclude_t<Exclude...>, get_t<Get...>, Owned...> {
         static_assert(std::conjunction_v<std::is_same<Owned, std::decay_t<Owned>>..., std::is_same<Get, std::decay_t<Get>>..., std::is_same<Exclude, std::decay_t<Exclude>>...>, "One or more component types are invalid");
         std::conditional_t<sizeof...(Owned) == 0, sparse_set<Entity>, std::size_t> current{};
+        basic_registry *owner;
+
+        group_handler(basic_registry &parent)
+            : owner{&parent}
+        {}
 
         template<typename Component>
-        void maybe_valid_if(basic_registry &owner, const Entity entt) {
-            [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...);
+        void maybe_valid_if(const Entity entt) {
+            [[maybe_unused]] const auto cpools = std::forward_as_tuple(owner->assure<Owned>()...);
 
             const auto is_valid = ((std::is_same_v<Component, Owned> || std::get<pool_handler<Owned> &>(cpools).contains(entt)) && ...)
-                    && ((std::is_same_v<Component, Get> || owner.assure<Get>().contains(entt)) && ...)
-                    && ((std::is_same_v<Component, Exclude> || !owner.assure<Exclude>().contains(entt)) && ...);
+                    && ((std::is_same_v<Component, Get> || owner->assure<Get>().contains(entt)) && ...)
+                    && ((std::is_same_v<Component, Exclude> || !owner->assure<Exclude>().contains(entt)) && ...);
 
             if constexpr(sizeof...(Owned) == 0) {
                 if(is_valid && !current.contains(entt)) {
@@ -151,13 +156,13 @@ class basic_registry {
             }
         }
 
-        void discard_if([[maybe_unused]] basic_registry &owner, const Entity entt) {
+        void discard_if(const Entity entt) {
             if constexpr(sizeof...(Owned) == 0) {
                 if(current.contains(entt)) {
                     current.erase(entt);
                 }
             } else {
-                if(const auto cpools = std::forward_as_tuple(owner.assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
+                if(const auto cpools = std::forward_as_tuple(owner->assure<Owned>()...); std::get<0>(cpools).contains(entt) && (std::get<0>(cpools).index(entt) < current)) {
                     const auto pos = --current;
                     (std::get<pool_handler<Owned> &>(cpools).swap(std::get<pool_handler<Owned> &>(cpools).data()[pos], entt), ...);
                 }
@@ -192,8 +197,8 @@ class basic_registry {
             if(auto &&pdata = pools[index]; !pdata.pool) {
                 pdata.type_id = type_info<Component>::id();
                 pdata.pool.reset(new pool_handler<Component>());
-                pdata.remove = [](sparse_set<entity_type> &target, basic_registry &owner, const entity_type entt) {
-                    static_cast<pool_handler<Component> &>(target).remove(owner, entt);
+                pdata.remove = [](sparse_set<entity_type> &target, const entity_type entt) {
+                    static_cast<pool_handler<Component> &>(target).remove(entt);
                 };
             }
 
@@ -203,8 +208,8 @@ class basic_registry {
                 cpool = pools.emplace_back(pool_data{
                     type_info<Component>::id(),
                     std::unique_ptr<sparse_set<entity_type>>{new pool_handler<Component>()},
-                    [](sparse_set<entity_type> &target, basic_registry &owner, const entity_type entt) {
-                        static_cast<pool_handler<Component> &>(target).remove(owner, entt);
+                    [](sparse_set<entity_type> &target, const entity_type entt) {
+                        static_cast<pool_handler<Component> &>(target).remove(entt);
                     }
                 }).pool.get();
             } else {
@@ -644,7 +649,7 @@ public:
     template<typename Component, typename... Args>
     decltype(auto) emplace(const entity_type entity, Args &&... args) {
         ENTT_ASSERT(valid(entity));
-        return assure<Component>().emplace(*this, entity, std::forward<Args>(args)...);
+        return assure<Component>().emplace(entity, std::forward<Args>(args)...);
     }
 
     /**
@@ -661,7 +666,7 @@ public:
     template<typename Component, typename It>
     void insert(It first, It last, const Component &value = {}) {
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
-        assure<Component>().insert(*this, first, last, value);
+        assure<Component>().insert(first, last, value);
     }
 
     /**
@@ -681,7 +686,7 @@ public:
     void insert(EIt first, EIt last, CIt from, CIt to) {
         static_assert(std::is_constructible_v<Component, typename std::iterator_traits<CIt>::value_type>, "Invalid value type");
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
-        assure<Component>().insert(*this, first, last, from, to);
+        assure<Component>().insert(first, last, from, to);
     }
 
     /**
@@ -712,8 +717,8 @@ public:
         auto &cpool = assure<Component>();
 
         return cpool.contains(entity)
-                ? cpool.replace(*this, entity, Component{std::forward<Args>(args)...})
-                : cpool.emplace(*this, entity, std::forward<Args>(args)...);
+                ? cpool.replace(entity, Component{std::forward<Args>(args)...})
+                : cpool.emplace(entity, std::forward<Args>(args)...);
     }
 
     /**
@@ -746,7 +751,7 @@ public:
     template<typename Component, typename... Func>
     decltype(auto) patch(const entity_type entity, Func &&... func) {
         ENTT_ASSERT(valid(entity));
-        return assure<Component>().patch(*this, entity, std::forward<Func>(func)...);
+        return assure<Component>().patch(entity, std::forward<Func>(func)...);
     }
 
     /**
@@ -771,7 +776,7 @@ public:
      */
     template<typename Component, typename... Args>
     decltype(auto) replace(const entity_type entity, Args &&... args) {
-        return assure<Component>().replace(*this, entity, Component{std::forward<Args>(args)...});
+        return assure<Component>().replace(entity, Component{std::forward<Args>(args)...});
     }
 
     /**
@@ -790,7 +795,7 @@ public:
     template<typename... Component>
     void remove(const entity_type entity) {
         ENTT_ASSERT(valid(entity));
-        (assure<Component>().remove(*this, entity), ...);
+        (assure<Component>().remove(entity), ...);
     }
 
     /**
@@ -806,7 +811,7 @@ public:
     template<typename... Component, typename It>
     void remove(It first, It last) {
         ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }));
-        (assure<Component>().remove(*this, first, last), ...);
+        (assure<Component>().remove(first, last), ...);
     }
 
     /**
@@ -834,7 +839,7 @@ public:
         ENTT_ASSERT(valid(entity));
 
         return ([this, entity](auto &&cpool) {
-            return cpool.contains(entity) ? (cpool.remove(*this, entity), true) : false;
+            return cpool.contains(entity) ? (cpool.remove(entity), true) : false;
         }(assure<Component>()) + ... + size_type{});
     }
 
@@ -859,7 +864,7 @@ public:
 
         for(auto pos = pools.size(); pos; --pos) {
             if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->contains(entity)) {
-                pdata.remove(*pdata.pool, *this, entity);
+                pdata.remove(*pdata.pool, entity);
             }
         }
     }
@@ -966,7 +971,7 @@ public:
     [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&... args) {
         ENTT_ASSERT(valid(entity));
         auto &cpool = assure<Component>();
-        return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(*this, entity, std::forward<Args>(args)...);
+        return cpool.contains(entity) ? cpool.get(entity) : cpool.emplace(entity, std::forward<Args>(args)...);
     }
 
     /**
@@ -1015,7 +1020,7 @@ public:
             each([this](const auto entity) { this->destroy(entity); });
         } else {
             ([this](auto &&cpool) {
-                cpool.remove(*this, cpool.sparse_set<entity_type>::begin(), cpool.sparse_set<entity_type>::end());
+                cpool.remove(cpool.sparse_set<entity_type>::begin(), cpool.sparse_set<entity_type>::end());
             }(assure<Component>()), ...);
         }
     }
@@ -1308,7 +1313,7 @@ public:
         if(!handler) {
             group_data candidate = {
                 size,
-                { new handler_type{}, [](void *instance) { delete static_cast<handler_type *>(instance); } },
+                { new handler_type{*this}, [](void *instance) { delete static_cast<handler_type *>(instance); } },
                 []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<std::decay_t<Owned>>::id()) || ...); },
                 []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<std::decay_t<Get>>::id()) || ...); },
                 []([[maybe_unused]] const id_type ctype) ENTT_NOEXCEPT { return ((ctype == type_info<Exclude>::id()) || ...); },
@@ -1356,7 +1361,7 @@ public:
             } else {
                 // we cannot iterate backwards because we want to leave behind valid entities in case of owned types
                 for(auto *first = std::get<0>(cpools).data(), *last = first + std::get<0>(cpools).size(); first != last; ++first) {
-                    handler->template maybe_valid_if<std::tuple_element_t<0, std::tuple<std::decay_t<Owned>...>>>(*this, *first);
+                    handler->template maybe_valid_if<std::tuple_element_t<0, std::tuple<std::decay_t<Owned>...>>>(*first);
                 }
             }
         }

+ 2 - 2
test/entt/entity/group.cpp

@@ -570,7 +570,7 @@ TEST(NonOwningGroup, FrontBack) {
 
 TEST(NonOwningGroup, SignalRace) {
     entt::registry registry;
-    registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>();
+    registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>(registry);
     const auto group = registry.group(entt::get<int, double>);
 
     auto entity = registry.create();
@@ -1227,7 +1227,7 @@ TEST(OwningGroup, FrontBack) {
 
 TEST(OwningGroup, SignalRace) {
     entt::registry registry;
-    registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>();
+    registry.on_construct<double>().connect<&entt::registry::emplace_or_replace<int>>(registry);
     const auto group = registry.group<int>(entt::get<double>);
 
     auto entity = registry.create();

+ 1 - 1
test/entt/entity/helper.cpp

@@ -33,7 +33,7 @@ TEST(Helper, Invoke) {
     entt::registry registry;
     const auto entity = registry.create();
 
-    registry.on_construct<clazz>().connect<entt::invoke<&clazz::func>>();
+    registry.on_construct<clazz>().connect<entt::invoke<&clazz::func>>(registry);
     registry.emplace<clazz>(entity);
 
     ASSERT_EQ(entity, registry.get<clazz>(entity).entt);

+ 7 - 11
test/entt/entity/registry.cpp

@@ -27,17 +27,13 @@ struct listener {
     }
 
     template<typename Component>
-    void incr(const entt::registry &registry, entt::entity entity) {
-        ASSERT_TRUE(registry.valid(entity));
-        ASSERT_TRUE(registry.has<Component>(entity));
+    void incr(entt::entity entity) {
         last = entity;
         ++counter;
     }
 
     template<typename Component>
-    void decr(const entt::registry &registry, entt::entity entity) {
-        ASSERT_TRUE(registry.valid(entity));
-        ASSERT_TRUE(registry.has<Component>(entity));
+    void decr(entt::entity entity) {
         last = entity;
         --counter;
     }
@@ -1378,8 +1374,8 @@ TEST(Registry, Dependencies) {
     constexpr auto emplace_or_replace = &entt::registry::emplace_or_replace<double>;
     constexpr auto remove = &entt::registry::remove<double>;
 
-    registry.on_construct<int>().connect<emplace_or_replace>();
-    registry.on_destroy<int>().connect<remove>();
+    registry.on_construct<int>().connect<emplace_or_replace>(registry);
+    registry.on_destroy<int>().connect<remove>(registry);
     registry.emplace<double>(entity, .3);
 
     ASSERT_FALSE(registry.has<int>(entity));
@@ -1394,8 +1390,8 @@ TEST(Registry, Dependencies) {
 
     ASSERT_FALSE((registry.any<int, double>(entity)));
 
-    registry.on_construct<int>().disconnect<emplace_or_replace>();
-    registry.on_destroy<int>().disconnect<remove>();
+    registry.on_construct<int>().disconnect<emplace_or_replace>(registry);
+    registry.on_destroy<int>().disconnect<remove>(registry);
     registry.emplace<int>(entity);
 
     ASSERT_TRUE((registry.any<int, double>(entity)));
@@ -1404,7 +1400,7 @@ TEST(Registry, Dependencies) {
 
 TEST(Registry, StableEmplace) {
     entt::registry registry;
-    registry.on_construct<int>().connect<&listener::sort<int>>();
+    registry.on_construct<int>().connect<&listener::sort<int>>(registry);
     registry.emplace<int>(registry.create(), 0);
 
     ASSERT_EQ(registry.emplace<int>(registry.create(), 1), 1);