Class basic_view< Entity, get_t< Component >, exclude_t<>, std::void_t< std::enable_if_t<!component_traits< std::remove_const_t< Component > >::in_place_delete > > >

Synopsis

#include <src/entt/entity/view.hpp>

template<typename Entity, typename Component>
class basic_view<Entity, get_t<Component>, exclude_t<>, std::void_t<std::enable_if_t<!component_traits<std::remove_const_t<Component>>::in_place_delete>>>

Description

Single component view specialization.

Single component views are specialized in order to get a boost in terms of performance. This kind of views can access the underlying data structure directly and avoid superfluous checks.

Important

Iterators aren't invalidated if:

  • New instances of the given component are created and assigned to entities.
  • The entity currently pointed is modified (as an example, the given component is removed from the entity to which the iterator points).
  • The entity currently pointed is destroyed.

In all other cases, modifying the pool iterated by the view in any way invalidates all the iterators and using them results in undefined behavior.

Template Parameters

Entity - A valid entity type (see entt_traits for more details).

Component - Type of component iterated by the view.

Methods

backReturns the last entity of the view, if any.
basic_view overloadDefault constructor to use to create empty, invalid views.
basic_view overloadConstructs a single-type view from a storage class.
beginReturns an iterator to the first entity of the view.
containsChecks if a view contains an entity.
each overloadIterates entities and components and applies the given function object to them.
each overloadReturns an iterable object to use to visit a view.
emptyChecks whether a view is empty.
endReturns an iterator that is past the last entity of the view.
findFinds an entity.
frontReturns the first entity of the view, if any.
get overloadReturns the component assigned to the given entity.
handleReturns the leading storage of a view.
operator boolChecks if a view is properly initialized.
operator[] overloadReturns the identifier that occupies the given position.
operator[] overloadReturns the component assigned to the given entity.
operator|Combines two views in a more specific one (friend function).
rbeginReturns an iterator to the first entity of the reversed view.
rendReturns an iterator that is past the last entity of the reversed view.
sizeReturns the number of entities that have the given component.
storage overloadReturns the storage for a given component type.

Source

Lines 531-829 in src/entt/entity/view.hpp.

template<typename Entity, typename Component>
class basic_view<Entity, get_t<Component>, exclude_t<>, std::void_t<std::enable_if_t<!component_traits<std::remove_const_t<Component>>::in_place_delete>>> {
    template<typename, typename, typename, typename>
    friend class basic_view;

    using storage_type = constness_as_t<typename storage_traits<Entity, std::remove_const_t<Component>>::storage_type, Component>;

public:
    /*! @brief Underlying entity identifier. */
    using entity_type = Entity;
    /*! @brief Unsigned integer type. */
    using size_type = std::size_t;
    /*! @brief Common type among all storage types. */
    using base_type = typename storage_type::base_type;
    /*! @brief Random access iterator type. */
    using iterator = typename base_type::iterator;
    /*! @brief Reversed iterator type. */
    using reverse_iterator = typename base_type::reverse_iterator;
    /*! @brief Iterable view type. */
    using iterable = decltype(std::declval<storage_type>().each());

    /*! @brief Default constructor to use to create empty, invalid views. */
    basic_view() ENTT_NOEXCEPT
        : pools{},
          filter{},
          view{} {}

    /**
     * @brief Constructs a single-type view from a storage class.
     * @param ref The storage for the type to iterate.
     */
    basic_view(storage_type &ref) ENTT_NOEXCEPT
        : pools{&ref},
          filter{},
          view{&ref} {}

    /**
     * @brief Returns the leading storage of a view.
     * @return The leading storage of the view.
     */
    const base_type &handle() const ENTT_NOEXCEPT {
        return *view;
    }

    /**
     * @brief Returns the storage for a given component type.
     * @tparam Comp Type of component of which to return the storage.
     * @return The storage for the given component type.
     */
    template<typename Comp = Component>
    [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
        static_assert(std::is_same_v<Comp, Component>, "Invalid component type");
        return *std::get<0>(pools);
    }

    /**
     * @brief Returns the storage for a given component type.
     * @tparam Comp Index of component of which to return the storage.
     * @return The storage for the given component type.
     */
    template<std::size_t Comp>
    [[nodiscard]] decltype(auto) storage() const ENTT_NOEXCEPT {
        return *std::get<Comp>(pools);
    }

    /**
     * @brief Returns the number of entities that have the given component.
     * @return Number of entities that have the given component.
     */
    [[nodiscard]] size_type size() const ENTT_NOEXCEPT {
        return view->size();
    }

    /**
     * @brief Checks whether a view is empty.
     * @return True if the view is empty, false otherwise.
     */
    [[nodiscard]] bool empty() const ENTT_NOEXCEPT {
        return view->empty();
    }

    /**
     * @brief Returns an iterator to the first entity of the view.
     *
     * The returned iterator points 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 ENTT_NOEXCEPT {
        return view->begin();
    }

    /**
     * @brief Returns an iterator that is past the last entity of the view.
     *
     * The returned iterator points to the entity following the last entity of
     * the view. Attempting to dereference the returned iterator results in
     * undefined behavior.
     *
     * @return An iterator to the entity following the last entity of the view.
     */
    [[nodiscard]] iterator end() const ENTT_NOEXCEPT {
        return view->end();
    }

    /**
     * @brief Returns an iterator to the first entity of the reversed view.
     *
     * The returned iterator points to the first entity of the reversed view. If
     * the view is empty, the returned iterator will be equal to `rend()`.
     *
     * @return An iterator to the first entity of the reversed view.
     */
    [[nodiscard]] reverse_iterator rbegin() const ENTT_NOEXCEPT {
        return view->rbegin();
    }

    /**
     * @brief Returns an iterator that is past the last entity of the reversed
     * view.
     *
     * The returned iterator points to the entity following the last entity of
     * the reversed view. Attempting to dereference the returned iterator
     * results in undefined behavior.
     *
     * @return An iterator to the entity following the last entity of the
     * reversed view.
     */
    [[nodiscard]] reverse_iterator rend() const ENTT_NOEXCEPT {
        return view->rend();
    }

    /**
     * @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 ENTT_NOEXCEPT {
        return empty() ? null : *begin();
    }

    /**
     * @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 ENTT_NOEXCEPT {
        return empty() ? null : *rbegin();
    }

    /**
     * @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 ENTT_NOEXCEPT {
        return contains(entt) ? view->find(entt) : end();
    }

    /**
     * @brief Returns the identifier that occupies the given position.
     * @param pos Position of the element to return.
     * @return The identifier that occupies the given position.
     */
    [[nodiscard]] entity_type operator[](const size_type pos) const {
        return begin()[pos];
    }

    /**
     * @brief Returns the component assigned to the given entity.
     * @param entt A valid identifier.
     * @return The component assigned to the given entity.
     */
    [[nodiscard]] decltype(auto) operator[](const entity_type entt) const {
        return get<Component>(entt);
    }

    /**
     * @brief Checks if a view is properly initialized.
     * @return True if the view is properly initialized, false otherwise.
     */
    [[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
        return view != nullptr;
    }

    /**
     * @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 ENTT_NOEXCEPT {
        return view->contains(entt);
    }

    /**
     * @brief Returns the component assigned to the given entity.
     *
     * @warning
     * Attempting to use an entity that doesn't belong to the view results in
     * undefined behavior.
     *
     * @tparam Comp Type or index of the component to get.
     * @param entt A valid identifier.
     * @return The component assigned to the entity.
     */
    template<typename... Comp>
    [[nodiscard]] decltype(auto) get(const entity_type entt) const {
        ENTT_ASSERT(contains(entt), "View does not contain entity");

        if constexpr(sizeof...(Comp) == 0) {
            return std::get<0>(pools)->get_as_tuple(entt);
        } else {
            static_assert(std::is_same_v<Comp..., Component>, "Invalid component type");
            return std::get<0>(pools)->get(entt);
        }
    }

    /*! @copydoc get */
    template<std::size_t Comp>
    [[nodiscard]] decltype(auto) get(const entity_type entt) const {
        ENTT_ASSERT(contains(entt), "View does not contain entity");
        return std::get<0>(pools)->get(entt);
    }

    /**
     * @brief Iterates entities and components and applies the given function
     * object to them.
     *
     * The function object is invoked for each entity. It is provided with the
     * entity itself and a reference to the component if it's a non-empty one.
     * The _constness_ of the component is as requested.<br/>
     * The signature of the function must be equivalent to one of the following
     * forms:
     *
     * @code{.cpp}
     * void(const entity_type, Component &);
     * void(Component &);
     * @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 constexpr(is_applicable_v<Func, decltype(*each().begin())>) {
            for(const auto pack: each()) {
                std::apply(func, pack);
            }
        } else if constexpr(std::is_invocable_v<Func, Component &>) {
            for(auto &&component: *std::get<0>(pools)) {
                func(component);
            }
        } else if constexpr(std::is_invocable_v<Func, Entity>) {
            for(auto entity: *view) {
                func(entity);
            }
        } else {
            for(size_type pos{}, last = size(); pos < last; ++pos) {
                func();
            }
        }
    }

    /**
     * @brief Returns an iterable object to use to _visit_ a view.
     *
     * The iterable object returns a tuple that contains the current entity and
     * a reference to its component if it's a non-empty one. The _constness_ of
     * the component is as requested.
     *
     * @return An iterable object to use to _visit_ the view.
     */
    [[nodiscard]] iterable each() const ENTT_NOEXCEPT {
        return std::get<0>(pools)->each();
    }

    /**
     * @brief Combines two views in a _more specific_ one (friend function).
     * @tparam Get Component list of the view to combine with.
     * @tparam Excl Filter list of the view to combine with.
     * @param other The view to combine with.
     * @return A more specific view.
     */
    template<typename... Get, typename... Excl>
    [[nodiscard]] auto operator|(const basic_view<Entity, get_t<Get...>, exclude_t<Excl...>> &other) const ENTT_NOEXCEPT {
        using view_type = basic_view<Entity, get_t<Component, Get...>, exclude_t<Excl...>>;
        return std::make_from_tuple<view_type>(std::tuple_cat(
            std::forward_as_tuple(*std::get<0>(pools)),
            std::apply([](auto *...curr) { return std::forward_as_tuple(*curr...); }, other.pools),
            std::apply([](const auto *...curr) { return std::forward_as_tuple(static_cast<const typename view_type::template storage_type<Excl> &>(*curr)...); }, other.filter)));
    }

private:
    std::tuple<storage_type *> pools;
    std::array<const base_type *, 0u> filter;
    const base_type *view;
};





Add Discussion

Log in to comment