diff --git a/distr/flecs.h b/distr/flecs.h index 710303ee9b..75eb41798a 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -23286,11 +23286,11 @@ struct entity_view : public id { */ template::value> = 0> const First* get(Second second) const { - auto comp_id = _::type::id(world_); + auto first = _::type::id(world_); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( - ecs_get_id(world_, id_, ecs_pair(comp_id, second))); + ecs_get_id(world_, id_, ecs_pair(first, second))); } /** Get a pair. @@ -23383,6 +23383,10 @@ struct entity_view : public id { template const Second* get_second(flecs::entity_t first) const { auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( @@ -23452,11 +23456,11 @@ struct entity_view : public id { */ template::value> = 0> First* get_mut(Second second) const { - auto comp_id = _::type::id(world_); + auto first = _::type::id(world_); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( - ecs_get_mut_id(world_, id_, ecs_pair(comp_id, second))); + ecs_get_mut_id(world_, id_, ecs_pair(first, second))); } /** Get a mutable pair. @@ -23504,6 +23508,10 @@ struct entity_view : public id { template Second* get_mut_second(flecs::entity_t first) const { auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( @@ -24909,6 +24917,10 @@ struct entity_builder : entity_view { template const Self& set_second(entity_t first, const Second& value) const { auto second = _::type::id(this->world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); flecs::set(this->world_, this->id_, value, ecs_pair(first, second)); return to_base(); @@ -24925,6 +24937,10 @@ struct entity_builder : entity_view { template const Self& set_second(entity_t first, Second&& value) const { auto second = _::type::id(this->world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); flecs::set(this->world_, this->id_, FLECS_FWD(value), ecs_pair(first, second)); return to_base(); @@ -24994,16 +25010,22 @@ struct entity_builder : entity_view { template const Self& emplace_first(flecs::entity_t second, Args&&... args) const { + auto first = _::type::id(this->world_); flecs::emplace(this->world_, this->id_, - ecs_pair(_::type::id(this->world_), second), + ecs_pair(first, second), FLECS_FWD(args)...); return to_base(); } template const Self& emplace_second(flecs::entity_t first, Args&&... args) const { + auto second = _::type::id(this->world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); flecs::emplace(this->world_, this->id_, - ecs_pair(first, _::type::id(this->world_)), + ecs_pair(first, second), FLECS_FWD(args)...); return to_base(); } @@ -25551,11 +25573,11 @@ struct entity : entity_builder */ template First& ensure(entity_t second) const { - auto comp_id = _::type::id(world_); + auto first = _::type::id(world_); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return *static_cast( - ecs_ensure_id(world_, id_, ecs_pair(comp_id, second))); + ecs_ensure_id(world_, id_, ecs_pair(first, second))); } /** Get mutable pointer for a pair (untyped). @@ -25579,6 +25601,10 @@ struct entity : entity_builder template Second& ensure_second(entity_t first) const { auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return *static_cast( @@ -25678,20 +25704,23 @@ struct entity : entity_builder typename A = actual_type_t

> ref get_ref() const { return ref(world_, id_, - ecs_pair(_::type::id(world_), - _::type::id(world_))); + ecs_pair(_::type::id(world_), _::type::id(world_))); } template ref get_ref(flecs::entity_t second) const { - return ref(world_, id_, - ecs_pair(_::type::id(world_), second)); + auto first = _::type::id(world_); + return ref(world_, id_, ecs_pair(first, second)); } template ref get_ref_second(flecs::entity_t first) const { - return ref(world_, id_, - ecs_pair(first, _::type::id(world_))); + auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); + return ref(world_, id_, ecs_pair(first, second)); } /** Clear an entity. diff --git a/include/flecs/addons/cpp/entity.hpp b/include/flecs/addons/cpp/entity.hpp index a8cce4dffa..258a824414 100644 --- a/include/flecs/addons/cpp/entity.hpp +++ b/include/flecs/addons/cpp/entity.hpp @@ -138,11 +138,11 @@ struct entity : entity_builder */ template First& ensure(entity_t second) const { - auto comp_id = _::type::id(world_); + auto first = _::type::id(world_); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return *static_cast( - ecs_ensure_id(world_, id_, ecs_pair(comp_id, second))); + ecs_ensure_id(world_, id_, ecs_pair(first, second))); } /** Get mutable pointer for a pair (untyped). @@ -166,6 +166,10 @@ struct entity : entity_builder template Second& ensure_second(entity_t first) const { auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return *static_cast( @@ -265,20 +269,23 @@ struct entity : entity_builder typename A = actual_type_t

> ref get_ref() const { return ref(world_, id_, - ecs_pair(_::type::id(world_), - _::type::id(world_))); + ecs_pair(_::type::id(world_), _::type::id(world_))); } template ref get_ref(flecs::entity_t second) const { - return ref(world_, id_, - ecs_pair(_::type::id(world_), second)); + auto first = _::type::id(world_); + return ref(world_, id_, ecs_pair(first, second)); } template ref get_ref_second(flecs::entity_t first) const { - return ref(world_, id_, - ecs_pair(first, _::type::id(world_))); + auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); + return ref(world_, id_, ecs_pair(first, second)); } /** Clear an entity. diff --git a/include/flecs/addons/cpp/entity_view.hpp b/include/flecs/addons/cpp/entity_view.hpp index c54ea7dc9f..1ff2492ffc 100644 --- a/include/flecs/addons/cpp/entity_view.hpp +++ b/include/flecs/addons/cpp/entity_view.hpp @@ -300,11 +300,11 @@ struct entity_view : public id { */ template::value> = 0> const First* get(Second second) const { - auto comp_id = _::type::id(world_); + auto first = _::type::id(world_); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( - ecs_get_id(world_, id_, ecs_pair(comp_id, second))); + ecs_get_id(world_, id_, ecs_pair(first, second))); } /** Get a pair. @@ -397,6 +397,10 @@ struct entity_view : public id { template const Second* get_second(flecs::entity_t first) const { auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( @@ -466,11 +470,11 @@ struct entity_view : public id { */ template::value> = 0> First* get_mut(Second second) const { - auto comp_id = _::type::id(world_); + auto first = _::type::id(world_); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( - ecs_get_mut_id(world_, id_, ecs_pair(comp_id, second))); + ecs_get_mut_id(world_, id_, ecs_pair(first, second))); } /** Get a mutable pair. @@ -518,6 +522,10 @@ struct entity_view : public id { template Second* get_mut_second(flecs::entity_t first) const { auto second = _::type::id(world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); ecs_assert(_::type::size() != 0, ECS_INVALID_PARAMETER, "operation invalid for empty type"); return static_cast( diff --git a/include/flecs/addons/cpp/mixins/entity/builder.hpp b/include/flecs/addons/cpp/mixins/entity/builder.hpp index b963a97d52..31ec886c3d 100644 --- a/include/flecs/addons/cpp/mixins/entity/builder.hpp +++ b/include/flecs/addons/cpp/mixins/entity/builder.hpp @@ -808,6 +808,10 @@ struct entity_builder : entity_view { template const Self& set_second(entity_t first, const Second& value) const { auto second = _::type::id(this->world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); flecs::set(this->world_, this->id_, value, ecs_pair(first, second)); return to_base(); @@ -824,6 +828,10 @@ struct entity_builder : entity_view { template const Self& set_second(entity_t first, Second&& value) const { auto second = _::type::id(this->world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); flecs::set(this->world_, this->id_, FLECS_FWD(value), ecs_pair(first, second)); return to_base(); @@ -893,16 +901,22 @@ struct entity_builder : entity_view { template const Self& emplace_first(flecs::entity_t second, Args&&... args) const { + auto first = _::type::id(this->world_); flecs::emplace(this->world_, this->id_, - ecs_pair(_::type::id(this->world_), second), + ecs_pair(first, second), FLECS_FWD(args)...); return to_base(); } template const Self& emplace_second(flecs::entity_t first, Args&&... args) const { + auto second = _::type::id(this->world_); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second)) != NULL, + ECS_INVALID_PARAMETER, "pair is not a component"); + ecs_assert( ecs_get_type_info(world_, ecs_pair(first, second))->component == second, + ECS_INVALID_PARAMETER, "type of pair is not Second"); flecs::emplace(this->world_, this->id_, - ecs_pair(first, _::type::id(this->world_)), + ecs_pair(first, second), FLECS_FWD(args)...); return to_base(); } diff --git a/test/cpp/project.json b/test/cpp/project.json index 410e706f6f..9daea7dacc 100644 --- a/test/cpp/project.json +++ b/test/cpp/project.json @@ -291,7 +291,12 @@ "insert_2_w_1_sparse", "emplace_sparse", "override_sparse", - "delete_w_override_sparse" + "delete_w_override_sparse", + "get_pair_second_invalid_type", + "get_mut_pair_second_invalid_type", + "ensure_pair_second_invalid_type", + "set_pair_second_invalid_type", + "get_ref_pair_second_invalid_type" ] }, { "id": "Pairs", diff --git a/test/cpp/src/Entity.cpp b/test/cpp/src/Entity.cpp index 3315a1aaae..7b03b7c628 100644 --- a/test/cpp/src/Entity.cpp +++ b/test/cpp/src/Entity.cpp @@ -4808,3 +4808,58 @@ void Entity_delete_w_override_sparse(void) { e.destruct(); } + +void Entity_get_pair_second_invalid_type(void) { + install_test_abort(); + + flecs::world world; + + auto v = world.component(); + + test_expect_abort(); + world.entity().get_second(v); +} + +void Entity_get_mut_pair_second_invalid_type(void) { + install_test_abort(); + + flecs::world world; + + auto v = world.component(); + + test_expect_abort(); + world.entity().get_mut_second(v); +} + +void Entity_ensure_pair_second_invalid_type(void) { + install_test_abort(); + + flecs::world world; + + auto v = world.component(); + + test_expect_abort(); + world.entity().ensure_second(v); +} + +void Entity_set_pair_second_invalid_type(void) { + install_test_abort(); + + flecs::world world; + + auto v = world.component(); + + test_expect_abort(); + world.entity().set_second(v, {0}); +} + +void Entity_get_ref_pair_second_invalid_type(void) { + install_test_abort(); + + flecs::world world; + + auto v = world.component(); + + test_expect_abort(); + world.entity().get_ref_second(v); +} diff --git a/test/cpp/src/main.cpp b/test/cpp/src/main.cpp index 27f67b6e2f..ff7ec7baa4 100644 --- a/test/cpp/src/main.cpp +++ b/test/cpp/src/main.cpp @@ -284,6 +284,11 @@ void Entity_insert_2_w_1_sparse(void); void Entity_emplace_sparse(void); void Entity_override_sparse(void); void Entity_delete_w_override_sparse(void); +void Entity_get_pair_second_invalid_type(void); +void Entity_get_mut_pair_second_invalid_type(void); +void Entity_ensure_pair_second_invalid_type(void); +void Entity_set_pair_second_invalid_type(void); +void Entity_get_ref_pair_second_invalid_type(void); // Testsuite 'Pairs' void Pairs_add_component_pair(void); @@ -2482,6 +2487,26 @@ bake_test_case Entity_testcases[] = { { "delete_w_override_sparse", Entity_delete_w_override_sparse + }, + { + "get_pair_second_invalid_type", + Entity_get_pair_second_invalid_type + }, + { + "get_mut_pair_second_invalid_type", + Entity_get_mut_pair_second_invalid_type + }, + { + "ensure_pair_second_invalid_type", + Entity_ensure_pair_second_invalid_type + }, + { + "set_pair_second_invalid_type", + Entity_set_pair_second_invalid_type + }, + { + "get_ref_pair_second_invalid_type", + Entity_get_ref_pair_second_invalid_type } }; @@ -6792,7 +6817,7 @@ static bake_test_suite suites[] = { "Entity", NULL, NULL, - 271, + 276, Entity_testcases }, {