Skip to content

Commit

Permalink
#856 implement pair support for emplace
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Nov 29, 2022
1 parent 2067b36 commit 75c43f2
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 43 deletions.
8 changes: 0 additions & 8 deletions include/flecs/addons/cpp/impl/world.hpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@
namespace flecs namespace flecs
{ {


// emplace for T(flecs::entity, Args...)
template <typename T, typename ... Args, if_t<
std::is_constructible<actual_type_t<T>, flecs::entity, Args...>::value >>
inline void emplace(world_t *world, id_t entity, Args&&... args) {
flecs::entity self(world, entity);
emplace<T>(world, entity, self, FLECS_FWD(args)...);
}

inline void world::init_builtin_components() { inline void world::init_builtin_components() {
component<Component>("flecs::core::Component"); component<Component>("flecs::core::Component");
component<Identifier>("flecs::core::Identifier"); component<Identifier>("flecs::core::Identifier");
Expand Down
32 changes: 29 additions & 3 deletions include/flecs/addons/cpp/mixins/entity/builder.hpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ struct entity_builder : entity_view {
this->override<T>(); this->override<T>();


flecs::emplace<T>(this->m_world, this->m_id, flecs::emplace<T>(this->m_world, this->m_id,
FLECS_FWD(args)...); _::cpp_type<T>::id(this->m_world), FLECS_FWD(args)...);


return to_base(); return to_base();
} }
Expand Down Expand Up @@ -736,9 +736,35 @@ struct entity_builder : entity_view {
* @tparam T the component to emplace * @tparam T the component to emplace
* @param args The arguments to pass to the constructor of T * @param args The arguments to pass to the constructor of T
*/ */
template <typename T, typename ... Args> template<typename T, typename ... Args, typename A = actual_type_t<T>>
Self& emplace(Args&&... args) { Self& emplace(Args&&... args) {
flecs::emplace<T>(this->m_world, this->m_id, flecs::emplace<A>(this->m_world, this->m_id,
_::cpp_type<T>::id(this->m_world), FLECS_FWD(args)...);
return to_base();
}

template <typename First, typename Second, typename ... Args, typename P = pair<First, Second>,
typename A = actual_type_t<P>, if_not_t< flecs::is_pair<First>::value> = 0>
Self& emplace(Args&&... args) {
flecs::emplace<A>(this->m_world, this->m_id,
ecs_pair(_::cpp_type<First>::id(this->m_world),
_::cpp_type<Second>::id(this->m_world)),
FLECS_FWD(args)...);
return to_base();
}

template <typename First, typename ... Args>
Self& emplace_first(flecs::entity_t second, Args&&... args) {
flecs::emplace<First>(this->m_world, this->m_id,
ecs_pair(_::cpp_type<First>::id(this->m_world), second),
FLECS_FWD(args)...);
return to_base();
}

template <typename Second, typename ... Args>
Self& emplace_second(flecs::entity_t first, Args&&... args) {
flecs::emplace<Second>(this->m_world, this->m_id,
ecs_pair(first, _::cpp_type<Second>::id(this->m_world)),
FLECS_FWD(args)...); FLECS_FWD(args)...);
return to_base(); return to_base();
} }
Expand Down
20 changes: 7 additions & 13 deletions include/flecs/addons/cpp/world.hpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace flecs


// set(T&&), T = constructible // set(T&&), T = constructible
template <typename T, if_t< is_flecs_constructible<T>::value > = 0> template <typename T, if_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, entity_t entity, T&& value, ecs_id_t id) { inline void set(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL); ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);


T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id)); T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id));
Expand All @@ -17,7 +17,7 @@ inline void set(world_t *world, entity_t entity, T&& value, ecs_id_t id) {


// set(const T&), T = constructible // set(const T&), T = constructible
template <typename T, if_t< is_flecs_constructible<T>::value > = 0> template <typename T, if_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, entity_t entity, const T& value, ecs_id_t id) { inline void set(world_t *world, flecs::entity_t entity, const T& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL); ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);


T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id)); T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id));
Expand All @@ -28,7 +28,7 @@ inline void set(world_t *world, entity_t entity, const T& value, ecs_id_t id) {


// set(T&&), T = not constructible // set(T&&), T = not constructible
template <typename T, if_not_t< is_flecs_constructible<T>::value > = 0> template <typename T, if_not_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, entity_t entity, T&& value, ecs_id_t id) { inline void set(world_t *world, flecs::entity_t entity, T&& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL); ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);


T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id)); T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id));
Expand All @@ -40,7 +40,7 @@ inline void set(world_t *world, entity_t entity, T&& value, ecs_id_t id) {


// set(const T&), T = not constructible // set(const T&), T = not constructible
template <typename T, if_not_t< is_flecs_constructible<T>::value > = 0> template <typename T, if_not_t< is_flecs_constructible<T>::value > = 0>
inline void set(world_t *world, id_t entity, const T& value, id_t id) { inline void set(world_t *world, flecs::entity_t entity, const T& value, flecs::id_t id) {
ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL); ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);


T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id)); T& dst = *static_cast<T*>(ecs_get_mut_id(world, entity, id));
Expand All @@ -53,9 +53,7 @@ inline void set(world_t *world, id_t entity, const T& value, id_t id) {
template <typename T, typename ... Args, if_t< template <typename T, typename ... Args, if_t<
std::is_constructible<actual_type_t<T>, Args...>::value || std::is_constructible<actual_type_t<T>, Args...>::value ||
std::is_default_constructible<actual_type_t<T>>::value > = 0> std::is_default_constructible<actual_type_t<T>>::value > = 0>
inline void emplace(world_t *world, id_t entity, Args&&... args) { inline void emplace(world_t *world, flecs::entity_t entity, flecs::id_t id, Args&&... args) {
id_t id = _::cpp_type<T>::id(world);

ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL); ecs_assert(_::cpp_type<T>::size() != 0, ECS_INVALID_PARAMETER, NULL);
T& dst = *static_cast<T*>(ecs_emplace_id(world, entity, id)); T& dst = *static_cast<T*>(ecs_emplace_id(world, entity, id));


Expand All @@ -64,11 +62,6 @@ inline void emplace(world_t *world, id_t entity, Args&&... args) {
ecs_modified_id(world, entity, id); ecs_modified_id(world, entity, id);
} }


// emplace for T(flecs::entity, Args...)
template <typename T, typename ... Args, if_t<
std::is_constructible<actual_type_t<T>, flecs::entity, Args...>::value > = 0>
inline void emplace(world_t *world, id_t entity, Args&&... args);

// set(T&&) // set(T&&)
template <typename T, typename A> template <typename T, typename A>
inline void set(world_t *world, entity_t entity, A&& value) { inline void set(world_t *world, entity_t entity, A&& value) {
Expand Down Expand Up @@ -529,7 +522,8 @@ struct world {


template <typename T, typename ... Args> template <typename T, typename ... Args>
void emplace(Args&&... args) const { void emplace(Args&&... args) const {
flecs::emplace<T>(m_world, _::cpp_type<T>::id(m_world), flecs::id_t component_id = _::cpp_type<T>::id(m_world);
flecs::emplace<T>(m_world, component_id, component_id,
FLECS_FWD(args)...); FLECS_FWD(args)...);
} }


Expand Down
5 changes: 4 additions & 1 deletion test/cpp_api/project.json
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@
"emplace_2", "emplace_2",
"emplace_after_add", "emplace_after_add",
"emplace_after_add_pair", "emplace_after_add_pair",
"emplace_w_self_ctor", "emplace_pair",
"emplace_pair_w_entity",
"emplace_pair_type",
"emplace_pair_second",
"get_generic", "get_generic",
"get_mut_generic", "get_mut_generic",
"get_generic_w_id", "get_generic_w_id",
Expand Down
66 changes: 52 additions & 14 deletions test/cpp_api/src/Entity.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -234,26 +234,64 @@ void Entity_emplace_after_add_pair() {
test_int(v->y, 40); test_int(v->y, 40);
} }


class SelfCtor { void Entity_emplace_pair() {
public: flecs::world ecs;
SelfCtor(flecs::entity e, int x, int y) : e_(e), x_(x), y_(y) { }


flecs::entity e_; auto e = ecs.entity()
int x_; .emplace<Position, Tag>(10.0f, 20.0f);
int y_;
}; test_assert((e.has<Position, Tag>()));

const Position *p = e.get<Position, Tag>();
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
}


void Entity_emplace_w_self_ctor() { void Entity_emplace_pair_w_entity() {
flecs::world ecs; flecs::world ecs;


auto tag = ecs.entity();

auto e = ecs.entity() auto e = ecs.entity()
.emplace<SelfCtor>(10, 20); .emplace_first<Position>(tag, 10.0f, 20.0f);


const SelfCtor *ptr = e.get<SelfCtor>(); test_assert((e.has<Position>(tag)));
test_assert(ptr != NULL);
test_int(ptr->x_, 10); const Position *p = e.get<Position>(tag);
test_int(ptr->y_, 20); test_assert(p != NULL);
test_assert(ptr->e_ == e); test_int(p->x, 10);
test_int(p->y, 20);
}

void Entity_emplace_pair_type() {
flecs::world ecs;

auto e = ecs.entity()
.emplace<flecs::pair<Position, Tag>>(10.0f, 20.0f);

test_assert((e.has<Position, Tag>()));

const Position *p = e.get<Position, Tag>();
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
}

void Entity_emplace_pair_second() {
flecs::world ecs;

auto tag = ecs.entity();

auto e = ecs.entity()
.emplace_second<Position>(tag, 10.0f, 20.0f);

test_assert((e.has_second<Position>(tag)));

const Position *p = e.get_second<Position>(tag);
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);
} }


void Entity_add_2() { void Entity_add_2() {
Expand Down
23 changes: 19 additions & 4 deletions test/cpp_api/src/main.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ void Entity_emplace(void);
void Entity_emplace_2(void); void Entity_emplace_2(void);
void Entity_emplace_after_add(void); void Entity_emplace_after_add(void);
void Entity_emplace_after_add_pair(void); void Entity_emplace_after_add_pair(void);
void Entity_emplace_w_self_ctor(void); void Entity_emplace_pair(void);
void Entity_emplace_pair_w_entity(void);
void Entity_emplace_pair_type(void);
void Entity_emplace_pair_second(void);
void Entity_get_generic(void); void Entity_get_generic(void);
void Entity_get_mut_generic(void); void Entity_get_mut_generic(void);
void Entity_get_generic_w_id(void); void Entity_get_generic_w_id(void);
Expand Down Expand Up @@ -1203,8 +1206,20 @@ bake_test_case Entity_testcases[] = {
Entity_emplace_after_add_pair Entity_emplace_after_add_pair
}, },
{ {
"emplace_w_self_ctor", "emplace_pair",
Entity_emplace_w_self_ctor Entity_emplace_pair
},
{
"emplace_pair_w_entity",
Entity_emplace_pair_w_entity
},
{
"emplace_pair_type",
Entity_emplace_pair_type
},
{
"emplace_pair_second",
Entity_emplace_pair_second
}, },
{ {
"get_generic", "get_generic",
Expand Down Expand Up @@ -5286,7 +5301,7 @@ static bake_test_suite suites[] = {
"Entity", "Entity",
NULL, NULL,
NULL, NULL,
223, 226,
Entity_testcases Entity_testcases
}, },
{ {
Expand Down

0 comments on commit 75c43f2

Please sign in to comment.