Skip to content

Commit

Permalink
#124 allow enum constants to be used with other component types
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Mar 23, 2022
1 parent 24c5f5b commit 98e722f
Show file tree
Hide file tree
Showing 6 changed files with 377 additions and 128 deletions.
196 changes: 133 additions & 63 deletions flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16495,14 +16495,27 @@ struct entity_view : public id {
* @tparam R the relation type.
* @param object the object.
*/
template<typename R>
const R* get(flecs::id_t object) const {
template<typename R, typename O, if_not_t< is_enum<O>::value> = 0>
const R* get(O object) const {
auto comp_id = _::cpp_type<R>::id(m_world);
ecs_assert(_::cpp_type<R>::size() != 0, ECS_INVALID_PARAMETER, NULL);
return static_cast<const R*>(
ecs_get_id(m_world, m_id, ecs_pair(comp_id, object)));
}

/** Get a pair.
* This operation gets the value for a pair from the entity.
*
* @tparam R the relation type.
* @param constant the enum constant.
*/
template<typename R, typename O, if_t< is_enum<O>::value> = 0>
const R* get(O constant) const {
const auto& et = enum_type<O>(this->m_world);
flecs::entity_t object = et.entity(constant);
return get<R>(object);
}

/** Get component value (untyped).
*
* @param comp The component to get.
Expand Down Expand Up @@ -16683,16 +16696,29 @@ struct entity_view : public id {

/** Check if entity has the provided pair.
*
* @tparam Relation The relation type.
* @tparam R The relation type.
* @param object The object.
* @return True if the entity has the provided component, false otherwise.
*/
template <typename Relation>
bool has(flecs::id_t object) const {
auto comp_id = _::cpp_type<Relation>::id(m_world);
template<typename R, typename O, if_not_t< is_enum<O>::value > = 0>
bool has(O object) const {
auto comp_id = _::cpp_type<R>::id(m_world);
return ecs_has_id(m_world, m_id, ecs_pair(comp_id, object));
}

/** Check if entity has the provided pair.
*
* @tparam R The relation type.
* @param value The enum constant.
* @return True if the entity has the provided component, false otherwise.
*/
template<typename R, typename E, if_t< is_enum<E>::value > = 0>
bool has(E value) const {
const auto& et = enum_type<E>(this->m_world);
flecs::entity_t object = et.entity(value);
return has<R>(object);
}

/** Check if entity has the provided pair.
*
* @param relation The relation.
Expand Down Expand Up @@ -16951,8 +16977,8 @@ struct entity_builder : entity_view {
/** Add a pair.
* This operation adds a pair to the entity.
*
* @param relation The relation id.
* @param object The object id.
* @param relation The relation.
* @param object The object.
*/
Self& add(entity_t relation, entity_t object) {
ecs_add_pair(this->m_world, this->m_id, relation, object);
Expand All @@ -16962,8 +16988,8 @@ struct entity_builder : entity_view {
/** Add a pair.
* This operation adds a pair to the entity.
*
* @tparam R the relation type.
* @tparam O the object type.
* @tparam R The relation type
* @tparam O The object type.
*/
template<typename R, typename O>
Self& add() {
Expand All @@ -16973,27 +16999,43 @@ struct entity_builder : entity_view {
/** Add a pair.
* This operation adds a pair to the entity.
*
* @tparam R the relation type.
* @param object the object type.
* @tparam R The relation type
* @param object The object.
*/
template<typename R>
Self& add(entity_t object) {
template<typename R, typename O, if_not_t< is_enum<O>::value > = 0>
Self& add(O object) {
flecs_static_assert(is_flecs_constructible<R>::value,
"cannot default construct type: add T::T() or use emplace<T>()");
"cannot default construct type: add T::T() or use emplace<T>()");
return this->add(_::cpp_type<R>::id(this->m_world), object);
}

/** Add a pair.
* This operation adds a pair to the entity that consists out of a tag
* combined with an enum constant.
*
* @tparam R The relation type
* @param constant the enum constant.
*/
template<typename R, typename O, if_t< is_enum<O>::value > = 0>
Self& add(O constant) {
flecs_static_assert(is_flecs_constructible<R>::value,
"cannot default construct type: add T::T() or use emplace<T>()");
const auto& et = enum_type<O>(this->m_world);
flecs::entity_t object = et.entity(constant);
return this->add<R>(object);
}

/** Shortcut for add(IsA, obj).
*
* @param object the object id.
* @param object The object.
*/
Self& is_a(entity_t object) {
return this->add(flecs::IsA, object);
}

/** Shortcut for add(IsA, obj).
*
* @tparam T the type associated with the object.
* @tparam T the type associated with the O.
*/
template <typename T>
Self& is_a() {
Expand All @@ -17002,27 +17044,27 @@ struct entity_builder : entity_view {

/** Shortcut for add(ChildOf, obj).
*
* @param object the object id.
* @param object The object.
*/
Self& child_of(entity_t object) {
return this->add(flecs::ChildOf, object);
}

/** Shortcut for add(ChildOf, obj).
*
* @tparam T the type associated with the object.
* @tparam T the type associated with the O.
*/
template <typename T>
Self& child_of() {
return this->add(flecs::ChildOf, _::cpp_type<T>::id(this->m_world));
}

/** Add a pair with object type.
* This operation adds a pair to the entity. The relation part of the pair
/** Add a pair with O type.
* This operation adds a pair to the entity. The R part of the pair
* should not be a component.
*
* @param relation the relation type.
* @tparam O the object type.
* @param relation The relation.
* @tparam O The object type.
*/
template<typename O>
Self& add_w_object(entity_t relation) {
Expand Down Expand Up @@ -17053,8 +17095,8 @@ struct entity_builder : entity_view {
/** Remove a pair.
* This operation removes a pair from the entity.
*
* @param relation The relation id.
* @param object The object id.
* @param relation The relation.
* @param object The object.
*/
Self& remove(entity_t relation, entity_t object) {
ecs_remove_pair(this->m_world, this->m_id, relation, object);
Expand All @@ -17064,34 +17106,47 @@ struct entity_builder : entity_view {
/** Removes a pair.
* This operation removes a pair from the entity.
*
* @tparam Relation the relation type.
* @tparam Object the object type.
* @tparam R The relation type
* @tparam O The object type.
*/
template<typename Relation, typename Object>
template<typename R, typename O>
Self& remove() {
return this->remove<Relation>(_::cpp_type<Object>::id(this->m_world));
return this->remove<R>(_::cpp_type<O>::id(this->m_world));
}

/** Remove a pair.
* This operation adds a pair to the entity.
*
* @tparam Relation the relation type.
* @param object the object type.
* @tparam R The relation type
* @param object The object.
*/
template<typename R, typename O, if_not_t< is_enum<O>::value > = 0>
Self& remove(O object) {
return this->remove(_::cpp_type<R>::id(this->m_world), object);
}

/** Remove a pair.
* This operation adds a pair to the entity.
*
* @tparam R The relation type
* @param constant the enum constant.
*/
template<typename Relation>
Self& remove(entity_t object) {
return this->remove(_::cpp_type<Relation>::id(this->m_world), object);
template<typename R, typename O, if_t< is_enum<O>::value > = 0>
Self& remove(O constant) {
const auto& et = enum_type<O>(this->m_world);
flecs::entity_t object = et.entity(constant);
return this->remove<R>(object);
}

/** Removes a pair with object type.
/** Removes a pair with O type.
* This operation removes a pair from the entity.
*
* @param relation the relation type.
* @tparam Object the object type.
* @param relation The relation.
* @tparam O The object type.
*/
template<typename Object>
template<typename O>
Self& remove_w_object(entity_t relation) {
return this->remove(relation, _::cpp_type<Object>::id(this->m_world));
return this->remove(relation, _::cpp_type<O>::id(this->m_world));
}

/** Add owned flag for component (forces ownership when instantiating)
Expand Down Expand Up @@ -17133,7 +17188,7 @@ struct entity_builder : entity_view {
this->override<T>();
this->set<T>(val);
return to_base();
}
}

/** Add a switch to an entity by id.
* The switch entity must be a type, that is it must have the EcsType
Expand Down Expand Up @@ -17244,10 +17299,10 @@ struct entity_builder : entity_view {
*/
template <typename E, if_t< is_enum<E>::value > = 0>
Self& add(E value) {
flecs::entity_t r = _::cpp_type<E>::id(this->m_world);
flecs::entity_t relation = _::cpp_type<E>::id(this->m_world);
const auto& et = enum_type<E>(this->m_world);
flecs::entity_t o = et.entity(value);
return this->add(r, o);
flecs::entity_t object = et.entity(value);
return this->add(relation, object);
}

/** Remove pair for enum.
Expand All @@ -17257,8 +17312,8 @@ struct entity_builder : entity_view {
*/
template <typename E, if_t< is_enum<E>::value > = 0>
Self& remove() {
flecs::entity_t r = _::cpp_type<E>::id(this->m_world);
return this->remove(r, flecs::Wildcard);
flecs::entity_t relation = _::cpp_type<E>::id(this->m_world);
return this->remove(relation, flecs::Wildcard);
}

/** Enable an entity.
Expand Down Expand Up @@ -17367,11 +17422,11 @@ struct entity_builder : entity_view {
}

/** Set a pair for an entity.
* This operation sets the pair value, and uses the relation as type. If the
* This operation sets the pair value, and uses the R as type. If the
* entity did not yet have the pair, it will be added.
*
* @tparam R The relation part of the pair.
* @tparam O The object part of the pair.
* @tparam R The relation type.
* @tparam O The object type.
* @param value The value to set.
*/
template <typename R, typename O, typename P = pair<R, O>,
Expand All @@ -17382,27 +17437,42 @@ struct entity_builder : entity_view {
}

/** Set a pair for an entity.
* This operation sets the pair value, and uses the relation as type. If the
* This operation sets the pair value, and uses the R as type. If the
* entity did not yet have the pair, it will be added.
*
* @tparam R The relation part of the pair.
* @param object The object part of the pair.
* @tparam R The relation type.
* @param object The object.
* @param value The value to set.
*/
template <typename R>
Self& set(entity_t object, const R& value) {
template <typename R, typename O, if_not_t< is_enum<O>::value > = 0>
Self& set(O object, const R& value) {
auto relation = _::cpp_type<R>::id(this->m_world);
flecs::set(this->m_world, this->m_id, value,
ecs_pair(relation, object));
return to_base();
}

/** Set a pair for an entity.
* This operation sets the pair value, and uses the relation as type. If the
* This operation sets the pair value, and uses the R as type. If the
* entity did not yet have the pair, it will be added.
*
* @tparam R The relation type.
* @param constant The enum constant.
* @param value The value to set.
*/
template <typename R, typename O, if_t< is_enum<O>::value > = 0>
Self& set(O constant, const R& value) {
const auto& et = enum_type<O>(this->m_world);
flecs::entity_t object = et.entity(constant);
return set<R>(object, value);
}

/** Set a pair for an entity.
* This operation sets the pair value, and uses the R as type. If the
* entity did not yet have the pair, it will be added.
*
* @tparam O The object part of the pair.
* @param relation The relation part of the pair.
* @tparam O The object type.
* @param relation The relation.
* @param value The value to set.
*/
template <typename O>
Expand Down Expand Up @@ -17439,7 +17509,7 @@ struct entity_builder : entity_view {

/** Emplace component.
* Emplace constructs a component in the storage, which prevents calling the
* destructor on the object passed into the function.
* destructor on the O passed into the function.
*
* Emplace attempts the following signatures to construct the component:
* T{Args...}
Expand Down Expand Up @@ -17474,25 +17544,25 @@ struct entity_builder : entity_view {
return to_base();
}

/** Entities created in function will have (Relation, this)
/** Entities created in function will have (relation, this)
* This operation is thread safe.
*
* @tparam Relation The relation to use.
* @tparam R The R to use.
* @param func The function to call.
*/
template <typename Relation, typename Func>
template <typename R, typename Func>
Self& with(const Func& func) {
with(_::cpp_type<Relation>::id(this->m_world), func);
with(_::cpp_type<R>::id(this->m_world), func);
return to_base();
}

/** Entities created in function will have (relation, this)
*
* @param relation The relation to use.
* @param relation The relation.
* @param func The function to call.
*/
template <typename Func>
Self& with(id_t relation, const Func& func) {
Self& with(entity_t relation, const Func& func) {
ecs_id_t prev = ecs_set_with(this->m_world,
ecs_pair(relation, this->m_id));
func();
Expand Down
Loading

0 comments on commit 98e722f

Please sign in to comment.