Class iter

Synopsis

#include <include/flecs/cpp/column.hpp>

class iter : public iter_deprecated<iter>

Description

Class that enables iterating over table columns.

Mentioned in

Inheritance

Ancestors: iter_deprecated

Methods

iterConstruct iterator from C iterator object
begin
c_ptrObtain pointer to C iterator object
countNumber of entities to iterate over.
delta_system_timeReturn time elapsed since last time system was invoked.
delta_timeReturn delta_time of current frame.
end
entityObtain mutable handle to entity being iterated over.
inactive_table_countObtain the total number of inactive tables the query is matched with.
is_ownedReturns whether term is owned.
is_readonlyReturns whether term is readonly.
is_setReturns whether term is set.
paramAccess param field
systemObtain handle to current system.
table_column overloadObtain untyped pointer to table column.
table_column overloadObtain typed pointer to table column
table_countObtain the total number of tables the iterator will iterate over.
term overloadObtain term with const type
term overloadObtain term with non-const type
term overloadObtain unsafe term
term_countNumber of terms in iteator.
term_idObtain component/tag entity of term.
term_ownedObtain owned term
term_sharedObtain shared term
term_sizeSize of term data type.
term_sourceObtain term source (0 if self)
typeObtain type of the entities being iterated over.
worldObtain current world.
world_timeReturn total time passed in simulation.

Source

Lines 228-532 in include/flecs/cpp/column.hpp.

class iter : public iter_deprecated<iter> {
    using row_iterator = _::range_iterator<size_t>;
public:
    /** Construct iterator from C iterator object.
     * This operation is typically not invoked directly by the user.
     *
     * @param it Pointer to C iterator.
     */
    iter(const ecs_iter_t *it) : m_iter(it) { 
        m_begin = 0;
        m_end = static_cast<std::size_t>(it->count);
    }

    row_iterator begin() const {
        return row_iterator(m_begin);
    }

    row_iterator end() const {
        return row_iterator(m_end);
    }

    /** Obtain handle to current system. 
     */
    flecs::entity system() const;

    /** Obtain current world. 
     */
    flecs::world world() const;

    /** Obtain pointer to C iterator object
     */
    const flecs::iter_t* c_ptr() const {
        return m_iter;
    }

    /** Number of entities to iterate over. 
     */
    size_t count() const {
        return static_cast<size_t>(m_iter->count);
    }

    /** Return delta_time of current frame. 
     */
    FLECS_FLOAT delta_time() const {
        return m_iter->delta_time;
    }

    /** Return time elapsed since last time system was invoked.
     */
    FLECS_FLOAT delta_system_time() const {
        return m_iter->delta_system_time;
    }

    /** Return total time passed in simulation.
     */
    FLECS_FLOAT world_time() const {
        return m_iter->world_time;
    }

    /** Obtain type of the entities being iterated over.
     */
    flecs::type type() const;

    /** Access param field. 
     * The param field contains the value assigned to flecs::Context, or the
     * value passed to the `param` argument when invoking system::run.
     */
    void* param() {
        return m_iter->param;
    }

    /** Obtain mutable handle to entity being iterated over.
     *
     * @param row Row being iterated over.
     */
    flecs::entity entity(size_t row) const;

    /** Obtain the total number of inactive tables the query is matched with.
     */
    int32_t inactive_table_count() const {
        return m_iter->inactive_table_count;
    }

    /** Returns whether term is owned.
     * 
     * @param index The term index.
     */
    bool is_owned(int32_t index) const {
        return ecs_term_is_owned(m_iter, index);
    }    

    /** Returns whether term is set.
     * 
     * @param index The term index.
     */
    bool is_set(int32_t index) const {
        return ecs_term_w_size(m_iter, 0, index) != NULL;
    }

    /** Returns whether term is readonly.
     *
     * @param index The term index.
     */
    bool is_readonly(int32_t index) const {
        return ecs_term_is_readonly(m_iter, index);
    }

    /** Number of terms in iteator.
     */
    int32_t term_count() const {
        return m_iter->column_count;
    }

    /** Size of term data type.
     *
     * @param index The term id.
     */
    size_t term_size(int32_t index) const {
        return ecs_term_size(m_iter, index);
    }

    /** Obtain term source (0 if self)
     *
     * @param index The term index.
     */    
    flecs::entity term_source(int32_t index) const;

    /** Obtain component/tag entity of term.
     *
     * @param index The term index.
     */
    flecs::entity term_id(int32_t index) const;

    /** Obtain term with const type.
     * If the specified term index does not match with the provided type, the
     * function will assert.
     *
     * @tparam T Type of the term.
     * @param index The term index.
     * @return The term data.
     */
    template <typename T,
        typename std::enable_if<std::is_const<T>::value, void>::type* = nullptr>

    flecs::column<T> term(int32_t index) const {
        return get_term<T>(index);
    }

    /** Obtain term with non-const type.
     * If the specified term id does not match with the provided type or if
     * the term is readonly, the function will assert.
     *
     * @tparam T Type of the term.
     * @param index The term index.
     * @return The term data.
     */
    template <typename T,
        typename std::enable_if<
            std::is_const<T>::value == false, void>::type* = nullptr>

    flecs::column<T> term(int32_t index) const {
        ecs_assert(!ecs_term_is_readonly(m_iter, index), 
            ECS_COLUMN_ACCESS_VIOLATION, NULL);
        return get_term<T>(index);
    }

    /** Obtain unsafe term.
     * Unsafe terms are required when a system does not know at compile time
     * which component will be passed to it. 
     *
     * @param index The term index. 
     */
    flecs::unsafe_column term(int32_t index) const {
        return get_unsafe_term(index);
    }

    /** Obtain owned term.
     * Same as iter::term, but ensures that term is owned.
     *
     * @tparam Type of the term.
     * @param index The term index.
     * @return The term data.
     */
    template <typename T>
    flecs::column<T> term_owned(int32_t index) const {
        ecs_assert(!!ecs_is_owned(m_iter, index), ECS_COLUMN_IS_SHARED, NULL);
        return this->term<T>(index);
    }

    /** Obtain shared term.
     * Same as iter::term, but ensures that term is shared.
     *
     * @tparam Type of the term.
     * @param index The term index.
     * @return The component term.
     */
    template <typename T>
    const T& term_shared(int32_t index) const {
        ecs_assert(
            ecs_column_entity(m_iter, index) == 
                _::cpp_type<T>::id(m_iter->world), 
                    ECS_COLUMN_TYPE_MISMATCH, NULL);

        ecs_assert(!ecs_term_is_owned(m_iter, index), 
            ECS_COLUMN_IS_NOT_SHARED, NULL);

        return *static_cast<T*>(ecs_term_w_size(m_iter, sizeof(T), index));
    }

    /** Obtain the total number of tables the iterator will iterate over.
     */
    int32_t table_count() const {
        return m_iter->table_count;
    }

    /** Obtain untyped pointer to table column.
     *
     * @param table_column Id of table column (corresponds with location in table type).
     * @return Pointer to table column.
     */
    void* table_column(int32_t col) const {
        return ecs_iter_column_w_size(m_iter, 0, col);
    }

    /** Obtain typed pointer to table column.
     * If the table does not contain a column with the specified type, the
     * function will assert.
     *
     * @tparam T Type of the table column.
     */
    template <typename T>
    flecs::column<T> table_column() const {
        auto col = ecs_iter_find_column(m_iter, _::cpp_type<T>::id());
        ecs_assert(col != -1, ECS_INVALID_PARAMETER, NULL);

        return flecs::column<T>(static_cast<T*>(ecs_iter_column_w_size(m_iter, 
            sizeof(T), col)), static_cast<std::size_t>(m_iter->count), false);
    }

private:
    /* Get term, check if correct type is used */
    template <typename T>
    flecs::column<T> get_term(int32_t index) const {

#ifndef NDEBUG
        ecs_entity_t term_id = ecs_term_id(m_iter, index);
        ecs_assert(term_id & ECS_PAIR || term_id & ECS_SWITCH || 
            term_id & ECS_CASE ||
            term_id == _::cpp_type<T>::id(m_iter->world), 
            ECS_COLUMN_TYPE_MISMATCH, NULL);
#endif

        size_t count;
        bool is_shared = !ecs_term_is_owned(m_iter, index);

        /* If a shared column is retrieved with 'column', there will only be a
         * single value. Ensure that the application does not accidentally read
         * out of bounds. */
        if (is_shared) {
            count = 1;
        } else {
            /* If column is owned, there will be as many values as there are
             * entities. */
            count = static_cast<size_t>(m_iter->count);
        }

        return flecs::column<T>(
            static_cast<T*>(ecs_term_w_size(m_iter, sizeof(T), index)), 
            count, is_shared);
    } 

    flecs::unsafe_column get_unsafe_term(int32_t index) const {
        size_t count;
        size_t size = ecs_column_size(m_iter, index);
        bool is_shared = !ecs_term_is_owned(m_iter, index);

        /* If a shared column is retrieved with 'column', there will only be a
         * single value. Ensure that the application does not accidentally read
         * out of bounds. */
        if (is_shared) {
            count = 1;
        } else {
            /* If column is owned, there will be as many values as there are
             * entities. */
            count = static_cast<size_t>(m_iter->count);
        }

        return flecs::unsafe_column(
            ecs_column_w_size(m_iter, 0, index), size, count, is_shared);
    }       

    /* Get single field, check if correct type is used */
    template <typename T>
    T& get_element(int32_t index, int32_t row) const {
        ecs_assert(
            ecs_term_id(m_iter, index) == _::cpp_type<T>::id(m_iter->world),
                ECS_COLUMN_TYPE_MISMATCH, NULL);
        return *static_cast<T*>(
            ecs_element_w_size(m_iter, sizeof(T), index, row));
    }       

    const flecs::iter_t *m_iter;
    std::size_t m_begin;
    std::size_t m_end;
};