Class entity_builder

Synopsis

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

template <typename Base>
class entity_builder

Description

Fluent API for chaining entity operations This class contains entity operations that can be chained. For example, by using this class, an entity can be created like this:

flecs::entity e = flecs::entity(world) .add<Position>() .add<Velocity>();

Methods

add overloadAdd a component to an entity
add overloadAdd an entity to an entity
add overloadAdd a type to an entity
add overloadAdd a pair
add_case overloadAdd a switch to an entity by id
add_objectAdd a pair with object type
add_owned overloadAdd owned flag for component (forces ownership when instantiating)
add_switch overloadAdd a switch to an entity by id
add_switch overloadAdd a switch to an entity
disable overloadDisable an entity
disable overloadDisable a component
ECS_DEPRECATED
enable overloadEnable an entity
enable overloadEnable a component
patchPatch a component value
remove overloadRemove a component from an entity.
remove overloadRemove an entity from an entity.
remove overloadRemove a type from an entity
remove overloadRemove a pair
remove overloadRemoves a pair
remove_case overloadRemove a case from an entity by id
remove_case overloadRemove a switch from an entity by id
remove_objectRemoves a pair with object type
remove_switch overloadRemove a switch from an entity by id.
remove_switch overloadRemove a switch from an entity
set overloadSet a component for an entity
set overloadSet a pair for an entity
set_objectSet a pair for an entity
set_ownedSet value, add owned flag.

Source

Lines 631-1094 in include/flecs/cpp/entity.hpp.

template <typename Base>
class entity_builder {
    using base_type = const Base;
public:
    /** Add a component to an entity.
     * To ensure the component is initialized, it should have a constructor.
     * 
     * @tparam T the component type to add.
     */
    template <typename T>
    base_type& add() const {
        ecs_add_entity(world(), id(), _::cpp_type<T>::id(world()));
        return *base();
    }

    /** Add an entity to an entity.
     * Add an entity to the entity. This is typically used for tagging.
     *
     * @param entity The entity to add.
     */
    base_type& add(const entity_view& entity) const {
        ecs_add_entity(world(), id(), entity.id());
        return *base();
    }

    /** Add a type to an entity.
     * A type is a vector of component ids. This operation adds all components
     * in a single operation, and is a more efficient version of doing 
     * individual add operations.
     * 
     * @param type The type to add.
     */
    base_type& add(const type& type) const;

    /** Add a pair.
     * This operation adds a pair to the entity.
     *
     * @param relation The relation id.
     * @param object The object id.
     */
    base_type& add(const entity_view& relation, const entity_view& object) const {
        ecs_add_pair(world(), id(), relation.id(), object.id());
        return *base();
    }

    /** Add a pair.
     * This operation adds a pair to the entity.
     *
     * @tparam Relation the relation type.
     * @tparam Object the object type.
     */
    template<typename Relation, typename Object>
    base_type& add() const {
        return this->add<Relation>(_::cpp_type<Object>::id(world()));
    }

    /** Add a pair.
     * This operation adds a pair to the entity.
     *
     * @tparam Relation the relation type.
     * @param object the object type.
     */
    template<typename Relation>
    base_type& add(const entity_view& object) const {
        return this->add(_::cpp_type<Relation>::id(world()), object.id());
    }    

    /** Add a pair with object type.
     * This operation adds a pair to the entity. The relation part of the pair
     * should not be a component.
     *
     * @param relation the relation type.
     * @tparam Object the object type.
     */
    template<typename Object>
    base_type& add_object(const entity_view& relation) const {
        return this->add(relation.id(),  _::cpp_type<Object>::id(world()));
    }

    /** Remove a component from an entity.
     *
     * @tparam T the type of the component to remove.
     */
    template <typename T>
    base_type& remove() const {
        ecs_remove_entity(world(), id(), _::cpp_type<T>::id(world()));
        return *base();
    }

    /** Remove an entity from an entity.
     *
     * @param entity The entity to remove.
     */
    base_type& remove(const entity_view& entity) const {
        ecs_remove_entity(world(), id(), entity.id());
        return *base();
    }

    /** Remove a type from an entity.
     * A type is a vector of component ids. This operation adds all components
     * in a single operation, and is a more efficient version of doing 
     * individual add operations.
     *
     * @param type the type to remove.
     */
    base_type& remove(const type& type) const;

    /** Remove a pair.
     * This operation removes a pair from the entity.
     *
     * @param relation The relation id.
     * @param object The object id.
     */
    base_type& remove(const entity_view& relation, const entity_view& object) const {
        ecs_remove_pair(world(), id(), relation.id(), object.id());
        return *base();
    }

    /** Removes a pair.
     * This operation removes a pair from the entity.
     *
     * @tparam Relation the relation type.
     * @tparam Object the object type.
     */
    template<typename Relation, typename Object>
    base_type& remove() const {
        return this->remove<Relation>(_::cpp_type<Object>::id(world()));
    }

    /** Remove a pair.
     * This operation adds a pair to the entity.
     *
     * @tparam Relation the relation type.
     * @param object the object type.
     */
    template<typename Relation>
    base_type& remove(const entity_view& object) const {
        return this->remove(_::cpp_type<Relation>::id(world()), object.id());
    }  

    /** Removes a pair with object type.
     * This operation removes a pair from the entity.
     *
     * @param relation the relation type.
     * @tparam Object the object type.
     */
    template<typename Object>
    base_type& remove_object(const entity_view& relation) const {
        return this->remove(relation.id(), _::cpp_type<Object>::id(world()));
    }    

    /** Add owned flag for component (forces ownership when instantiating)
     *
     * @param entity The entity for which to add the OWNED flag
     */    
    base_type& add_owned(const entity_view& entity) const {
        ecs_add_entity(world(), id(), ECS_OWNED | entity.id());
        return *base();  
    }

    /** Add owned flag for component (forces ownership when instantiating)
     *
     * @tparam T The component for which to add the OWNED flag
     */    
    template <typename T>
    base_type& add_owned() const {
        ecs_add_entity(world(), id(), ECS_OWNED | _::cpp_type<T>::id(world()));
        return *base();  
    }

    ECS_DEPRECATED("use add_owned(flecs::entity e)")
    base_type& add_owned(const type& type) const;

    /** Set value, add owned flag.
     *
     * @tparam T The component to set and for which to add the OWNED flag
     */    
    template <typename T>
    base_type& set_owned(T&& val) const {
        this->add_owned<T>();
        this->set<T>(std::forward<T>(val));
        return *base();  
    }    

    /** Add a switch to an entity by id.
     * The switch entity must be a type, that is it must have the EcsType
     * component. Entities created with flecs::type are valid here.
     *
     * @param sw The switch entity id to add.
     */    
    base_type& add_switch(const entity_view& sw) const {
        ecs_add_entity(world(), id(), ECS_SWITCH | sw.id());
        return *base();  
    }

    /** Add a switch to an entity.
     * Any instance of flecs::type can be used as a switch.
     *
     * @param sw The switch to add.
     */     
    base_type& add_switch(const type& sw) const;

    /** Remove a switch from an entity by id.
     *
     * @param sw The switch entity id to remove.
     */    
    base_type& remove_switch(const entity_view& sw) const {
        ecs_remove_entity(world(), id(), ECS_SWITCH | sw.id());
        return *base();  
    }

    /** Remove a switch from an entity.
     * Any instance of flecs::type can be used as a switch.
     *
     * @param sw The switch to remove.
     */      
    base_type& remove_switch(const type& sw) const;

    /** Add a switch to an entity by id.
     * The case must belong to a switch that is already added to the entity.
     *
     * @param sw_case The case entity id to add.
     */    
    base_type& add_case(const entity_view& sw_case) const {
        ecs_add_entity(world(), id(), ECS_CASE | sw_case.id());
        return *base();
    }

    /** Add a switch to an entity by id.
     * The case must belong to a switch that is already added to the entity.
     *
     * @tparam T The case to add.
     */   
    template<typename T>
    base_type& add_case() const {
        return this->add_case(_::cpp_type<T>::id());
    }

    /** Remove a case from an entity by id.
     * The case must belong to a switch that is already added to the entity.
     *
     * @param sw_case The case entity id to remove.
     */    
    base_type& remove_case(const entity_view& sw_case) const {
        ecs_remove_entity(world(), id(), ECS_CASE | sw_case.id());
        return *base();  
    }

    /** Remove a switch from an entity by id.
     * The case must belong to a switch that is already added to the entity.
     *
     * @tparam T The case to remove.
     */   
    template<typename T>
    base_type& remove_case() const {
        return this->remove_case(_::cpp_type<T>::id());
    }

    /** Enable an entity.
     * Enabled entities are matched with systems and can be searched with
     * queries.
     */
    base_type& enable() const {
        ecs_enable(world(), id(), true);
        return *base();
    }

    /** Disable an entity.
     * Disabled entities are not matched with systems and cannot be searched 
     * with queries, unless explicitly specified in the query expression.
     */
    base_type& disable() const {
        ecs_enable(world(), id(), false);
        return *base();
    }

    /** Enable a component.
     * This sets the enabled bit for this component. If this is the first time
     * the component is enabled or disabled, the bitset is added.
     *
     * @tparam T The component to enable.
     */   
    template<typename T>
    base_type& enable() const {
        ecs_enable_component_w_entity(world(), id(), _::cpp_type<T>::id(), true);
        return *base();
    }  

    /** Disable a component.
     * This sets the enabled bit for this component. If this is the first time
     * the component is enabled or disabled, the bitset is added.
     *
     * @tparam T The component to enable.
     */   
    template<typename T>
    base_type& disable() const {
        ecs_enable_component_w_entity(world(), id(), _::cpp_type<T>::id(), false);
        return *base();
    }  

    /** Enable a component.
     * See enable<T>.
     *
     * @param component The component to enable.
     */   
    base_type& enable(const entity_view& component) const {
        ecs_enable_component_w_entity(world(), id(), component.id(), true);
        return *base();       
    }

    /** Disable a component.
     * See disable<T>.
     *
     * @param component The component to disable.
     */   
    base_type& disable(const entity_view& component) const {
        ecs_enable_component_w_entity(world(), id(), component.id(), false);
        return *base();       
    }

    /** Set a component for an entity.
     * This operation sets the component value. If the entity did not yet
     * have the component, it will be added.
     *
     * @tparam T The component to set.
     * @param value The value to assign to the component.
     */
    template <typename T>
    const base_type& set(const T& value) const {
        auto comp_id = _::cpp_type<T>::id(world());

        ecs_assert(_::cpp_type<T>::size() != 0, 
            ECS_INVALID_PARAMETER, NULL);

        T& ptr = *static_cast<T*>(
            ecs_get_mut_w_id(world(), id(), comp_id, NULL));

        ptr = std::move(value);

        ecs_modified_w_id(world(), id(), comp_id);

        return *base();
    }

    /** Set a component for an entity.
     * This operation sets the component value. If the entity did not yet
     * have the component, it will be added.
     *
     * @tparam T The component to set.
     * @param value The value to assign to the component.
     */
    template <typename T>
    const base_type& set(T&& value) const {
        auto comp_id = _::cpp_type<T>::id(world());

        ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);

        T& ptr = *static_cast<T*>(
            ecs_get_mut_w_id(world(), id(), comp_id, NULL));

        ptr = std::move(value);

        ecs_modified_w_id(world(), id(), comp_id);

        return *base();
    }

    /** Set a pair for an entity.
     * This operation sets the pair value, and uses the relation as type. If the
     * entity did not yet have the pair, it will be added.
     *
     * @tparam Relation The relation part of the pair.
     * @tparam Object The object part of the pair.
     * @param value The value to set.
     */
    template <typename Relation, typename Object>
    const base_type& set(const Relation& value) const {
        auto comp_id = _::cpp_type<Relation>::id(world());

        ecs_assert(_::cpp_type<Relation>::size() != 0, 
            ECS_INVALID_PARAMETER, NULL);

        ecs_set_ptr_w_entity(world(), id(),
            ecs_pair(comp_id, _::cpp_type<Object>::id(world())),
            sizeof(Relation), &value);

        return *base();
    }

    /** Set a pair for an entity.
     * This operation sets the pair value, and uses the relation as type. If the
     * entity did not yet have the pair, it will be added.
     *
     * @tparam Relation The relation part of the pair.
     * @param object The object part of the pair.
     * @param value The value to set.
     */
    template <typename Relation>
    const base_type& set(const entity_view& object, const Relation& value) const {
        auto comp_id = _::cpp_type<Relation>::id(world());

        ecs_assert(_::cpp_type<Relation>::size() != 0, 
            ECS_INVALID_PARAMETER, NULL);

        ecs_set_ptr_w_entity(world(), id(),
            ecs_pair(comp_id, object.id()),
            sizeof(Relation), &value);

        return *base();
    }    

    /** Set a pair for an entity.
     * This operation sets the pair value, and uses the relation as type. If the
     * entity did not yet have the pair, it will be added.
     *
     * @tparam Object The object part of the pair.
     * @param relation The relation part of the pair.
     * @param value The value to set.
     */
    template <typename Object>
    const base_type& set_object(const entity_view& relation, const Object& value) const {
        auto comp_id = _::cpp_type<Object>::id(world());

        ecs_assert(_::cpp_type<Object>::size() != 0, 
            ECS_INVALID_PARAMETER, NULL);

        ecs_set_ptr_w_entity(world(), id(),
            ecs_pair(relation.id(), comp_id),
            sizeof(Object), &value);

        return *base();
    }

    /** Patch a component value.
     * This operation allows an application to partially overwrite a component 
     * value. The operation invokes a function with a reference to the value to
     * write, and a boolean indicating if the component already existed.
     *
     * @tparam T The component to patch.
     * @param func The function invoked by this operation.
     */
    template <typename T, typename Func>
    const base_type& patch(const Func& func) const {
        auto comp_id = _::cpp_type<T>::id(world());

        ecs_assert(_::cpp_type<T>::size() != 0, 
            ECS_INVALID_PARAMETER, NULL);

        bool is_added;
        T *ptr = static_cast<T*>(ecs_get_mut_w_entity(
            world(), id(), comp_id, &is_added));
        ecs_assert(ptr != NULL, ECS_INTERNAL_ERROR, NULL);

        func(*ptr);
        ecs_modified_w_entity(world(), id(), comp_id);

        return *base();
    }

private:
    const Base* base() const { return static_cast<const Base*>(this); }
    flecs::world_t* world() const { return base()->world().c_ptr(); }
    flecs::entity_t id() const { return base()->id(); }
};