/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
third_party/flecs-3.2.11/test/cpp_api/src/ComponentLifecycle.cpp
1 823 строки
48 KB
Den163
Added flecs and glm to the repo
31 май 2024, 23:08
31 май 2024, 23:08
5d252b3
Код
Авторство
О чём код?
// Catch static asserts #define flecs_static_assert(cond, str)\ ecs_assert(cond, ECS_INVALID_OPERATION, str) #include <cpp_api.h> int Pod::ctor_invoked = 0; int Pod::dtor_invoked = 0; int Pod::copy_invoked = 0; int Pod::move_invoked = 0; int Pod::copy_ctor_invoked = 0; int Pod::move_ctor_invoked = 0; int CountNoDefaultCtor::ctor_invoked = 0; int CountNoDefaultCtor::dtor_invoked = 0; int CountNoDefaultCtor::copy_invoked = 0; int CountNoDefaultCtor::move_invoked = 0; int CountNoDefaultCtor::copy_ctor_invoked = 0; int CountNoDefaultCtor::move_ctor_invoked = 0; void ComponentLifecycle_ctor_on_add(void) { flecs::world world; world.component<Pod>(); auto e = world.entity().add<Pod>(); test_assert(e.id() != 0); test_assert(e.has<Pod>()); const Pod *pod = e.get<Pod>(); test_assert(pod != NULL); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); test_int(pod->value, 10); } void ComponentLifecycle_dtor_on_remove(void) { flecs::world world; world.component<Pod>(); auto e = world.entity().add<Pod>(); test_assert(e.id() != 0); test_assert(e.has<Pod>()); test_int(Pod::ctor_invoked, 1); e.remove<Pod>(); test_assert(!e.has<Pod>()); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 1); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); } void ComponentLifecycle_move_on_add(void) { flecs::world world; world.component<Pod>(); auto e = world.entity().add<Pod>(); test_assert(e.id() != 0); test_assert(e.has<Pod>()); const Pod *pod = e.get<Pod>(); test_assert(pod != NULL); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); test_int(Pod::copy_ctor_invoked, 0); test_int(Pod::move_ctor_invoked, 0); e.add<Position>(); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 1); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); test_int(Pod::copy_ctor_invoked, 0); test_int(Pod::move_ctor_invoked, 1); test_int(pod->value, 10); } void ComponentLifecycle_move_on_remove(void) { flecs::world world; world.component<Pod>(); auto e = world.entity().add<Position>().add<Pod>(); test_assert(e.id() != 0); test_assert(e.has<Pod>()); const Pod *pod = e.get<Pod>(); test_assert(pod != NULL); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); test_int(Pod::copy_ctor_invoked, 0); test_int(Pod::move_ctor_invoked, 0); e.remove<Position>(); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 1); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); test_int(Pod::copy_ctor_invoked, 0); test_int(Pod::move_ctor_invoked, 1); test_int(pod->value, 10); } void ComponentLifecycle_copy_on_set(void) { flecs::world world; world.component<Pod>(); auto e = world.entity(); test_assert(e.id() != 0); e.set<Pod>({20}); test_assert(e.has<Pod>()); test_int(Pod::ctor_invoked, 2); test_int(Pod::dtor_invoked, 1); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 1); } void ComponentLifecycle_copy_on_override(void) { flecs::world world; world.component<Pod>(); auto base = world.entity(); test_assert(base.id() != 0); base.set<Pod>({10}); test_int(Pod::ctor_invoked, 2); test_int(Pod::dtor_invoked, 1); test_int(Pod::copy_invoked, 0); Pod::ctor_invoked = 0; Pod::dtor_invoked = 0; Pod::copy_invoked = 0; Pod::move_invoked = 0; auto e = world.entity(); test_assert(e.id() != 0); e.add(flecs::IsA, base); test_int(Pod::ctor_invoked, 0); e.add<Pod>(); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_int(Pod::copy_invoked, 1); test_int(Pod::move_invoked, 0); const Pod *pod = e.get<Pod>(); test_assert(pod != NULL); test_int(pod->value, 10); } void ComponentLifecycle_struct_w_string_add(void) { flecs::world world; auto e = world.entity().add<Struct_w_string>(); test_assert(e.id() != 0); test_assert(e.has<Struct_w_string>()); const Struct_w_string *str = e.get<Struct_w_string>(); test_assert(str != NULL); test_assert(str->value == ""); } void ComponentLifecycle_struct_w_string_remove(void) { flecs::world world; auto e = world.entity().add<Struct_w_string>(); test_assert(e.id() != 0); test_assert(e.has<Struct_w_string>()); e.remove<Struct_w_string>(); test_assert(!e.has<Struct_w_string>()); } void ComponentLifecycle_struct_w_string_set(void) { flecs::world world; auto e = world.entity() .set<Struct_w_string>({"Hello World"}); test_assert(e.id() != 0); test_assert(e.has<Struct_w_string>()); const Struct_w_string *str = e.get<Struct_w_string>(); test_assert(str != NULL); test_assert(str->value == "Hello World"); } void ComponentLifecycle_struct_w_string_override(void) { flecs::world world; auto base = world.entity(); test_assert(base.id() != 0); base.set<Struct_w_string>({"Hello World"}); auto e = world.entity(); test_assert(e.id() != 0); e.add(flecs::IsA, base); e.add<Struct_w_string>(); const Struct_w_string *str = e.get<Struct_w_string>(); test_assert(str != NULL); test_assert(str->value == "Hello World"); } void ComponentLifecycle_struct_w_string_add_2_remove(void) { flecs::world world; auto e1 = world.entity().add<Struct_w_string>(); auto e2 = world.entity().add<Struct_w_string>(); const Struct_w_string *str1 = e1.get<Struct_w_string>(); test_assert(str1 != NULL); test_assert(str1->value == ""); const Struct_w_string *str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == ""); e1.remove<Struct_w_string>(); str1 = e1.get<Struct_w_string>(); test_assert(str1 == NULL); str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == ""); e2.remove<Struct_w_string>(); str2 = e2.get<Struct_w_string>(); test_assert(str2 == NULL); } void ComponentLifecycle_struct_w_string_set_2_remove(void) { flecs::world world; auto e1 = world.entity().set<Struct_w_string>({"hello"}); auto e2 = world.entity().set<Struct_w_string>({"world"}); const Struct_w_string *str1 = e1.get<Struct_w_string>(); test_assert(str1 != NULL); test_assert(str1->value == "hello"); const Struct_w_string *str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == "world"); e1.remove<Struct_w_string>(); str1 = e1.get<Struct_w_string>(); test_assert(str1 == NULL); str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == "world"); e2.remove<Struct_w_string>(); str2 = e2.get<Struct_w_string>(); test_assert(str2 == NULL); } void ComponentLifecycle_struct_w_string_add_2_remove_w_tag(void) { flecs::world world; auto e1 = world.entity().add<Tag>().add<Struct_w_string>(); auto e2 = world.entity().add<Tag>().add<Struct_w_string>(); const Struct_w_string *str1 = e1.get<Struct_w_string>(); test_assert(str1 != NULL); test_assert(str1->value == ""); const Struct_w_string *str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == ""); e1.remove<Struct_w_string>(); str1 = e1.get<Struct_w_string>(); test_assert(str1 == NULL); str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == ""); e2.remove<Struct_w_string>(); str2 = e2.get<Struct_w_string>(); test_assert(str2 == NULL); } void ComponentLifecycle_struct_w_string_set_2_remove_w_tag(void) { flecs::world world; auto e1 = world.entity().add<Tag>().set<Struct_w_string>({"hello"}); auto e2 = world.entity().add<Tag>().set<Struct_w_string>({"world"}); const Struct_w_string *str1 = e1.get<Struct_w_string>(); test_assert(str1 != NULL); test_assert(str1->value == "hello"); const Struct_w_string *str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == "world"); e1.remove<Struct_w_string>(); str1 = e1.get<Struct_w_string>(); test_assert(str1 == NULL); str2 = e2.get<Struct_w_string>(); test_assert(str2 != NULL); test_assert(str2->value == "world"); e2.remove<Struct_w_string>(); str2 = e2.get<Struct_w_string>(); test_assert(str2 == NULL); } void ComponentLifecycle_struct_w_vector_add(void) { flecs::world world; auto e = world.entity().add<Struct_w_vector>(); test_assert(e.has<Struct_w_vector>()); const Struct_w_vector *ptr = e.get<Struct_w_vector>(); test_assert(ptr != NULL); test_int(ptr->value.size(), 0); } void ComponentLifecycle_struct_w_vector_remove(void) { flecs::world world; auto e = world.entity().add<Struct_w_vector>(); test_assert(e.has<Struct_w_vector>()); e.remove<Struct_w_vector>(); test_assert(!e.has<Struct_w_vector>()); } void ComponentLifecycle_struct_w_vector_set(void) { flecs::world world; auto e = world.entity().set<Struct_w_vector>({std::vector<int>{1, 2}}); test_assert(e.has<Struct_w_vector>()); const Struct_w_vector *ptr = e.get<Struct_w_vector>(); test_assert(ptr != NULL); test_int(ptr->value.size(), 2); test_int(ptr->value.at(0), 1); test_int(ptr->value.at(1), 2); } void ComponentLifecycle_struct_w_vector_override(void) { flecs::world world; auto base = world.entity().set<Struct_w_vector>({std::vector<int>{1, 2}}); test_assert(base.has<Struct_w_vector>()); auto e = world.entity().is_a(base).add<Struct_w_vector>(); test_assert(e.has<Struct_w_vector>()); const Struct_w_vector *ptr = base.get<Struct_w_vector>(); test_assert(ptr != NULL); test_int(ptr->value.size(), 2); test_int(ptr->value.at(0), 1); test_int(ptr->value.at(1), 2); ptr = e.get<Struct_w_vector>(); test_assert(ptr != NULL); test_int(ptr->value.size(), 2); test_int(ptr->value.at(0), 1); test_int(ptr->value.at(1), 2); } void ComponentLifecycle_struct_w_vector_add_2_remove(void) { flecs::world world; auto e1 = world.entity().add<Struct_w_vector>(); auto e2 = world.entity().add<Struct_w_vector>(); const Struct_w_vector *ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 != NULL); test_int(ptr1->value.size(), 0); const Struct_w_vector *ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 0); e1.remove<Struct_w_vector>(); ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 == NULL); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 0); e2.remove<Struct_w_vector>(); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 == NULL); } void ComponentLifecycle_struct_w_vector_set_2_remove(void) { flecs::world world; auto e1 = world.entity().set<Struct_w_vector>({std::vector<int>{1, 2}}); auto e2 = world.entity().set<Struct_w_vector>({std::vector<int>{3, 4}}); const Struct_w_vector *ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 != NULL); test_int(ptr1->value.size(), 2); test_int(ptr1->value.at(0), 1); test_int(ptr1->value.at(1), 2); const Struct_w_vector *ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 2); test_int(ptr2->value.at(0), 3); test_int(ptr2->value.at(1), 4); e1.remove<Struct_w_vector>(); ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 == NULL); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 2); test_int(ptr2->value.at(0), 3); test_int(ptr2->value.at(1), 4); e2.remove<Struct_w_vector>(); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 == NULL); } void ComponentLifecycle_struct_w_vector_add_2_remove_w_tag(void) { flecs::world world; auto e1 = world.entity().add<Tag>().add<Struct_w_vector>(); auto e2 = world.entity().add<Tag>().add<Struct_w_vector>(); const Struct_w_vector *ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 != NULL); test_int(ptr1->value.size(), 0); const Struct_w_vector *ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 0); e1.remove<Struct_w_vector>(); ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 == NULL); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 0); e2.remove<Struct_w_vector>(); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 == NULL); } void ComponentLifecycle_struct_w_vector_set_2_remove_w_tag(void) { flecs::world world; auto e1 = world.entity().add<Tag>().set<Struct_w_vector>({std::vector<int>{1, 2}}); auto e2 = world.entity().add<Tag>().set<Struct_w_vector>({std::vector<int>{3, 4}}); const Struct_w_vector *ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 != NULL); test_int(ptr1->value.size(), 2); test_int(ptr1->value.at(0), 1); test_int(ptr1->value.at(1), 2); const Struct_w_vector *ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 2); test_int(ptr2->value.at(0), 3); test_int(ptr2->value.at(1), 4); e1.remove<Struct_w_vector>(); ptr1 = e1.get<Struct_w_vector>(); test_assert(ptr1 == NULL); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 != NULL); test_int(ptr2->value.size(), 2); test_int(ptr2->value.at(0), 3); test_int(ptr2->value.at(1), 4); e2.remove<Struct_w_vector>(); ptr2 = e2.get<Struct_w_vector>(); test_assert(ptr2 == NULL); } void ComponentLifecycle_get_mut_new(void) { flecs::world world; world.component<Pod>(); auto e = world.entity(); test_assert(e.id() != 0); Pod* value = e.get_mut<Pod>(); test_assert(value != NULL); Pod::ctor_invoked = 1; Pod::dtor_invoked = 0; Pod::copy_invoked = 0; Pod::move_invoked = 0; e.modified<Pod>(); Pod::ctor_invoked = 1; Pod::dtor_invoked = 0; Pod::copy_invoked = 0; Pod::move_invoked = 0; } void ComponentLifecycle_get_mut_existing(void) { flecs::world world; world.component<Pod>(); auto e = world.entity(); test_assert(e.id() != 0); Pod* value = e.get_mut<Pod>(); test_assert(value != NULL); Pod::ctor_invoked = 1; Pod::dtor_invoked = 0; Pod::copy_invoked = 0; Pod::move_invoked = 0; value = e.get_mut<Pod>(); test_assert(value != NULL); /* Repeated calls to get_mut should not invoke constructor */ Pod::ctor_invoked = 1; Pod::dtor_invoked = 0; Pod::copy_invoked = 0; Pod::move_invoked = 0; } void ComponentLifecycle_implicit_component(void) { flecs::world world; auto e = world.entity().add<Pod>(); test_assert(e.id() != 0); test_assert(e.has<Pod>()); test_int(Pod::ctor_invoked, 1); const Pod *pod = e.get<Pod>(); test_assert(pod != NULL); test_int(pod->value, 10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); world.entity().add<Pod>(); test_int(Pod::ctor_invoked, 2); test_int(Pod::move_ctor_invoked, 0); test_int(Pod::move_invoked, 0); world.entity().add<Pod>(); test_int(Pod::ctor_invoked, 3); test_int(Pod::move_ctor_invoked, 2); test_int(Pod::move_invoked, 0); } void ComponentLifecycle_implicit_after_query(void) { flecs::world world; world.query<Pod>(); auto e = world.entity().add<Pod>(); test_assert(e.id() != 0); test_assert(e.has<Pod>()); test_int(Pod::ctor_invoked, 1); const Pod *pod = e.get<Pod>(); test_assert(pod != NULL); test_int(pod->value, 10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::move_invoked, 0); world.entity().add<Pod>(); test_int(Pod::ctor_invoked, 2); test_int(Pod::move_ctor_invoked, 0); test_int(Pod::move_invoked, 0); world.entity().add<Pod>(); test_int(Pod::ctor_invoked, 3); test_int(Pod::move_ctor_invoked, 2); test_int(Pod::move_invoked, 0); } template <typename T> static void try_add(flecs::world& ecs) { flecs::entity e = ecs.entity().add<T>(); test_assert(e.has<T>()); const T *ptr = e.get<T>(); test_int(ptr->x_, 99); e.remove<T>(); test_assert(!e.has<T>()); } template <typename T> static void try_add_relation(flecs::world& ecs) { flecs::entity obj = ecs.entity(); flecs::entity e = ecs.entity().add<T>(obj); test_assert(e.has<T>()); const T *ptr = e.get<T>(); test_int(ptr->x_, 89); e.remove<T>(); test_assert(!e.has<T>()); } template <typename T> static void try_add_second(flecs::world& ecs) { flecs::entity rel = ecs.entity(); flecs::entity e = ecs.entity().add_second<T>(rel); test_assert(e.has<T>()); const T *ptr = e.get<T>(); test_int(ptr->x_, 89); e.remove<T>(); test_assert(!e.has<T>()); } template <typename T> static void try_set(flecs::world& ecs) { flecs::entity e = ecs.entity().set<T>({10}); const T *ptr = e.get<T>(); test_int(ptr->x_, 10); } template <typename T> static void try_emplace(flecs::world& ecs) { flecs::entity e = ecs.entity().emplace<T>(10); const T *ptr = e.get<T>(); test_int(ptr->x_, 10); } template <typename T> static void try_set_default(flecs::world& ecs) { flecs::entity e = ecs.entity().set(T()); const T *ptr = e.get<T>(); test_int(ptr->x_, 99); e.remove<T>(); } void ComponentLifecycle_deleted_copy(void) { flecs::world ecs; ecs.component<NoCopy>(); try_add<NoCopy>(ecs); try_set<NoCopy>(ecs); } void ComponentLifecycle_no_default_ctor_emplace(void) { flecs::world ecs; ecs.component<NoDefaultCtor>(); try_emplace<NoDefaultCtor>(ecs); } void ComponentLifecycle_default_init(void) { flecs::world ecs; ecs.component<DefaultInit>(); try_add<DefaultInit>(ecs); try_set<DefaultInit>(ecs); } void ComponentLifecycle_no_default_ctor_add(void) { install_test_abort(); flecs::world ecs; ecs.component<NoDefaultCtor>(); test_expect_abort(); try_add<NoDefaultCtor>(ecs); } void ComponentLifecycle_no_default_ctor_add_relation(void) { install_test_abort(); flecs::world ecs; ecs.component<NoDefaultCtor>(); test_expect_abort(); try_add_relation<NoDefaultCtor>(ecs); } void ComponentLifecycle_no_default_ctor_add_second(void) { install_test_abort(); flecs::world ecs; ecs.component<NoDefaultCtor>(); test_expect_abort(); try_add_second<NoDefaultCtor>(ecs); } void ComponentLifecycle_no_default_ctor_set(void) { install_test_abort(); flecs::world ecs; ecs.component<NoDefaultCtor>(); test_expect_abort(); try_set<NoDefaultCtor>(ecs); } void ComponentLifecycle_no_copy_ctor(void) { flecs::world ecs; ecs.component<NoCopyCtor>(); try_add<NoCopyCtor>(ecs); try_set<NoCopyCtor>(ecs); } void ComponentLifecycle_no_move_ctor(void) { install_test_abort(); flecs::world ecs; test_expect_abort(); ecs.component<NoMoveCtor>(); } void ComponentLifecycle_no_copy_assign(void) { flecs::world ecs; ecs.component<NoCopyAssign>(); try_add<NoCopyAssign>(ecs); try_set<NoCopyAssign>(ecs); } void ComponentLifecycle_no_move_assign(void) { install_test_abort(); flecs::world ecs; test_expect_abort(); ecs.component<NoMoveAssign>(); } void ComponentLifecycle_no_copy(void) { flecs::world ecs; ecs.component<NoCopy>(); try_add<NoCopy>(ecs); try_set<NoCopy>(ecs); } void ComponentLifecycle_no_move(void) { install_test_abort(); flecs::world ecs; test_expect_abort(); ecs.component<NoMove>(); } void ComponentLifecycle_no_dtor(void) { install_test_abort(); flecs::world ecs; test_expect_abort(); ecs.component<NoDtor>(); } void ComponentLifecycle_default_ctor_w_value_ctor(void) { flecs::world ecs; ecs.component<DefaultCtorValueCtor>(); try_add<DefaultCtorValueCtor>(ecs); try_set<DefaultCtorValueCtor>(ecs); try_set_default<FlecsCtorDefaultCtor>(ecs); } void ComponentLifecycle_no_default_ctor_move_ctor_on_set(void) { flecs::world ecs; ecs.component<CountNoDefaultCtor>(); // Emplace, construct auto e = ecs.entity().emplace<CountNoDefaultCtor>(10); test_assert(e.has<CountNoDefaultCtor>()); const CountNoDefaultCtor* ptr = e.get<CountNoDefaultCtor>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 0); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); // Set, move assign e.set<CountNoDefaultCtor>({10}); test_int(CountNoDefaultCtor::ctor_invoked, 2); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 1); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); } void ComponentLifecycle_emplace_w_ctor(void) { flecs::world ecs; auto e = ecs.entity() .emplace<Pod>(10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); const Pod *ptr = e.get<Pod>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); } void ComponentLifecycle_emplace_no_default_ctor(void) { flecs::world ecs; auto e = ecs.entity() .emplace<CountNoDefaultCtor>(10); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 0); const CountNoDefaultCtor *ptr = e.get<CountNoDefaultCtor>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 0); } void ComponentLifecycle_emplace_defer_use_move_ctor(void) { { flecs::world ecs; auto e = ecs.entity(); ecs.defer_begin(); e.emplace<CountNoDefaultCtor>(10); test_assert(!e.has<CountNoDefaultCtor>()); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); ecs.defer_end(); test_assert(e.has<CountNoDefaultCtor>()); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); const CountNoDefaultCtor *ptr = e.get<CountNoDefaultCtor>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); } test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 2); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); } void ComponentLifecycle_emplace_existing(void) { install_test_abort(); flecs::world ecs; auto e = ecs.entity() .emplace<Pod>(10); const Pod *ptr = e.get<Pod>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); test_expect_abort(); e.emplace<Pod>(20); } void ComponentLifecycle_emplace_singleton(void) { flecs::world ecs; ecs.emplace<Pod>(10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); const Pod *ptr = ecs.get<Pod>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(Pod::ctor_invoked, 1); test_int(Pod::dtor_invoked, 0); } class CtorDtorNonTrivial { public: CtorDtorNonTrivial(int x) : x_(x) { ctor_invoked ++; } ~CtorDtorNonTrivial() { dtor_invoked ++; dtor_value = x_; } int x_; std::string str_; static int ctor_invoked; static int dtor_invoked; static int dtor_value; }; int CtorDtorNonTrivial::ctor_invoked; int CtorDtorNonTrivial::dtor_invoked; int CtorDtorNonTrivial::dtor_value; void ComponentLifecycle_dtor_w_non_trivial_implicit_move(void) { flecs::world ecs; test_bool(std::is_trivially_move_assignable<CtorDtorNonTrivial>::value, false); test_bool(std::is_move_assignable<CtorDtorNonTrivial>::value, true); auto e_1 = ecs.entity().emplace<CtorDtorNonTrivial>(10); auto e_2 = ecs.entity().emplace<CtorDtorNonTrivial>(20); const CtorDtorNonTrivial *ptr = e_1.get<CtorDtorNonTrivial>(); test_assert(ptr != nullptr); test_int(ptr->x_, 10); ptr = e_2.get<CtorDtorNonTrivial>(); test_assert(ptr != nullptr); test_int(ptr->x_, 20); test_int(CtorDtorNonTrivial::ctor_invoked, 2); // Moves e_2 to e_1 e_1.destruct(); test_int(CtorDtorNonTrivial::ctor_invoked, 2); test_int(CtorDtorNonTrivial::dtor_invoked, 1); // Counter intuitive but correct. The class is not trivially movable, so // the move assignment should take care of cleaning up e_1 (10). That still // leaves the original e_2 which was moved from, but not destructed. // // In a real application the class should probably implement its own move // assignment to ensure correct destructor behavior. test_int(CtorDtorNonTrivial::dtor_value, 20); } class CtorDtor_w_MoveAssign { public: CtorDtor_w_MoveAssign(int x) : x_(x) { ctor_invoked ++; } ~CtorDtor_w_MoveAssign() { dtor_invoked ++; dtor_value = x_; } CtorDtor_w_MoveAssign(const CtorDtor_w_MoveAssign& obj) = default; CtorDtor_w_MoveAssign(CtorDtor_w_MoveAssign&& obj) = default; CtorDtor_w_MoveAssign& operator=(const CtorDtor_w_MoveAssign& obj) = default; CtorDtor_w_MoveAssign& operator=(CtorDtor_w_MoveAssign&& obj) noexcept { move_value = this->x_; this->x_ = obj.x_; obj.x_ = 0; return *this; } int x_; std::string str_; static int ctor_invoked; static int dtor_invoked; static int dtor_value; static int move_value; }; int CtorDtor_w_MoveAssign::ctor_invoked; int CtorDtor_w_MoveAssign::dtor_invoked; int CtorDtor_w_MoveAssign::dtor_value; int CtorDtor_w_MoveAssign::move_value; void ComponentLifecycle_dtor_w_non_trivial_explicit_move(void) { flecs::world ecs; test_bool(std::is_trivially_move_assignable<CtorDtor_w_MoveAssign>::value, false); test_bool(std::is_move_assignable<CtorDtor_w_MoveAssign>::value, true); auto e_1 = ecs.entity().emplace<CtorDtor_w_MoveAssign>(10); auto e_2 = ecs.entity().emplace<CtorDtor_w_MoveAssign>(20); const CtorDtor_w_MoveAssign *ptr = e_1.get<CtorDtor_w_MoveAssign>(); test_assert(ptr != nullptr); test_int(ptr->x_, 10); ptr = e_2.get<CtorDtor_w_MoveAssign>(); test_assert(ptr != nullptr); test_int(ptr->x_, 20); test_int(CtorDtor_w_MoveAssign::ctor_invoked, 2); // Moves e_2 to e_1 e_1.destruct(); test_int(CtorDtor_w_MoveAssign::ctor_invoked, 2); test_int(CtorDtor_w_MoveAssign::dtor_invoked, 1); test_int(CtorDtor_w_MoveAssign::move_value, 10); test_int(CtorDtor_w_MoveAssign::dtor_value, 0); } void ComponentLifecycle_grow_no_default_ctor(void) { { flecs::world world; world.component<CountNoDefaultCtor>(); auto e1 = world.entity().emplace<CountNoDefaultCtor>(1); auto e2 = world.entity().emplace<CountNoDefaultCtor>(2); test_int(CountNoDefaultCtor::ctor_invoked, 2); test_int(CountNoDefaultCtor::dtor_invoked, 0); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); auto e3 = world.entity().emplace<CountNoDefaultCtor>(3); test_int(CountNoDefaultCtor::ctor_invoked, 3); test_int(CountNoDefaultCtor::dtor_invoked, 2); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); test_assert(e1.has<CountNoDefaultCtor>()); test_assert(e2.has<CountNoDefaultCtor>()); test_assert(e3.has<CountNoDefaultCtor>()); test_int(e1.get<CountNoDefaultCtor>()->value, 1); test_int(e2.get<CountNoDefaultCtor>()->value, 2); test_int(e3.get<CountNoDefaultCtor>()->value, 3); } test_int(CountNoDefaultCtor::ctor_invoked, 3); test_int(CountNoDefaultCtor::dtor_invoked, 5); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); } void ComponentLifecycle_grow_no_default_ctor_move(void) { { flecs::world world; world.component<CountNoDefaultCtor>(); world.component<Tag>(); auto e1 = world.entity().emplace<CountNoDefaultCtor>(1); auto e2 = world.entity().emplace<CountNoDefaultCtor>(2); test_int(CountNoDefaultCtor::ctor_invoked, 2); test_int(CountNoDefaultCtor::dtor_invoked, 0); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); CountNoDefaultCtor::reset(); auto e3 = world.entity().emplace<CountNoDefaultCtor>(3); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 2); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); test_assert(e1.has<CountNoDefaultCtor>()); test_assert(e2.has<CountNoDefaultCtor>()); test_assert(e3.has<CountNoDefaultCtor>()); test_int(e1.get<CountNoDefaultCtor>()->value, 1); test_int(e2.get<CountNoDefaultCtor>()->value, 2); test_int(e3.get<CountNoDefaultCtor>()->value, 3); CountNoDefaultCtor::reset(); e1.add<Tag>(); test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 1); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); CountNoDefaultCtor::reset(); e2.add<Tag>(); test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); CountNoDefaultCtor::reset(); e3.add<Tag>(); test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 3); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 3); CountNoDefaultCtor::reset(); } test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 3); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); } void ComponentLifecycle_grow_no_default_ctor_move_w_component(void) { { flecs::world world; world.component<CountNoDefaultCtor>(); world.component<Position>(); auto e1 = world.entity().emplace<CountNoDefaultCtor>(1); auto e2 = world.entity().emplace<CountNoDefaultCtor>(2); test_int(CountNoDefaultCtor::ctor_invoked, 2); test_int(CountNoDefaultCtor::dtor_invoked, 0); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); CountNoDefaultCtor::reset(); auto e3 = world.entity().emplace<CountNoDefaultCtor>(3); test_int(CountNoDefaultCtor::ctor_invoked, 1); test_int(CountNoDefaultCtor::dtor_invoked, 2); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); test_assert(e1.has<CountNoDefaultCtor>()); test_assert(e2.has<CountNoDefaultCtor>()); test_assert(e3.has<CountNoDefaultCtor>()); test_int(e1.get<CountNoDefaultCtor>()->value, 1); test_int(e2.get<CountNoDefaultCtor>()->value, 2); test_int(e3.get<CountNoDefaultCtor>()->value, 3); CountNoDefaultCtor::reset(); e1.add<Position>(); test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 1); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); CountNoDefaultCtor::reset(); e2.add<Position>(); // e2 is last element, e3 got moved to e1's location test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 1); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 1); CountNoDefaultCtor::reset(); e3.add<Position>(); test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 3); /* 2 (e1,e2) for resize, 1 (e3) for moved away storage */ test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 3); /* resize */ CountNoDefaultCtor::reset(); } test_int(CountNoDefaultCtor::ctor_invoked, 0); test_int(CountNoDefaultCtor::dtor_invoked, 3); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 0); } void ComponentLifecycle_delete_no_default_ctor(void) { { flecs::world world; world.component<CountNoDefaultCtor>(); auto e1 = world.entity().emplace<CountNoDefaultCtor>(1); auto e2 = world.entity().emplace<CountNoDefaultCtor>(2); auto e3 = world.entity().emplace<CountNoDefaultCtor>(3); test_int(CountNoDefaultCtor::ctor_invoked, 3); test_int(CountNoDefaultCtor::dtor_invoked, 2); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 0); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); test_assert(e1.has<CountNoDefaultCtor>()); test_assert(e2.has<CountNoDefaultCtor>()); test_assert(e3.has<CountNoDefaultCtor>()); test_int(e1.get<CountNoDefaultCtor>()->value, 1); test_int(e2.get<CountNoDefaultCtor>()->value, 2); test_int(e3.get<CountNoDefaultCtor>()->value, 3); e2.destruct(); test_int(CountNoDefaultCtor::ctor_invoked, 3); test_int(CountNoDefaultCtor::dtor_invoked, 3); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 1); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); } test_int(CountNoDefaultCtor::ctor_invoked, 3); test_int(CountNoDefaultCtor::dtor_invoked, 5); test_int(CountNoDefaultCtor::copy_invoked, 0); test_int(CountNoDefaultCtor::move_invoked, 1); test_int(CountNoDefaultCtor::copy_ctor_invoked, 0); test_int(CountNoDefaultCtor::move_ctor_invoked, 2); } void ComponentLifecycle_on_add_hook(void) { int count = 0; { flecs::world ecs; ecs.component<Position>().on_add([&](Position& p) { count ++; }); test_int(0, count); auto e = ecs.entity().add<Position>(); test_int(1, count); e.add<Position>(); test_int(1, count); } test_int(1, count); } void ComponentLifecycle_on_remove_hook(void) { int count = 0; { flecs::world ecs; ecs.component<Position>().on_remove([&](Position& p) { count ++; }); test_int(0, count); auto e1 = ecs.entity().add<Position>(); ecs.entity().add<Position>(); test_int(0, count); e1.remove<Position>(); test_int(1, count); } test_int(2, count); } void ComponentLifecycle_on_set_hook(void) { int count = 0; Position v = {0}; { flecs::world ecs; ecs.component<Position>().on_set([&](Position& p) { count ++; v = p; }); test_int(0, count); auto e1 = ecs.entity().add<Position>(); test_int(0, count); e1.set<Position>({10, 20}); test_int(1, count); test_int(10, v.x); test_int(20, v.y); ecs.entity().set<Position>({30, 40}); test_int(2, count); test_int(30, v.x); test_int(40, v.y); } test_int(2, count); } void ComponentLifecycle_on_add_hook_w_entity(void) { int count = 0; flecs::entity e_arg; { flecs::world ecs; ecs.component<Position>().on_add([&](flecs::entity arg, Position& p) { e_arg = arg; count ++; }); test_int(0, count); test_assert(e_arg == 0); auto e = ecs.entity().add<Position>(); test_int(1, count); test_assert(e_arg == e); e.add<Position>(); test_int(1, count); } test_int(1, count); } void ComponentLifecycle_on_remove_hook_w_entity(void) { int count = 0; flecs::entity e_arg; flecs::entity e2; { flecs::world ecs; ecs.component<Position>().on_remove([&](flecs::entity arg, Position& p){ e_arg = arg; count ++; }); test_int(0, count); test_assert(e_arg == 0); auto e1 = ecs.entity().add<Position>(); e2 = ecs.entity().add<Position>(); test_int(0, count); e1.remove<Position>(); test_int(1, count); test_assert(e_arg == e1); } test_int(2, count); test_assert(e_arg == e2); } void ComponentLifecycle_on_set_hook_w_entity(void) { int count = 0; Position v = {0}; flecs::entity e_arg; { flecs::world ecs; ecs.component<Position>().on_set([&](flecs::entity arg, Position& p) { count ++; v = p; e_arg = arg; }); test_int(0, count); auto e1 = ecs.entity().add<Position>(); test_int(0, count); e1.set<Position>({10, 20}); test_int(1, count); test_assert(e_arg == e1); test_int(10, v.x); test_int(20, v.y); auto e2 = ecs.entity().set<Position>({30, 40}); test_int(2, count); test_assert(e_arg == e2); test_int(30, v.x); test_int(40, v.y); } test_int(2, count); } void ComponentLifecycle_chained_hooks(void) { flecs::world ecs; int32_t add_count = 0; int32_t remove_count = 0; int32_t set_count = 0; ecs.component<Position>() .on_add([&](Position& p){ add_count ++; }) .on_set([&](Position& p){ set_count ++; }) .on_remove([&](Position& p){ remove_count ++; }); auto e = ecs.entity(); test_int(0, add_count); test_int(0, set_count); test_int(0, remove_count); e.add<Position>(); test_int(1, add_count); test_int(0, set_count); test_int(0, remove_count); e.set<Position>({10, 20}); test_int(1, add_count); test_int(1, set_count); test_int(0, remove_count); e.remove<Position>(); test_int(1, add_count); test_int(1, set_count); test_int(1, remove_count); } void ComponentLifecycle_ctor_w_2_worlds(void) { { flecs::world ecs; test_int(Pod::ctor_invoked, 0); ecs.entity().add<Pod>(); test_int(Pod::ctor_invoked, 1); } Pod::ctor_invoked = 0; { flecs::world ecs; test_int(Pod::ctor_invoked, 0); ecs.entity().add<Pod>(); test_int(Pod::ctor_invoked, 1); } } void ComponentLifecycle_ctor_w_2_worlds_explicit_registration(void) { { flecs::world ecs; ecs.component<Pod>(); test_int(Pod::ctor_invoked, 0); ecs.entity().add<Pod>(); test_int(Pod::ctor_invoked, 1); } Pod::ctor_invoked = 0; { flecs::world ecs; ecs.component<Pod>(); test_int(Pod::ctor_invoked, 0); ecs.entity().add<Pod>(); test_int(Pod::ctor_invoked, 1); } } struct DeferEmplaceTest { double x, y; DeferEmplaceTest(double x_, double y_) { x = x_; y = y_; } }; void ComponentLifecycle_defer_emplace(void) { flecs::world ecs; flecs::entity e = ecs.entity(); ecs.defer_begin(); e.emplace<DeferEmplaceTest>(10.0, 20.0); test_assert(!e.has<DeferEmplaceTest>()); ecs.defer_end(); test_assert(e.has<DeferEmplaceTest>()); const DeferEmplaceTest *p = e.get<DeferEmplaceTest>(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void ComponentLifecycle_emplace_w_on_add(void) { flecs::world ecs; flecs::entity e1 = ecs.entity(); int on_add = 0; ecs.component<Position>() .on_add([&](flecs::entity e, Position&) { on_add = true; test_assert(e == e1); }); e1.emplace<Position>(); test_int(on_add, 1); } void ComponentLifecycle_emplace_w_on_add_existing(void) { flecs::world ecs; flecs::entity e1 = ecs.entity().add<Velocity>(); int on_add = 0; ecs.component<Position>() .on_add([&](flecs::entity e, Position&) { on_add = true; test_assert(e == e1); }); e1.emplace<Position>(); test_int(on_add, 1); } void ComponentLifecycle_set_pair_no_copy(void) { flecs::world ecs; struct Tag { }; flecs::entity e = ecs.entity() .set<NoCopy, Tag>({ 10 }); const NoCopy *ptr = e.get<NoCopy, Tag>(); test_assert(ptr != NULL); test_int(ptr->x_, 10); } void ComponentLifecycle_set_pair_w_entity_no_copy(void) { flecs::world ecs; flecs::entity tag = ecs.entity(); flecs::entity e = ecs.entity() .set<NoCopy>(tag, { 10 }); const NoCopy *ptr = e.get<NoCopy>(tag); test_assert(ptr != NULL); test_int(ptr->x_, 10); } void ComponentLifecycle_set_pair_second_no_copy(void) { flecs::world ecs; flecs::entity tag = ecs.entity(); flecs::entity e = ecs.entity() .set_second<NoCopy>(tag, { 10 }); const NoCopy *ptr = e.get_second<NoCopy>(tag); test_assert(ptr != NULL); test_int(ptr->x_, 10); } void ComponentLifecycle_set_override_no_copy(void) { flecs::world ecs; flecs::entity e = ecs.entity() .set_override<NoCopy>({ 10 }); const NoCopy *ptr = e.get<NoCopy>(); test_assert(ptr != NULL); test_int(ptr->x_, 10); test_assert(e.has(flecs::Override | ecs.id<NoCopy>())); } void ComponentLifecycle_set_override_pair_no_copy(void) { flecs::world ecs; flecs::entity e = ecs.entity() .set_override<NoCopy, Tag>({ 10 }); const NoCopy *ptr = e.get<NoCopy, Tag>(); test_assert(ptr != NULL); test_int(ptr->x_, 10); test_assert(e.has(flecs::Override | ecs.pair<NoCopy, Tag>())); } void ComponentLifecycle_set_override_pair_w_entity_no_copy(void) { flecs::world ecs; flecs::entity tag = ecs.entity(); flecs::entity e = ecs.entity() .set_override<NoCopy>(tag, { 10 }); const NoCopy *ptr = e.get<NoCopy>(tag); test_assert(ptr != NULL); test_int(ptr->x_, 10); test_assert(e.has(flecs::Override | ecs.pair<NoCopy>(tag))); } void ComponentLifecycle_dtor_after_defer_set(void) { { flecs::world ecs; auto e = ecs.entity(); ecs.defer_begin(); e.set<Pod>({10}); test_assert(!e.has<Pod>()); test_int(Pod::ctor_invoked, 2); test_int(Pod::dtor_invoked, 1); test_int(Pod::move_invoked, 1); test_int(Pod::move_ctor_invoked, 0); ecs.defer_end(); test_assert(e.has<Pod>()); test_int(Pod::ctor_invoked, 3); test_int(Pod::dtor_invoked, 2); test_int(Pod::move_invoked, 2); test_int(Pod::move_ctor_invoked, 0); const Pod *ptr = e.get<Pod>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(Pod::ctor_invoked, 3); test_int(Pod::dtor_invoked, 2); test_int(Pod::move_invoked, 2); test_int(Pod::move_ctor_invoked, 0); } test_int(Pod::ctor_invoked, 3); test_int(Pod::dtor_invoked, 3); test_int(Pod::move_invoked, 2); test_int(Pod::move_ctor_invoked, 0); } void ComponentLifecycle_dtor_with_relation(void) { { flecs::world ecs; auto e = ecs.entity(); auto e2 = ecs.entity().set<Pod>({5}); e.set<Pod>({10}).add<Tag>(e2); test_int(Pod::ctor_invoked, 4); test_int(Pod::dtor_invoked, 3); test_int(Pod::move_invoked, 2); test_int(Pod::move_ctor_invoked, 1); const Pod *ptr = e.get<Pod>(); test_assert(ptr != NULL); test_int(ptr->value, 10); test_int(Pod::ctor_invoked, 4); test_int(Pod::dtor_invoked, 3); test_int(Pod::move_invoked, 2); test_int(Pod::move_ctor_invoked, 1); } test_int(Pod::ctor_invoked, 5); test_int(Pod::dtor_invoked, 6); test_int(Pod::move_invoked, 4); test_int(Pod::move_ctor_invoked, 1); } void ComponentLifecycle_register_parent_after_child_w_hooks(void) { { flecs::world ecs; ecs.component<Pod::Child>(); ecs.component<Pod>(); ecs.entity().set<Pod>({}); } test_int(Pod::ctor_invoked, 2); test_int(Pod::dtor_invoked, 2); test_int(Pod::move_invoked, 1); test_int(Pod::move_ctor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::copy_ctor_invoked, 0); } void ComponentLifecycle_register_parent_after_child_w_hooks_implicit(void) { { flecs::world ecs; ecs.entity().add<Pod::Child>().set<Pod>({}); } test_int(Pod::ctor_invoked, 2); test_int(Pod::dtor_invoked, 2); test_int(Pod::move_invoked, 1); test_int(Pod::move_ctor_invoked, 0); test_int(Pod::copy_invoked, 0); test_int(Pod::copy_ctor_invoked, 0); }