Преглед изворни кода

removed indexes from persistent views

Michele Caini пре 7 година
родитељ
комит
a5a6a58556
2 измењених фајлова са 43 додато и 108 уклоњено
  1. 30 72
      src/entt/entity/registry.hpp
  2. 13 36
      src/entt/entity/view.hpp

+ 30 - 72
src/entt/entity/registry.hpp

@@ -43,65 +43,23 @@ template<typename Entity = std::uint32_t>
 class registry {
     using component_family = family<struct internal_registry_component_family>;
     using handler_family = family<struct internal_registry_handler_family>;
-    using component_signal_type = sigh<void(registry &, const Entity)>;
-    using pool_signal_type = sigh<void(registry &, const typename component_family::family_type)>;
+    using signal_type = sigh<void(registry &, const Entity)>;
     using traits_type = entt_traits<Entity>;
 
-    template<typename, typename>
-    struct handler_pool;
-
-    template<typename... Component, typename... Exclude>
-    struct handler_pool<type_list<Component...>, type_list<Exclude...>>: sparse_set<Entity, std::array<typename sparse_set<Entity>::size_type, sizeof...(Component)>> {
-        void candidate(registry &reg, const Entity entity) {
-            if((reg.assure<Component>().has(entity) && ...) && !(reg.assure<Exclude>().has(entity) || ...)) {
-                handler_pool::construct(entity, reg.pools[component_family::type<Component>]->get(entity)...);
-            }
-        }
-
-        template<typename Comp, std::size_t Index>
-        void check(registry &reg, const Entity entity) {
-            const sparse_set<Entity> &cpool = reg.assure<Comp>();
-            const auto last = *cpool.begin();
-
-            if(handler_pool::has(last)) {
-                handler_pool::get(last)[Index] = cpool.get(entity);
-            }
-
-            if(handler_pool::has(entity)) {
-                handler_pool::destroy(entity);
-            }
-        }
-
-        void discard(registry &, const Entity entity) {
-            if(handler_pool::has(entity)) {
-                handler_pool::destroy(entity);
-            }
+    template<typename Type, auto Has, auto Any>
+    static void construct_if(registry &reg, const Entity entity) {
+        if((reg.*Has)(entity) && !(reg.*Any)(entity)) {
+            reg.handlers[handler_family::type<Type>]->construct(entity);
         }
+    }
 
-        void rebuild(registry &reg, const typename component_family::family_type ctype) {
-            auto index = sizeof...(Component);
-            decltype(index) cnt{};
-
-            ((index = (component_family::type<Component> == ctype) ? cnt++ : (static_cast<void>(++cnt), index)), ...);
-
-            if(index != sizeof...(Component)) {
-                auto begin = sparse_set<Entity>::begin();
-                const auto &cpool = *reg.pools[ctype];
+    template<typename Type>
+    static void destroy_if(registry &reg, const Entity entity) {
+        auto &handler = reg.handlers[handler_family::type<Type>];
 
-                for(auto &&indexes: *this) {
-                    indexes[index] = cpool.get(*(begin++));
-                }
-            }
+        if(handler->has(entity)) {
+            handler->destroy(entity);
         }
-    };
-
-    template<typename... Component, typename... Exclude, std::size_t... Indexes>
-    void connect(handler_pool<type_list<Component...>, type_list<Exclude...>> *handler, std::index_sequence<Indexes...>) {
-        using handler_type = handler_pool<type_list<Component...>, type_list<Exclude...>>;
-        (sighs[component_family::type<Component>].first.sink().template connect<&handler_type::candidate>(handler), ...);
-        (sighs[component_family::type<Exclude>].first.sink().template connect<&handler_type::discard>(handler), ...);
-        (sighs[component_family::type<Component>].second.sink().template connect<&handler_type::template check<Component, Indexes>>(handler), ...);
-        (sighs[component_family::type<Exclude>].second.sink().template connect<&handler_type::candidate>(handler), ...);
     }
 
     template<typename Component>
@@ -120,6 +78,12 @@ class registry {
         return static_cast<sparse_set<Entity, std::decay_t<Component>> &>(*pools[ctype]);
     }
 
+    template<typename... Component>
+    bool any_of(const Entity entity) const ENTT_NOEXCEPT {
+        assert(valid(entity));
+        return (assure<Component>().has(entity) || ...);
+    }
+
 public:
     /*! @brief Underlying entity identifier. */
     using entity_type = typename traits_type::entity_type;
@@ -130,7 +94,7 @@ public:
     /*! @brief Unsigned integer type. */
     using component_type = typename component_family::family_type;
     /*! @brief Type of sink for the given component. */
-    using sink_type = typename component_signal_type::sink_type;
+    using sink_type = typename signal_type::sink_type;
 
     /**
      * @brief Returns the numeric identifier of a type of component at runtime.
@@ -855,7 +819,6 @@ public:
     template<typename Component, typename Compare, typename Sort = std_sort, typename... Args>
     void sort(Compare compare, Sort sort = Sort{}, Args &&... args) {
         assure<Component>().sort(std::move(compare), std::move(sort), std::forward<Args>(args)...);
-        invalidate.publish(*this, component_family::type<Component>);
     }
 
     /**
@@ -891,7 +854,6 @@ public:
     template<typename To, typename From>
     void sort() {
         assure<To>().respect(assure<From>());
-        invalidate.publish(*this, component_family::type<To>);
     }
 
     /**
@@ -1129,9 +1091,8 @@ public:
      */
     template<typename... Component, typename... Exclude>
     entt::persistent_view<Entity, Component...> persistent_view(type_list<Exclude...> = {}) {
-        static_assert(sizeof...(Component));
-        using handler_type = handler_pool<type_list<Component...>, type_list<Exclude...>>;
-        const auto htype = handler_family::type<Component...>;
+        using handler_type = type_list<Component..., type_list<Exclude...>>;
+        const auto htype = handler_family::type<handler_type>;
 
         if(!(htype < handlers.size())) {
             handlers.resize(htype + 1);
@@ -1141,24 +1102,22 @@ public:
             (assure<Component>(), ...);
             (assure<Exclude>(), ...);
 
-            auto handler = std::make_unique<handler_type>();
+            handlers[htype] = std::make_unique<sparse_set<entity_type>>();
+            auto *direct = handlers[htype].get();
 
-            connect(handler.get(), std::make_index_sequence<sizeof...(Component)>{});
-            invalidate.sink().template connect<&handler_type::rebuild>(handler.get());
+            ((sighs[component_family::type<Component>].first.sink().template connect<&construct_if<handler_type, &registry::has<Component...>, &registry::any_of<Exclude...>>>()), ...);
+            ((sighs[component_family::type<Exclude>].second.sink().template connect<&construct_if<handler_type, &registry::has<Component...>, &registry::any_of<Exclude...>>>()), ...);
+            ((sighs[component_family::type<Exclude>].first.sink().template connect<&registry::destroy_if<handler_type>>()), ...);
+            ((sighs[component_family::type<Component>].second.sink().template connect<&registry::destroy_if<handler_type>>()), ...);
 
             for(const auto entity: view<Component...>()) {
-                if(!(assure<Exclude>().has(entity) || ...)) {
-                    handler->construct(entity, pools[component_family::type<Component>]->get(entity)...);
+                if(!any_of<Exclude...>(entity)) {
+                    direct->construct(entity);
                 }
             }
-
-            handlers[htype] = std::move(handler);
         }
 
-        return {
-            static_cast<handler_type *>(handlers[htype].get()),
-            &assure<Component>()...
-        };
+        return { handlers[htype].get(), &assure<Component>()... };
     }
 
     /*! @copydoc persistent_view */
@@ -1325,11 +1284,10 @@ public:
 private:
     std::vector<std::unique_ptr<sparse_set<Entity>>> handlers;
     mutable std::vector<std::unique_ptr<sparse_set<Entity>>> pools;
-    mutable std::vector<std::pair<component_signal_type, component_signal_type>> sighs;
+    mutable std::vector<std::pair<signal_type, signal_type>> sighs;
     std::vector<entity_type> entities;
     size_type available{};
     entity_type next{};
-    pool_signal_type invalidate;
 };
 
 

+ 13 - 36
src/entt/entity/view.hpp

@@ -77,43 +77,12 @@ class persistent_view {
     template<typename Comp>
     using pool_type = std::conditional_t<std::is_const_v<Comp>, const sparse_set<Entity, std::remove_const_t<Comp>>, sparse_set<Entity, Comp>>;
 
-    using persistent_type = sparse_set<Entity, std::array<typename sparse_set<Entity>::size_type, sizeof...(Component)>>;
-
     // we could use pool_type<Component> *..., but vs complains about it and refuses to compile for unknown reasons (likely a bug)
-    persistent_view(persistent_type *handler, sparse_set<Entity, std::remove_const_t<Component>> *... pools) ENTT_NOEXCEPT
+    persistent_view(sparse_set<Entity> *handler, sparse_set<Entity, std::remove_const_t<Component>> *... pools) ENTT_NOEXCEPT
         : handler{handler},
           pools{pools...}
     {}
 
-    const sparse_set<Entity> * candidate() const ENTT_NOEXCEPT {
-        return std::min({ static_cast<const sparse_set<Entity> *>(std::get<pool_type<Component> *>(pools))... }, [](const auto *lhs, const auto *rhs) {
-            return lhs->size() < rhs->size();
-        });
-    }
-
-    template<typename Comp>
-    inline decltype(auto) instance([[maybe_unused]] typename persistent_type::object_type::value_type index) const {
-        if constexpr(std::is_empty_v<Comp>) {
-            return *std::get<pool_type<Comp> *>(pools)->raw();
-        } else {
-            return std::get<pool_type<Comp> *>(pools)->raw()[index];
-        }
-    }
-
-    template<typename Func, std::size_t... Indexes>
-    void each(Func func, std::index_sequence<Indexes...>) const {
-        if constexpr(std::is_invocable_v<Func, std::add_lvalue_reference_t<Component>...>) {
-            std::for_each(handler->cbegin(), handler->cend(), [func = std::move(func), this](const auto &indexes) mutable {
-                func(instance<Component>(indexes[Indexes])...);
-            });
-        } else {
-            std::for_each(handler->sparse_set<Entity>::begin(), handler->sparse_set<Entity>::end(), [func = std::move(func), raw = handler->cbegin(), this](const auto entity) mutable {
-                func(entity, instance<Component>((*raw)[Indexes])...);
-                ++raw;
-            });
-        }
-    }
-
 public:
     /*! @brief Underlying entity identifier. */
     using entity_type = typename sparse_set<Entity>::entity_type;
@@ -179,7 +148,7 @@ public:
      * @return An iterator to the first entity that has the given components.
      */
     iterator_type begin() const ENTT_NOEXCEPT {
-        return handler->sparse_set<Entity>::begin();
+        return handler->begin();
     }
 
     /**
@@ -198,7 +167,7 @@ public:
      * given components.
      */
     iterator_type end() const ENTT_NOEXCEPT {
-        return handler->sparse_set<Entity>::end();
+        return handler->end();
     }
 
     /**
@@ -280,7 +249,15 @@ public:
      */
     template<typename Func>
     inline void each(Func func) const {
-        each(std::move(func), std::make_index_sequence<sizeof...(Component)>{});
+        if constexpr(std::is_invocable_v<Func, std::add_lvalue_reference_t<Component>...>) {
+            std::for_each(handler->begin(), handler->end(), [func = std::move(func), this](const auto entity) mutable {
+                func(std::get<pool_type<Component> *>(pools)->get(entity)...);
+            });
+        } else {
+            std::for_each(handler->begin(), handler->end(), [func = std::move(func), this](const auto entity) mutable {
+                func(entity, std::get<pool_type<Component> *>(pools)->get(entity)...);
+            });
+        }
     }
 
     /**
@@ -305,7 +282,7 @@ public:
     }
 
 private:
-    persistent_type *handler;
+    sparse_set<entity_type> *handler;
     const std::tuple<pool_type<Component> *...> pools;
 };