Class term_builder_i

Synopsis

#include <include/flecs/addons/cpp/builder.hpp>

template<typename Base>
class term_builder_i : public term_id_builder_i<Base>

Description

No description yet.

Inheritance

Ancestors: term_id_builder_i

Decsendents: filter_builder_i, trigger_builder_i

Methods

term_builder_i overload
expr
get_object
get_subject
id overload
inout overload

Mentioned in

object overload
oper overload

Mentioned in

populate_term_from_pack
predicate
role
set_term
singleton
subject overload

Mentioned in

type_to_inout overload
type_to_oper overload
world

Source

Lines 86-311 in include/flecs/addons/cpp/builder.hpp.

template<typename Base>
class term_builder_i : public term_id_builder_i<Base> {
public:
    term_builder_i() : m_term(nullptr) { }

    term_builder_i(ecs_term_t *term_ptr) { 
        set_term(term_ptr);
    }

    template<typename T>
    Base& id() {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->pred.entity = _::cpp_type<T>::id(world());
        return *this;
    }

    template<typename R, typename O>
    Base& id() {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->pred.entity = _::cpp_type<R>::id(world());
        m_term->args[1].entity = _::cpp_type<O>::id(world());
        return *this;
    }

    template<typename R>
    Base& id(id_t o) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->pred.entity = _::cpp_type<R>::id(world());
        m_term->args[1].entity = o;
        return *this;
    }    

    Base& id(id_t id) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->pred.entity = id;
        return *this;
    }

    Base& id(const flecs::type& type);

    Base& id(id_t r, id_t o) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->pred.entity = r;
        m_term->args[1].entity = o;
        return *this;
    }

    Base& expr(const char *expr) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        const char *ptr;
        if ((ptr = ecs_parse_term(world(), nullptr, expr, expr, m_term)) == nullptr) {
            ecs_abort(ECS_INVALID_PARAMETER, NULL);
        }

        // Should not have more than one term
        ecs_assert(ptr[0] == 0, ECS_INVALID_PARAMETER, NULL);
        return *this;
    }

    Base& predicate() {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        this->m_term_id = &m_term->pred;
        return *this;
    }

    Base& subject() {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        this->m_term_id = &m_term->args[0];
        return *this;
    }

    Base& object() {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        this->m_term_id = &m_term->args[1];
        return *this;
    }

    Base& subject(entity_t entity) {
        this->subject();
        this->m_term_id->entity = entity;
        return *this;
    }

    Base& object(entity_t entity) {
        this->object();
        this->m_term_id->entity = entity;
        return *this;
    }

    template<typename T>
    Base& subject() {
        this->subject();
        this->m_term_id->entity = _::cpp_type<T>::id(world());
        return *this;
    }

    template<typename T>
    Base& object() {
        this->object();
        this->m_term_id->entity = _::cpp_type<T>::id(world());
        return *this;
    }        

    Base& role(id_t role) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->role = role;
        return *this;
    }

    Base& inout(flecs::inout_kind_t inout) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->inout = static_cast<ecs_inout_kind_t>(inout);
        return *this;
    }

    Base& oper(flecs::oper_kind_t oper) {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        m_term->oper = static_cast<ecs_oper_kind_t>(oper);
        return *this;
    }

    Base& singleton() {
        ecs_assert(m_term != nullptr, ECS_INVALID_PARAMETER, NULL);
        ecs_assert(m_term->id || m_term->pred.entity, ECS_INVALID_PARAMETER, NULL);

        flecs::id_t pred = m_term->id;
        if (!pred) {
            pred = m_term->pred.entity;
        }

        ecs_assert(pred != 0, ECS_INVALID_PARAMETER, NULL);

        m_term->args[0].entity = pred;

        return *this;
    }

    flecs::id id() {
        return flecs::id(world(), m_term->id);
    }

    flecs::entity get_subject() {
        return flecs::entity(world(), m_term->args[0].entity);
    }

    flecs::entity get_object() {
        return flecs::entity(world(), m_term->args[1].entity);
    }

    flecs::inout_kind_t inout() {
        return static_cast<flecs::inout_kind_t>(m_term->inout);
    }

    flecs::oper_kind_t oper() {
        return static_cast<flecs::oper_kind_t>(m_term->oper);
    }

    ecs_term_t *m_term;

protected:
    virtual flecs::world_t* world() = 0;

    void set_term(ecs_term_t *term) {
        m_term = term;
        if (term) {
            this->m_term_id = &m_term->args[0]; // default to subject
        } else {
            this->m_term_id = nullptr;
        }
    }

    // A term can contain at most one component, but the parameter pack makes
    // the template parameter optional, which makes it easier to reuse the same
    // code for templated vs. non-templated terms.
    template <typename ... Components>
    void populate_term_from_pack() {
        flecs::array<flecs::id_t, sizeof...(Components)> ids ({
            (_::cpp_type<Components>::id(world()))...
        });

        flecs::array<flecs::inout_kind_t, sizeof...(Components)> inout_kinds ({
            (type_to_inout<Components>())...
        });

        flecs::array<flecs::oper_kind_t, sizeof...(Components)> oper_kinds ({
            (type_to_oper<Components>())...
        });

        size_t i = 0;
        for (auto the_id : ids) {
            this->id(the_id).inout(inout_kinds[i]).oper(oper_kinds[i]);
            i ++;
        }
    }

    template <typename T, if_t< is_const<T>::value > = 0>
    constexpr flecs::inout_kind_t type_to_inout() const {
        return flecs::In;
    }

    template <typename T, if_t< is_reference<T>::value > = 0>
    constexpr flecs::inout_kind_t type_to_inout() const {
        return flecs::Out;
    }

    template <typename T, if_not_t< 
        is_const<T>::value || is_reference<T>::value > = 0>
    constexpr flecs::inout_kind_t type_to_inout() const {
        return flecs::InOutDefault;
    }

    template <typename T, if_t< is_pointer<T>::value > = 0>
    constexpr flecs::oper_kind_t type_to_oper() const {
        return flecs::Optional;
    }

    template <typename T, if_not_t< is_pointer<T>::value > = 0>
    constexpr flecs::oper_kind_t type_to_oper() const {
        return flecs::And;
    } 

private:
    operator Base&() {
        return *static_cast<Base*>(this);
    }   
};