Explorar o código

view: drop specialization for single type views with exclusion list

Michele Caini %!s(int64=2) %!d(string=hai) anos
pai
achega
7ec739b5c7
Modificáronse 2 ficheiros con 9 adicións e 294 borrados
  1. 0 1
      TODO
  2. 9 293
      src/entt/entity/view.hpp

+ 0 - 1
TODO

@@ -17,7 +17,6 @@ TODO (high prio):
 * update view doc: single vs multi type views are no longer a thing actually
 * meta container: add value type to resize
 * further improve meta resolve function by id
-* drop specialization for single type views with exclusion list
 * fully test sparse set with swap only policy and write more tests for entity storage
 * ===> TEST: review view tests after the last changes
 

+ 9 - 293
src/entt/entity/view.hpp

@@ -535,300 +535,15 @@ public:
      * @return An iterable object to use to _visit_ the view.
      */
     [[nodiscard]] iterable each() const noexcept {
-        return {internal::extended_view_iterator{begin(), pools}, internal::extended_view_iterator{end(), pools}};
-    }
-
-    /**
-     * @brief Combines two views in a _more specific_ one.
-     * @tparam OGet Component list of the view to combine with.
-     * @tparam OExclude Filter list of the view to combine with.
-     * @param other The view to combine with.
-     * @return A more specific view.
-     */
-    template<typename... OGet, typename... OExclude>
-    [[nodiscard]] auto operator|(const basic_view<get_t<OGet...>, exclude_t<OExclude...>> &other) const noexcept {
-        return internal::view_pack(
-            std::tuple_cat(pools, other.pools),
-            std::tuple_cat(internal::filter_as_tuple<Exclude...>(filter, std::index_sequence_for<Exclude...>{}), internal::filter_as_tuple<OExclude...>(other.filter, std::index_sequence_for<OExclude...>{})),
-            std::index_sequence_for<Get..., OGet..., Exclude..., OExclude...>{});
-    }
-
-private:
-    std::tuple<Get *...> pools;
-    std::array<const common_type *, sizeof...(Exclude)> filter;
-    const common_type *view;
-};
-
-/**
- * @brief Single type view specialization.
- *
- * This specialization is a refinement of the general purpose view and offers a
- * slightly revised interface to suit individual storage models.
- *
- * @sa basic_view
- *
- * @tparam Get Type of storage iterated by the view.
- * @tparam Exclude Types of storage used to filter the view.
- */
-template<typename Get, typename... Exclude>
-class basic_view<get_t<Get>, exclude_t<Exclude...>> {
-    template<typename, typename, typename>
-    friend class basic_view;
-
-    template<typename Type>
-    static constexpr std::size_t index_of = type_list_index_v<std::remove_const_t<Type>, type_list<typename Get::value_type, typename Exclude::value_type...>>;
-
-public:
-    /*! @brief Common type among all storage types. */
-    using common_type = std::common_type_t<typename Get::base_type, typename Exclude::base_type...>;
-    /*! @brief Underlying entity identifier. */
-    using entity_type = typename common_type::entity_type;
-    /*! @brief Unsigned integer type. */
-    using size_type = std::size_t;
-    /*! @brief Bidirectional iterator type. */
-    using iterator = internal::view_iterator<common_type, 0u, sizeof...(Exclude)>;
-    /*! @brief Iterable view type. */
-    using iterable = iterable_adaptor<internal::extended_view_iterator<iterator, Get>>;
-
-    /*! @brief Default constructor to use to create empty, invalid views. */
-    basic_view() noexcept
-        : pools{},
-          filter{} {}
-
-    /**
-     * @brief Constructs a view from a set of storage classes.
-     * @param value The storage for the types to iterate.
-     * @param excl The storage for the types used to filter the view.
-     */
-    basic_view(Get &value, Exclude &...excl) noexcept
-        : pools{&value},
-          filter{&excl...} {
-    }
-
-    /**
-     * @brief Constructs a view from a set of storage classes.
-     * @param value The storage for the types to iterate.
-     * @param excl The storage for the types used to filter the view.
-     */
-    basic_view(std::tuple<Get &> value, std::tuple<Exclude &...> excl = {}) noexcept
-        : basic_view{std::make_from_tuple<basic_view>(std::tuple_cat(value, excl))} {}
-
-    /**
-     * @brief Returns the leading storage of a view, if any.
-     * @return The leading storage of the view.
-     */
-    [[nodiscard]] const common_type *handle() const noexcept {
-        return storage<0>();
-    }
-
-    /**
-     * @brief Returns the storage for a given component type, if any.
-     * @tparam Type Type of component of which to return the storage.
-     * @return The storage for the given component type.
-     */
-    template<typename Type>
-    [[nodiscard]] auto *storage() const noexcept {
-        return storage<index_of<Type>>();
-    }
-
-    /**
-     * @brief Returns the storage for a given index, if any.
-     * @tparam Index Index of the storage to return.
-     * @return The storage for the given index.
-     */
-    template<std::size_t Index>
-    [[nodiscard]] auto *storage() const noexcept {
-        return std::get<Index>(std::tuple_cat(pools, internal::filter_as_tuple<Exclude...>(filter, std::index_sequence_for<Exclude...>{})));
-    }
-
-    /**
-     * @brief Assigns a storage to a view.
-     * @tparam Type Type of storage to assign to the view.
-     * @param elem A storage to assign to the view.
-     */
-    template<typename Type>
-    void storage(Type &elem) noexcept {
-        storage<index_of<typename Type::value_type>>(elem);
-    }
-
-    /**
-     * @brief Assigns a storage to a view.
-     * @tparam Index Index of the storage to assign to the view.
-     * @tparam Type Type of storage to assign to the view.
-     * @param elem A storage to assign to the view.
-     */
-    template<std::size_t Index, typename Type>
-    void storage(Type &elem) noexcept {
-        if constexpr(Index == 0u) {
-            std::get<Index>(pools) = &elem;
-        } else {
-            std::get<Index - 1u>(filter) = &elem;
-        }
-    }
-
-    /**
-     * @brief Estimates the number of entities iterated by the view.
-     * @return Estimated number of entities iterated by the view.
-     */
-    [[nodiscard]] size_type size_hint() const noexcept {
-        return handle() ? handle()->size() : size_type{};
-    }
-
-    /**
-     * @brief Returns an iterator to the first entity of the view.
-     *
-     * If the view is empty, the returned iterator will be equal to `end()`.
-     *
-     * @return An iterator to the first entity of the view.
-     */
-    [[nodiscard]] iterator begin() const noexcept {
-        return handle() ? iterator{handle()->begin(), handle()->end(), std::array<const common_type *, 0u>{}, filter} : iterator{};
-    }
-
-    /**
-     * @brief Returns an iterator that is past the last entity of the view.
-     * @return An iterator to the entity following the last entity of the view.
-     */
-    [[nodiscard]] iterator end() const noexcept {
-        return handle() ? iterator{handle()->end(), handle()->end(), std::array<const common_type *, 0u>{}, filter} : iterator{};
-    }
-
-    /**
-     * @brief Returns the first entity of the view, if any.
-     * @return The first entity of the view if one exists, the null entity
-     * otherwise.
-     */
-    [[nodiscard]] entity_type front() const noexcept {
-        const auto it = begin();
-        return it != end() ? *it : null;
-    }
-
-    /**
-     * @brief Returns the last entity of the view, if any.
-     * @return The last entity of the view if one exists, the null entity
-     * otherwise.
-     */
-    [[nodiscard]] entity_type back() const noexcept {
-        if(auto *view = handle(); view) {
-            auto it = view->rbegin();
-            for(const auto last = view->rend(); it != last && !contains(*it); ++it) {}
-            return it == view->rend() ? null : *it;
-        }
-
-        return null;
-    }
-
-    /**
-     * @brief Finds an entity.
-     * @param entt A valid identifier.
-     * @return An iterator to the given entity if it's found, past the end
-     * iterator otherwise.
-     */
-    [[nodiscard]] iterator find(const entity_type entt) const noexcept {
-        return contains(entt) ? iterator{handle()->find(entt), handle()->end(), std::array<const common_type *, 0u>{}, filter} : end();
-    }
-
-    /**
-     * @brief Returns the components assigned to the given entity.
-     * @param entt A valid identifier.
-     * @return The components assigned to the given entity.
-     */
-    [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
-        return get(entt);
-    }
-
-    /**
-     * @brief Checks if a view is fully initialized.
-     * @return True if the view is fully initialized, false otherwise.
-     */
-    [[nodiscard]] explicit operator bool() const noexcept {
-        return handle() && internal::fully_initialized(filter);
-    }
-
-    /**
-     * @brief Checks if a view contains an entity.
-     * @param entt A valid identifier.
-     * @return True if the view contains the given entity, false otherwise.
-     */
-    [[nodiscard]] bool contains(const entity_type entt) const noexcept {
-        return handle() && handle()->contains(entt) && internal::none_of(filter, entt);
-    }
-
-    /**
-     * @brief Returns the component assigned to the given entity.
-     * @tparam Elem Type of the component to get.
-     * @param entt A valid identifier.
-     * @return The component assigned to the entity.
-     */
-    template<typename Elem>
-    [[nodiscard]] decltype(auto) get(const entity_type entt) const {
-        static_assert(std::is_same_v<std::remove_const_t<Elem>, typename Get::value_type>, "Invalid component type");
-        return get<0>(entt);
-    }
-
-    /**
-     * @brief Returns the component assigned to the given entity.
-     * @tparam Index Index of the component to get.
-     * @param entt A valid identifier.
-     * @return The component assigned to the entity.
-     */
-    template<std::size_t... Index>
-    [[nodiscard]] decltype(auto) get(const entity_type entt) const {
-        if constexpr(sizeof...(Index) == 0) {
-            return std::get<0>(pools)->get_as_tuple(entt);
-        } else {
-            return std::get<Index...>(pools)->get(entt);
-        }
-    }
-
-    /**
-     * @brief Iterates entities and components and applies the given function
-     * object to them.
-     *
-     * The signature of the function must be equivalent to one of the following
-     * (non-empty types only, constness as requested):
-     *
-     * @code{.cpp}
-     * void(const entity_type, Type &...);
-     * void(Type &...);
-     * @endcode
-     *
-     * @tparam Func Type of the function object to invoke.
-     * @param func A valid function object.
-     */
-    template<typename Func>
-    void each(Func func) const {
-        if(auto *view = storage<0>(); view) {
-            for(auto curr: view->each()) {
-                if(const auto entt = std::get<0>(curr); (!Get::traits_type::in_place_delete || (entt != tombstone)) && internal::none_of(filter, entt)) {
-                    if constexpr(is_applicable_v<Func, decltype(curr)>) {
-                        std::apply(func, curr);
-                    } else {
-                        func(std::get<1>(curr));
-                    }
-                }
-            }
-        }
-    }
+        if(view) {
+            const auto len = (view->policy() == deletion_policy::swap_only) ? view->free_list() : view->size();
+            const auto check_set = opaque_check_set();
+            const auto it = view->end();
 
-    /**
-     * @brief Returns an iterable object to use to _visit_ a view.
-     *
-     * The iterable object returns a tuple that contains the current entity and
-     * a set of references to its non-empty components. The _constness_ of the
-     * components is as requested.
-     *
-     * @return An iterable object to use to _visit_ the view.
-     */
-    [[nodiscard]] iterable each() const noexcept {
-        if(auto *view = storage<0>(); view) {
-            auto elem = view->each();
-            iterator from{elem.begin().base(), elem.end().base(), std::array<const common_type *, 0u>{}, filter};
-            iterator to{elem.end().base(), elem.end().base(), std::array<const common_type *, 0u>{}, filter};
-            return iterable{internal::extended_view_iterator{from, pools}, internal::extended_view_iterator{to, pools}};
+            return {internal::extended_view_iterator{iterator{it - len, it, check_set, filter}, pools}, internal::extended_view_iterator{iterator{it, it, check_set, filter}, pools}};
         }
 
-        return {};
+        return iterable{};
     }
 
     /**
@@ -843,12 +558,13 @@ public:
         return internal::view_pack(
             std::tuple_cat(pools, other.pools),
             std::tuple_cat(internal::filter_as_tuple<Exclude...>(filter, std::index_sequence_for<Exclude...>{}), internal::filter_as_tuple<OExclude...>(other.filter, std::index_sequence_for<OExclude...>{})),
-            std::index_sequence_for<Get, OGet..., Exclude..., OExclude...>{});
+            std::index_sequence_for<Get..., OGet..., Exclude..., OExclude...>{});
     }
 
 private:
-    std::tuple<Get *> pools;
+    std::tuple<Get *...> pools;
     std::array<const common_type *, sizeof...(Exclude)> filter;
+    const common_type *view;
 };
 
 /**