#include struct Parent { struct EntityType { }; }; void Entity_new(void) { flecs::world world; auto entity = world.entity(); test_assert(entity); } void Entity_new_named(void) { flecs::world world; auto entity = flecs::entity(world, "Foo"); test_assert(entity); test_str(entity.name().c_str(), "Foo"); } void Entity_new_named_from_scope(void) { flecs::world world; auto entity = flecs::entity(world, "Foo"); test_assert(entity); test_str(entity.name().c_str(), "Foo"); auto prev = world.set_scope(entity); auto child = world.entity("Bar"); test_assert(child != 0); world.set_scope(prev); test_str(child.name().c_str(), "Bar"); test_str(child.path().c_str(), "::Foo::Bar"); } void Entity_new_nested_named_from_scope(void) { flecs::world world; auto entity = flecs::entity(world, "Foo"); test_assert(entity); test_str(entity.name().c_str(), "Foo"); auto prev = world.set_scope(entity); auto child = world.entity("Bar::Hello"); test_assert(child != 0); world.set_scope(prev); test_str(child.name().c_str(), "Hello"); test_str(child.path().c_str(), "::Foo::Bar::Hello"); } void Entity_new_nested_named_from_nested_scope(void) { flecs::world world; auto entity = flecs::entity(world, "Foo::Bar"); test_assert(entity); test_str(entity.name().c_str(), "Bar"); test_str(entity.path().c_str(), "::Foo::Bar"); auto prev = world.set_scope(entity); auto child = world.entity("Hello::World"); test_assert(child != 0); world.set_scope(prev); test_str(child.name().c_str(), "World"); test_str(child.path().c_str(), "::Foo::Bar::Hello::World"); } void Entity_new_add(void) { flecs::world world; world.component(); auto entity = world.entity() .add(); test_assert(entity); test_assert(entity.has()); } void Entity_new_add_2(void) { flecs::world world; world.component(); world.component(); auto entity = world.entity() .add() .add(); test_assert(entity); test_assert(entity.has()); test_assert(entity.has()); } void Entity_new_set(void) { flecs::world world; world.component(); auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); const Position *p = entity.get(); test_int(p->x, 10); test_int(p->y, 20); } void Entity_new_set_2(void) { flecs::world world; world.component(); world.component(); auto entity = world.entity() .set({10, 20}) .set({1, 2}); test_assert(entity); test_assert(entity.has()); test_assert(entity.has()); const Position *p = entity.get(); test_int(p->x, 10); test_int(p->y, 20); const Velocity *v = entity.get(); test_int(v->x, 1); test_int(v->y, 2); } void Entity_add(void) { flecs::world world; world.component(); auto entity = world.entity(); test_assert(entity); entity.add(); test_assert(entity.has()); } void Entity_remove(void) { flecs::world world; world.component(); auto entity = world.entity(); test_assert(entity); entity.add(); test_assert(entity.has()); entity.remove(); test_assert(!entity.has()); } void Entity_set(void) { flecs::world world; world.component(); auto entity = world.entity(); test_assert(entity); entity.set({10, 20}); test_assert(entity.has()); const Position *p = entity.get(); test_int(p->x, 10); test_int(p->y, 20); } void Entity_emplace_2(void) { flecs::world ecs; auto e = ecs.entity() .emplace(10.0f, 20.0f) .emplace(30.0f, 40.0f); test_assert(e.has()); test_assert(e.has()); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); const Velocity *v = e.get(); test_assert(v != NULL); test_int(v->x, 30); test_int(v->y, 40); } void Entity_emplace_after_add(void) { flecs::world ecs; auto e = ecs.entity() .add() .emplace(30.0f, 40.0f); test_assert(e.has()); test_assert(e.has()); const Velocity *v = e.get(); test_assert(v != NULL); test_int(v->x, 30); test_int(v->y, 40); } void Entity_emplace_after_add_pair(void) { flecs::world ecs; auto dummy = ecs.entity(); auto e = ecs.entity() .add(flecs::ChildOf, dummy) .emplace(30.0f, 40.0f); test_assert(e.has(flecs::ChildOf, dummy)); test_assert(e.has()); const Velocity *v = e.get(); test_assert(v != NULL); test_int(v->x, 30); test_int(v->y, 40); } void Entity_emplace_pair(void) { flecs::world ecs; auto e = ecs.entity() .emplace(10.0f, 20.0f); test_assert((e.has())); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_emplace_pair_w_entity(void) { flecs::world ecs; auto tag = ecs.entity(); auto e = ecs.entity() .emplace_first(tag, 10.0f, 20.0f); test_assert((e.has(tag))); const Position *p = e.get(tag); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_emplace_pair_type(void) { flecs::world ecs; auto e = ecs.entity() .emplace>(10.0f, 20.0f); test_assert((e.has())); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_emplace_pair_second(void) { flecs::world ecs; auto tag = ecs.entity(); auto e = ecs.entity() .emplace_second(tag, 10.0f, 20.0f); test_assert((e.has_second(tag))); const Position *p = e.get_second(tag); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_add_2(void) { flecs::world world; world.component(); world.component(); auto entity = world.entity(); test_assert(entity); entity.add() .add(); test_assert(entity.has()); test_assert(entity.has()); } void Entity_add_entity(void) { flecs::world world; auto tag = world.entity(); test_assert(tag != 0); auto entity = world.entity(); test_assert(entity); entity.add(tag); test_assert(entity.has(tag)); } void Entity_add_childof(void) { flecs::world world; auto parent = world.entity(); test_assert(parent != 0); auto entity = world.entity(); test_assert(entity); entity.add(flecs::ChildOf, parent); test_assert(entity.has(flecs::ChildOf, parent)); } void Entity_add_instanceof(void) { flecs::world world; auto base = world.entity(); test_assert(base != 0); auto entity = world.entity(); test_assert(entity); entity.add(flecs::IsA, base); test_assert(entity.has(flecs::IsA, base)); } void Entity_remove_2(void) { flecs::world world; world.component(); world.component(); auto entity = world.entity(); test_assert(entity); entity.add() .add(); test_assert(entity.has()); test_assert(entity.has()); entity.remove() .remove(); test_assert(!entity.has()); test_assert(!entity.has()); } void Entity_set_2(void) { flecs::world world; world.component(); world.component(); auto entity = world.entity(); test_assert(entity); entity.set({10, 20}) .set({1, 2}); test_assert(entity.has()); test_assert(entity.has()); const Position *p = entity.get(); test_int(p->x, 10); test_int(p->y, 20); const Velocity *v = entity.get(); test_int(v->x, 1); test_int(v->y, 2); } void Entity_remove_entity(void) { flecs::world world; auto tag = world.entity(); test_assert(tag != 0); auto entity = world.entity(); test_assert(entity); entity.add(tag); test_assert(entity.has(tag)); entity.remove(tag); test_assert(!entity.has(tag)); } void Entity_remove_childof(void) { flecs::world world; auto parent = world.entity(); test_assert(parent != 0); auto entity = world.entity(); test_assert(entity); entity.add(flecs::ChildOf, parent); test_assert(entity.has(flecs::ChildOf, parent)); entity.remove(flecs::ChildOf, parent); test_assert(!entity.has(flecs::ChildOf, parent)); } void Entity_remove_instanceof(void) { flecs::world world; auto base = world.entity(); test_assert(base != 0); auto entity = world.entity(); test_assert(entity); entity.add(flecs::IsA, base); test_assert(entity.has(flecs::IsA, base)); entity.remove(flecs::IsA, base); test_assert(!entity.has(flecs::IsA, base)); } void Entity_get_generic(void) { flecs::world world; auto position = world.component(); auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); const void *void_p = entity.get(position); test_assert(void_p != nullptr); const Position *p = static_cast(void_p); test_int(p->x, 10); test_int(p->y, 20); } void Entity_get_mut_generic(void) { flecs::world world; auto position = world.component(); auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); bool invoked; world.observer() .event(flecs::OnSet) .each([&invoked](flecs::entity e, Position& p) { invoked = true; }); void *void_p = entity.get_mut(position); test_assert(void_p != nullptr); Position *p = static_cast(void_p); test_int(p->x, 10); test_int(p->y, 20); entity.modified(position); test_bool(invoked, true); } void Entity_get_generic_w_id(void) { flecs::world world; auto position = world.component(); flecs::id id = position; auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); const void *void_p = entity.get(id); test_assert(void_p != nullptr); const Position *p = static_cast(void_p); test_int(p->x, 10); test_int(p->y, 20); } void Entity_get_generic_w_id_t(void) { flecs::world world; auto position = world.component(); flecs::id_t id = position; auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); const void *void_p = entity.get(id); test_assert(void_p != nullptr); const Position *p = static_cast(void_p); test_int(p->x, 10); test_int(p->y, 20); } void Entity_get_mut_generic_w_id(void) { flecs::world world; auto position = world.component(); flecs::id id = position; auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); bool invoked; world.observer() .event(flecs::OnSet) .each([&invoked](flecs::entity e, Position& p) { invoked = true; }); void *void_p = entity.get_mut(id); test_assert(void_p != nullptr); Position *p = static_cast(void_p); test_int(p->x, 10); test_int(p->y, 20); entity.modified(id); test_bool(invoked, true); } void Entity_get_mut_generic_w_id_t(void) { flecs::world world; auto position = world.component(); flecs::id_t id = position; auto entity = world.entity() .set({10, 20}); test_assert(entity); test_assert(entity.has()); bool invoked; world.observer() .event(flecs::OnSet) .each([&invoked](flecs::entity e, Position& p) { invoked = true; }); void *void_p = entity.get_mut(id); test_assert(void_p != nullptr); Position *p = static_cast(void_p); test_int(p->x, 10); test_int(p->y, 20); entity.modified(id); test_bool(invoked, true); } void Entity_set_generic(void) { flecs::world world; auto position = world.component(); Position p = {10, 20}; auto e = world.entity() .set_ptr(position, sizeof(Position), &p); test_assert(e.has()); test_assert(e.has(position)); const Position *ptr = e.get(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_set_generic_w_id(void) { flecs::world world; auto position = world.component(); flecs::id id = position; Position p = {10, 20}; auto e = world.entity() .set_ptr(id, sizeof(Position), &p); test_assert(e.has()); test_assert(e.has(id)); const Position *ptr = e.get(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_set_generic_w_id_t(void) { flecs::world world; auto position = world.component(); flecs::id_t id = position; Position p = {10, 20}; auto e = world.entity() .set_ptr(id, sizeof(Position), &p); test_assert(e.has()); test_assert(e.has(id)); const Position *ptr = e.get(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_set_generic_no_size(void) { flecs::world world; auto position = world.component(); Position p = {10, 20}; auto e = world.entity() .set_ptr(position, &p); test_assert(e.has()); test_assert(e.has(position)); const Position *ptr = e.get(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_set_generic_no_size_w_id(void) { flecs::world world; auto position = world.component(); flecs::id id = position; Position p = {10, 20}; auto e = world.entity() .set_ptr(id, &p); test_assert(e.has()); test_assert(e.has(id)); const Position *ptr = e.get(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_set_generic_no_size_w_id_t(void) { flecs::world world; auto position = world.component(); flecs::id_t id = position; Position p = {10, 20}; auto e = world.entity() .set_ptr(id, &p); test_assert(e.has()); test_assert(e.has(id)); const Position *ptr = e.get(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_add_role(void) { flecs::world world; auto entity = world.entity(); entity = entity.add_flags(flecs::Pair); test_assert(entity & ECS_PAIR); } void Entity_remove_role(void) { flecs::world world; auto entity = world.entity(); flecs::entity_t id = entity; entity = entity.add_flags(flecs::Pair); test_assert(entity & ECS_PAIR); entity = entity.remove_flags(); test_assert(entity == id); } void Entity_has_role(void) { flecs::world world; auto entity = world.entity(); entity = entity.add_flags(flecs::Pair); test_assert(entity.has_flags(flecs::Pair)); entity = entity.remove_flags(); test_assert(!entity.has_flags(flecs::Pair)); } void Entity_pair_role(void) { flecs::world world; auto a = world.entity(); auto b = world.entity(); auto pair = flecs::id(a, b); pair = pair.add_flags(flecs::Pair); test_assert(pair.has_flags(flecs::Pair)); auto rel = pair.first(); auto obj = pair.second(); test_assert(rel == a); test_assert(obj == b); } void Entity_equals(void) { flecs::world world; auto e1 = world.entity(); auto e2 = world.entity(); auto e1_2 = world.entity(e1); auto e2_2 = world.entity(e2); test_assert(e1 == e1_2); test_assert(e2 == e2_2); test_assert(e1 >= e1_2); test_assert(e1 <= e1_2); test_assert(e2 >= e2_2); test_assert(e2 <= e2_2); test_assert(e1 != e2); test_assert(!(e2 == e1_2)); test_assert(!(e1 == e2_2)); test_assert(!(e2 <= e1_2)); test_assert(!(e1 >= e2_2)); test_assert(!(e2 != e2)); } void Entity_compare_0(void) { flecs::world world; auto e = world.entity(); auto e0 = world.entity(0); auto e0_2 = world.entity(0); test_assert(e != e0); test_assert(e > e0); test_assert(e >= e0); test_assert(e0 < e); test_assert(e0 <= e); test_assert(e0 == e0_2); test_assert(e0 >= e0_2); test_assert(e0 <= e0_2); } void Entity_compare_id_t(void) { flecs::world world; auto e1 = world.entity(); auto e2 = world.entity(); flecs::id_t id1 = e1; flecs::id_t id2 = e2; test_assert(e1 == id1); test_assert(e2 == id2); test_assert(e1 != id2); test_assert(e2 != id1); test_assert(e1 >= id1); test_assert(e2 >= id2); test_assert(e1 <= id1); test_assert(e2 <= id2); test_assert(e1 <= id2); test_assert(e2 >= id1); test_assert(e1 < id2); test_assert(e2 > id1); test_assert(!(e2 == id1)); test_assert(!(e1 == id2)); test_assert(!(e2 != id2)); test_assert(!(e1 != id1)); test_assert(!(e1 >= id2)); test_assert(!(e2 <= id1)); test_assert(!(e2 < id2)); test_assert(!(e1 > id1)); } void Entity_compare_id(void) { flecs::world world; auto e1 = world.entity(); auto e2 = world.entity(); flecs::id id1 = e1; flecs::id id2 = e2; test_assert(e1 == id1); test_assert(e2 == id2); test_assert(e1 != id2); test_assert(e2 != id1); test_assert(e1 >= id1); test_assert(e2 >= id2); test_assert(e1 <= id1); test_assert(e2 <= id2); test_assert(e1 <= id2); test_assert(e2 >= id1); test_assert(e1 < id2); test_assert(e2 > id1); test_assert(!(e2 == id1)); test_assert(!(e1 == id2)); test_assert(!(e2 != id2)); test_assert(!(e1 != id1)); test_assert(!(e1 >= id2)); test_assert(!(e2 <= id1)); test_assert(!(e2 < id2)); test_assert(!(e1 > id1)); } void Entity_compare_literal(void) { flecs::world world; auto e1 = world.entity(500); auto e2 = world.entity(600); test_assert(e1 == 500); test_assert(e2 == 600); test_assert(e1 != 600); test_assert(e2 != 500); test_assert(e1 >= 500); test_assert(e2 >= 600); test_assert(e1 <= 500); test_assert(e2 <= 600); test_assert(e1 <= 600); test_assert(e2 >= 500); test_assert(e1 < 600); test_assert(e2 > 500); test_assert(!(e2 == 500)); test_assert(!(e1 == 600)); test_assert(!(e2 != 600)); test_assert(!(e1 != 500)); test_assert(!(e1 >= 600)); test_assert(!(e2 <= 500)); test_assert(!(e2 < 600)); test_assert(!(e1 > 500)); } void Entity_greater_than(void) { flecs::world world; auto e1 = world.entity(); auto e2 = world.entity(); test_assert(e2 > e1); test_assert(e2 >= e1); } void Entity_less_than(void) { flecs::world world; auto e1 = world.entity(); auto e2 = world.entity(); test_assert(e1 < e2); test_assert(e1 <= e2); } void Entity_not_0_or_1(void) { flecs::world world; auto e = world.entity(); flecs::id_t id = e; test_assert(id != 0); test_assert(id != 1); } void Entity_not_true_or_false(void) { flecs::world world; auto e = world.entity(); flecs::id_t id = e; test_assert(id != true); test_assert(id != false); } void Entity_has_childof(void) { flecs::world world; auto parent = world.entity(); auto e = world.entity() .add(flecs::ChildOf, parent); test_assert(e.has(flecs::ChildOf, parent)); } void Entity_has_instanceof(void) { flecs::world world; auto base = world.entity(); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has(flecs::IsA, base)); } void Entity_has_instanceof_indirect(void) { flecs::world world; auto base_of_base = world.entity(); auto base = world.entity() .add(flecs::IsA, base_of_base); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has(flecs::IsA, base_of_base)); } void Entity_null_string(void) { flecs::world world; auto e = world.entity(); test_str(e.name().c_str(), ""); } void Entity_set_name(void) { flecs::world world; auto e = world.entity(); test_str(e.name().c_str(), ""); e.set_name("Foo"); test_str(e.name().c_str(), "Foo"); } void Entity_change_name(void) { flecs::world world; auto e = world.entity("Bar"); test_str(e.name().c_str(), "Bar"); e.set_name("Foo"); test_str(e.name().c_str(), "Foo"); } void Entity_delete(void) { flecs::world world; auto e = world.entity() .add() .add(); e.destruct(); test_assert(!e.is_alive()); auto e2 = world.entity(); // Entity ids should be equal without the generation test_assert((uint32_t)e2 == (uint32_t)e); test_assert(e2 != e); } void Entity_clear(void) { flecs::world world; auto e = world.entity() .add() .add(); e.clear(); test_assert(!e.has()); test_assert(!e.has()); auto e2 = world.entity(); test_assert(e2 > e); } void Entity_foce_owned(void) { flecs::world world; auto prefab = world.prefab() .add() .add() .override(); auto e = world.entity() .add(flecs::IsA, prefab); test_assert(e.has()); test_assert(e.owns()); test_assert(e.has()); test_assert(!e.owns()); } void Entity_force_owned_2(void) { flecs::world world; auto prefab = world.prefab() .add() .add() .override() .override(); auto e = world.entity() .add(flecs::IsA, prefab); test_assert(e.has()); test_assert(e.owns()); test_assert(e.has()); test_assert(e.owns()); } void Entity_force_owned_nested(void) { flecs::world world; auto prefab = world.prefab() .add() .add() .override(); auto prefab_2 = world.prefab() .add(flecs::IsA, prefab); auto e = world.entity() .add(flecs::IsA, prefab_2); test_assert(e.has()); test_assert(e.owns()); test_assert(e.has()); test_assert(!e.owns()); } struct MyTag { }; void Entity_tag_has_size_zero(void) { flecs::world world; auto comp = world.component(); auto ptr = comp.get(); test_int(ptr->size, 0); test_int(ptr->alignment, 0); } void Entity_get_null_name(void) { flecs::world world; auto e = world.entity().set_name(nullptr); auto n = e.name(); test_assert(n.size() == 0); } void Entity_get_target(void) { flecs::world world; auto Rel = world.entity(); auto obj1 = world.entity() .add(); auto obj2 = world.entity() .add(); auto obj3 = world.entity() .add(); auto child = world.entity() .add(Rel, obj1) .add(Rel, obj2) .add(Rel, obj3); auto p = child.target(Rel); test_assert(p != 0); test_assert(p == obj1); p = child.target(Rel, 0); test_assert(p != 0); test_assert(p == obj1); p = child.target(Rel, 1); test_assert(p != 0); test_assert(p == obj2); p = child.target(Rel, 2); test_assert(p != 0); test_assert(p == obj3); p = child.target(Rel, 3); test_assert(p == 0); } void Entity_get_parent(void) { flecs::world world; flecs::entity parent = world.entity(); flecs::entity child = world.entity().child_of(parent); test_assert(child.target(flecs::ChildOf) == parent); test_assert(child.parent() == parent); } void Entity_is_component_enabled(void) { flecs::world world; auto e = world.entity() .add(); test_assert(e.enabled()); test_assert(!e.enabled()); } void Entity_is_enabled_component_enabled(void) { flecs::world world; auto e = world.entity() .add() .enable(); test_assert(e.enabled()); } void Entity_is_disabled_component_enabled(void) { flecs::world world; auto e = world.entity() .add() .disable(); test_assert(!e.enabled()); } void Entity_is_pair_enabled(void) { flecs::world world; struct TgtA { }; struct TgtB { }; auto e = world.entity() .add(); test_assert((e.enabled())); test_assert((!e.enabled())); } void Entity_is_enabled_pair_enabled(void) { flecs::world world; struct Tgt { }; auto e = world.entity() .add() .enable(); test_assert((e.enabled())); } void Entity_is_disabled_pair_enabled(void) { flecs::world world; struct Tgt { }; auto e = world.entity() .add() .disable(); test_assert((!e.enabled())); } void Entity_is_pair_enabled_w_ids(void) { flecs::world world; auto rel = world.entity(); auto tgt_a = world.entity(); auto tgt_b = world.entity(); auto e = world.entity() .add(rel, tgt_a); test_assert((e.enabled(rel, tgt_a))); test_assert((!e.enabled(rel, tgt_b))); } void Entity_is_enabled_pair_enabled_w_ids(void) { flecs::world world; auto rel = world.entity(); auto tgt = world.entity(); auto e = world.entity() .add(rel, tgt) .enable(rel, tgt); test_assert((e.enabled(rel, tgt))); } void Entity_is_disabled_pair_enabled_w_ids(void) { flecs::world world; auto rel = world.entity(); auto tgt = world.entity(); auto e = world.entity() .add(rel, tgt) .disable(rel, tgt); test_assert((!e.enabled(rel, tgt))); } void Entity_is_pair_enabled_w_tgt_id(void) { flecs::world world; auto tgt_a = world.entity(); auto tgt_b = world.entity(); auto e = world.entity() .add(tgt_a); test_assert((e.enabled(tgt_a))); test_assert((!e.enabled(tgt_b))); } void Entity_is_enabled_pair_enabled_w_tgt_id(void) { flecs::world world; auto tgt = world.entity(); auto e = world.entity() .add(tgt) .enable(tgt); test_assert((e.enabled(tgt))); } void Entity_is_disabled_pair_enabled_w_tgt_id(void) { flecs::world world; auto tgt = world.entity(); auto e = world.entity() .add(tgt) .disable(tgt); test_assert((!e.enabled(tgt))); } void Entity_get_type(void) { flecs::world world; auto entity = world.entity(); test_assert(entity); auto type_1 = entity.type(); test_int(type_1.count(), 0); auto type_2 = entity.type(); test_int(type_2.count(), 0); } void Entity_get_nonempty_type(void) { flecs::world world; auto entity = world.entity() .add(); test_assert(entity); auto type_1 = entity.type(); test_int(type_1.count(), 1); test_int(type_1.get(0), world.id()); auto type_2 = entity.type(); test_int(type_2.count(), 1); test_int(type_2.get(0), world.id()); } void Entity_set_no_copy(void) { flecs::world world; auto e = world.entity() .set({10}); test_int(Pod::copy_invoked, 0); test_assert(e.has()); const Pod *p = e.get(); test_assert(p != NULL); test_int(p->value, 10); } void Entity_set_copy(void) { flecs::world world; Pod val(10); auto e = world.entity() .set(val); test_int(Pod::copy_invoked, 1); test_assert(e.has()); const Pod *p = e.get(); test_assert(p != NULL); test_int(p->value, 10); } void Entity_set_deduced(void) { flecs::world world; auto e = world.entity() .set(Position{10, 20}); test_assert(e.has()); const Position *p = e.get(); test_int(p->x, 10); test_int(p->y, 20); } void Entity_override(void) { flecs::world world; auto base = world.entity() .override(); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has()); test_assert(e.owns()); } void Entity_override_id(void) { flecs::world world; auto tag_a = world.entity(); auto tag_b = world.entity(); auto base = world.entity() .override(tag_a) .add(tag_b); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has(tag_a)); test_assert(e.owns(tag_a)); test_assert(e.has(tag_b)); test_assert(!e.owns(tag_b)); } void Entity_override_pair_w_tgt_id(void) { flecs::world world; auto tgt_a = world.entity(); auto tgt_b = world.entity(); auto base = world.entity() .override(tgt_a) .add(tgt_b); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has(tgt_a)); test_assert(e.owns(tgt_a)); test_assert(e.has(tgt_b)); test_assert(!e.owns(tgt_b)); } void Entity_override_pair_w_ids(void) { flecs::world world; auto rel = world.entity(); auto tgt_a = world.entity(); auto tgt_b = world.entity(); auto base = world.entity() .override(rel, tgt_a) .add(rel, tgt_b); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has(rel, tgt_a)); test_assert(e.owns(rel, tgt_a)); test_assert(e.has(rel, tgt_b)); test_assert(!e.owns(rel, tgt_b)); } void Entity_override_pair(void) { flecs::world world; struct TagA { }; struct TagB { }; auto base = world.entity() .override() .add(); auto e = world.entity() .add(flecs::IsA, base); test_assert((e.has())); test_assert((e.owns())); test_assert((e.has())); test_assert((!e.owns())); } void Entity_set_override(void) { flecs::world world; auto base = world.entity() .set_override({10, 20}); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has()); test_assert(e.owns()); const Position* p = e.get(); test_int(p->x, 10); test_int(p->y, 20); const Position* p_base = base.get(); test_assert(p != p_base); test_int(p_base->x, 10); test_int(p_base->y, 20); } void Entity_set_override_lvalue(void) { flecs::world world; Position plvalue = {10, 20}; auto base = world.entity() .set_override(plvalue); auto e = world.entity() .add(flecs::IsA, base); test_assert(e.has()); test_assert(e.owns()); const Position* p = e.get(); test_int(p->x, 10); test_int(p->y, 20); const Position* p_base = base.get(); test_assert(p != p_base); test_int(p_base->x, 10); test_int(p_base->y, 20); } void Entity_set_override_pair(void) { flecs::world world; struct Tgt { }; auto base = world.entity() .set_override({10, 20}); auto e = world.entity() .add(flecs::IsA, base); test_assert((e.has())); test_assert((e.owns())); const Position* p = e.get(); test_int(p->x, 10); test_int(p->y, 20); const Position* p_base = base.get(); test_assert(p != p_base); test_int(p_base->x, 10); test_int(p_base->y, 20); } void Entity_set_override_pair_w_tgt_id(void) { flecs::world world; auto tgt = world.entity(); auto base = world.entity() .set_override(tgt, {10, 20}); auto e = world.entity() .add(flecs::IsA, base); test_assert((e.has(tgt))); test_assert((e.owns(tgt))); const Position* p = e.get(tgt); test_int(p->x, 10); test_int(p->y, 20); const Position* p_base = base.get(tgt); test_assert(p != p_base); test_int(p_base->x, 10); test_int(p_base->y, 20); } void Entity_set_override_pair_w_rel_tag(void) { flecs::world world; struct Tgt { }; auto base = world.entity() .set_override({10, 20}); auto e = world.entity() .add(flecs::IsA, base); test_assert((e.has())); test_assert((e.owns())); const Position* p = e.get(); test_int(p->x, 10); test_int(p->y, 20); const Position* p_base = base.get(); test_assert(p != p_base); test_int(p_base->x, 10); test_int(p_base->y, 20); } void Entity_emplace_override(void) { flecs::world world; auto e = world.entity().emplace_override(10); test_assert(e.has()); const NoDefaultCtor *ptr = e.get(); test_assert(ptr != nullptr); test_int(ptr->x_, 10); } void Entity_emplace_override_pair(void) { flecs::world world; auto e = world.entity().emplace_override(10); test_assert((e.has())); const NoDefaultCtor *ptr = e.get(); test_assert(ptr != nullptr); test_int(ptr->x_, 10); } void Entity_implicit_name_to_char(void) { flecs::world world; auto entity = flecs::entity(world, "Foo"); test_assert(entity); test_str(entity.name().c_str(), "Foo"); test_str(entity.name(), "Foo"); } void Entity_path(void) { flecs::world world; flecs::entity parent = world.entity("parent"); flecs::entity child = world.scope(parent).entity("child"); test_str(child.path().c_str(), "::parent::child"); } void Entity_path_from(void) { flecs::world world; flecs::entity parent = world.entity("parent"); flecs::entity child = world.scope(parent).entity("child"); flecs::entity grandchild = world.scope(child).entity("grandchild"); test_str(grandchild.path().c_str(), "::parent::child::grandchild"); test_str(grandchild.path_from(parent).c_str(), "child::grandchild"); } void Entity_path_from_type(void) { flecs::world world; flecs::entity parent = world.entity(); flecs::entity child = world.scope(parent).entity("child"); flecs::entity grandchild = world.scope(child).entity("grandchild"); test_str(grandchild.path().c_str(), "::Parent::child::grandchild"); test_str(grandchild.path_from().c_str(), "child::grandchild"); } void Entity_path_custom_sep(void) { flecs::world world; flecs::entity parent = world.entity("parent"); flecs::entity child = world.scope(parent).entity("child"); test_str(child.path("_", "").c_str(), "parent_child"); } void Entity_path_from_custom_sep(void) { flecs::world world; flecs::entity parent = world.entity("parent"); flecs::entity child = world.scope(parent).entity("child"); flecs::entity grandchild = world.scope(child).entity("grandchild"); test_str(grandchild.path().c_str(), "::parent::child::grandchild"); test_str(grandchild.path_from(parent, "_").c_str(), "child_grandchild"); } void Entity_path_from_type_custom_sep(void) { flecs::world world; flecs::entity parent = world.entity(); flecs::entity child = world.scope(parent).entity("child"); flecs::entity grandchild = world.scope(child).entity("grandchild"); test_str(grandchild.path().c_str(), "::Parent::child::grandchild"); test_str(grandchild.path_from("_").c_str(), "child_grandchild"); } void Entity_implicit_path_to_char(void) { flecs::world world; auto entity = flecs::entity(world, "Foo::Bar"); test_assert(entity); test_str(entity.name().c_str(), "Bar"); test_str(entity.path(), "::Foo::Bar"); } void Entity_implicit_type_str_to_char(void) { flecs::world world; auto entity = flecs::entity(world, "Foo"); test_assert(entity); test_str(entity.type().str(), "(Identifier,Name)"); } void Entity_entity_to_entity_view(void) { flecs::world world; flecs::entity e = world.entity() .set({10, 20}); test_assert(e != 0); flecs::entity_view ev = e; test_assert(ev != 0); test_assert(e == ev); const Position *p = ev.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_entity_view_to_entity_world(void) { flecs::world world; flecs::entity e = world.entity() .set({10, 20}); test_assert(e != 0); flecs::entity_view ev = e; test_assert(ev != 0); test_assert(e == ev); flecs::entity ew = ev.mut(world); ew.set({10, 20}); test_assert(ev.has()); const Position *p = ev.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_entity_view_to_entity_stage(void) { flecs::world world; flecs::entity_view ev = world.entity(); auto stage = world.get_stage(0); world.readonly_begin(); flecs::entity ew = ev.mut(stage); ew.set({10, 20}); test_assert(!ew.has()); world.readonly_end(); test_assert(ew.has()); test_assert(ev.has()); const Position *p = ev.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_create_entity_view_from_stage(void) { flecs::world world; auto stage = world.get_stage(0); world.readonly_begin(); flecs::entity_view ev = stage.entity(); test_assert(ev != 0); world.readonly_end(); // Ensure we can use created ev out of stage auto ew = ev.mut(world); ew.set({10, 20}); test_assert(ev.has()); const Position *p = ev.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_set_template(void) { flecs::world ecs; auto e = ecs.entity() .set>({10, 20}); const Template *ptr = e.get>(); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_get_1_component_w_callback(void) { flecs::world ecs; auto e_1 = ecs.entity() .set({10, 20}) .set({1, 2}); auto e_2 = ecs.entity() .set({11, 22}); auto e_3 = ecs.entity() .set({1, 2}); test_bool(e_1.get([](const Position& p) { test_int(p.x, 10); test_int(p.y, 20); }), true); test_bool(e_2.get([](const Position& p) { test_int(p.x, 11); test_int(p.y, 22); }), true); test_bool(e_3.get([](const Position& p) {}), false); } void Entity_get_2_components_w_callback(void) { flecs::world ecs; auto e_1 = ecs.entity() .set({10, 20}) .set({1, 2}); auto e_2 = ecs.entity() .set({11, 22}); auto e_3 = ecs.entity() .set({1, 2}); test_bool(e_1.get([](const Position& p, const Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); }), true); test_bool(e_2.get([](const Position& p, const Velocity& v) {}), false); test_bool(e_3.get([](const Position& p, const Velocity& v) {}), false); } void Entity_get_mut_1_component_w_callback(void) { flecs::world ecs; auto e_1 = ecs.entity() .set({10, 20}) .set({1, 2}); auto e_2 = ecs.entity() .set({11, 22}); auto e_3 = ecs.entity() .set({1, 2}); test_bool(e_1.get([](Position& p) { test_int(p.x, 10); test_int(p.y, 20); p.x ++; p.y += 2; }), true); test_bool(e_2.get([](Position& p) { test_int(p.x, 11); test_int(p.y, 22); p.x ++; p.y += 2; }), true); const Position* p = e_1.get(); test_int(p->x, 11); test_int(p->y, 22); p = e_2.get(); test_int(p->x, 12); test_int(p->y, 24); test_bool(e_3.get([](const Position& p) {}), false); } void Entity_get_mut_2_components_w_callback(void) { flecs::world ecs; auto e_1 = ecs.entity() .set({10, 20}) .set({1, 2}); auto e_2 = ecs.entity() .set({11, 22}); auto e_3 = ecs.entity() .set({1, 2}); test_bool(e_1.get([](Position& p, Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); p.x ++; p.y += 2; v.x += 3; v.y += 4; }), true); test_bool(e_2.get([](const Position& p, const Velocity& v) {}), false); test_bool(e_3.get([](const Position& p, const Velocity& v) {}), false); const Position* p = e_1.get(); test_int(p->x, 11); test_int(p->y, 22); const Velocity* v = e_1.get(); test_int(v->x, 4); test_int(v->y, 6); } void Entity_get_component_w_callback_nested(void) { flecs::world ecs; auto e = ecs.entity() .set({10, 20}) .set({1, 2}); test_bool(e.get([&](const Position& p) { test_int(p.x, 10); test_int(p.y, 20); test_bool(e.get([](const Velocity& v) { test_int(v.x, 1); test_int(v.y, 2); }), true); }), true); } void Entity_get_mut_component_w_callback_nested(void) { install_test_abort(); flecs::world ecs; auto e = ecs.entity() .set({10, 20}) .set({1, 2}); test_bool(e.get([&](Position& p) { test_int(p.x, 10); test_int(p.y, 20); test_expect_abort(); test_bool(e.get([](Velocity& v) { }), false); }), true); } void Entity_set_1_component_w_callback(void) { flecs::world ecs; auto e = ecs.entity() .set([](Position& p){ p.x = 10; p.y = 20; }); test_assert(e.has()); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_set_2_components_w_callback(void) { flecs::world ecs; auto e = ecs.entity() .set([](Position& p, Velocity& v){ p = {10, 20}; v = {1, 2}; }); test_assert(e.has()); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); const Velocity *v = e.get(); test_assert(v != NULL); test_int(v->x, 1); test_int(v->y, 2); } void Entity_set_3_components_w_callback(void) { flecs::world ecs; auto e = ecs.entity() .set([](Position& p, Velocity& v, Mass& m){ p = {10, 20}; v = {1, 2}; m = {50}; }); test_assert(e.has()); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); const Velocity *v = e.get(); test_assert(v != NULL); test_int(v->x, 1); test_int(v->y, 2); const Mass *m = e.get(); test_assert(m != NULL); test_int(m->value, 50); } void Entity_defer_set_1_component(void) { flecs::world ecs; ecs.defer_begin(); auto e = ecs.entity() .set([](Position& p){ p.x = 10; p.y = 20; }); test_assert(!e.has()); ecs.defer_end(); test_assert(e.has()); e.get([](const Position& p) { test_int(p.x, 10); test_int(p.y, 20); }); } void Entity_defer_set_2_components(void) { flecs::world ecs; ecs.defer_begin(); auto e = ecs.entity() .set([](Position& p, Velocity& v){ p = {10, 20}; v = {1, 2}; }); test_assert(!e.has()); test_assert(!e.has()); ecs.defer_end(); test_assert(e.has()); test_assert(e.has()); e.get([](const Position& p, const Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); }); } void Entity_defer_set_3_components(void) { flecs::world ecs; ecs.defer_begin(); auto e = ecs.entity() .set([](Position& p, Velocity& v, Mass& m){ p = {10, 20}; v = {1, 2}; m = {50}; }); test_assert(!e.has()); test_assert(!e.has()); test_assert(!e.has()); ecs.defer_end(); test_assert(e.has()); test_assert(e.has()); test_assert(e.has()); e.get([](const Position& p, const Velocity& v, const Mass& m) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); test_int(m.value, 50); }); } void Entity_set_2_w_on_set(void) { flecs::world ecs; int32_t position_set = 0; int32_t velocity_set = 0; ecs.observer() .event(flecs::OnSet) .each([&](flecs::entity e, Position& p) { position_set ++; test_int(p.x, 10); test_int(p.y, 20); }); ecs.observer() .event(flecs::OnSet) .each([&](flecs::entity e, Velocity& v) { velocity_set ++; test_int(v.x, 1); test_int(v.y, 2); }); auto e = ecs.entity() .set([](Position& p, Velocity& v){ p = {10, 20}; v = {1, 2}; }); test_int(position_set, 1); test_int(velocity_set, 1); test_bool(e.get([](const Position& p, const Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); }), true); } void Entity_defer_set_2_w_on_set(void) { flecs::world ecs; int32_t position_set = 0; int32_t velocity_set = 0; ecs.observer() .event(flecs::OnSet) .each([&](flecs::entity e, Position& p) { position_set ++; test_int(p.x, 10); test_int(p.y, 20); }); ecs.observer() .event(flecs::OnSet) .each([&](flecs::entity e, Velocity& v) { velocity_set ++; test_int(v.x, 1); test_int(v.y, 2); }); ecs.defer_begin(); auto e = ecs.entity() .set([](Position& p, Velocity& v){ p = {10, 20}; v = {1, 2}; }); test_int(position_set, 0); test_int(velocity_set, 0); ecs.defer_end(); test_int(position_set, 1); test_int(velocity_set, 1); test_bool(e.get([](const Position& p, const Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); }), true); } void Entity_set_2_after_fluent(void) { flecs::world ecs; auto e = ecs.entity() .set({50}) .set([](Position& p, Velocity& v){ p = {10, 20}; v = {1, 2}; }); test_assert(e.has()); test_assert(e.has()); test_assert(e.has()); test_bool(e.get([](const Position& p, const Velocity& v, const Mass& m) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); test_int(m.value, 50); }), true); } void Entity_set_2_before_fluent(void) { flecs::world ecs; auto e = ecs.entity() .set([](Position& p, Velocity& v){ p = {10, 20}; v = {1, 2}; }) .set({50}); test_assert(e.has()); test_assert(e.has()); test_assert(e.has()); test_bool(e.get([](const Position& p, const Velocity& v, const Mass& m) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); test_int(m.value, 50); }), true); } void Entity_set_2_after_set_1(void) { flecs::world ecs; int called = 0; auto e = ecs.entity().set({5, 10}); test_assert(e.has()); test_bool(e.get([](const Position& p) { test_int(p.x, 5); test_int(p.y, 10); }), true); // Set both Position and Velocity e.set([](Position& p, Velocity& v) { p = {10, 20}; v = {1, 2}; }); test_bool(e.get([&](const Position& p, const Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 1); test_int(v.y, 2); called ++; }), true); test_int(called, 1); } void Entity_set_2_after_set_2(void) { flecs::world ecs; int called = 0; auto e = ecs.entity() .set({5, 10}) .set({1, 2}); test_assert(e.has()); test_assert(e.has()); test_bool(e.get([&](const Position& p, const Velocity& v) { test_int(p.x, 5); test_int(p.y, 10); test_int(v.x, 1); test_int(v.y, 2); called ++; }), true); test_int(called, 1); // Set both Position and Velocity (doesn't add any components) e.set([](Position& p, Velocity& v) { p = {10, 20}; v = {3, 4}; }); test_bool(e.get([&](const Position& p, const Velocity& v) { test_int(p.x, 10); test_int(p.y, 20); test_int(v.x, 3); test_int(v.y, 4); called ++; }), true); test_int(called, 2); } void Entity_with_self(void) { flecs::world ecs; auto Tag = ecs.entity().with([&]{ auto e1 = ecs.entity(); e1.set({e1}); auto e2 = ecs.entity(); e2.set({e2}); auto e3 = ecs.entity(); e3.set({e3}); }); // Ensures that while Self is (implicitly) registered within the with, it // does not get the tag. auto self = ecs.component(); test_assert(!self.has(Tag)); int count = 0; auto q = ecs.query_builder<>().term(Tag).build(); q.each([&](flecs::entity e) { test_assert(e.has(Tag)); test_bool(e.get([&](const Self& s){ test_assert(s.value == e); }), true); count ++; }); test_int(count, 3); } void Entity_with_relation_type_self(void) { flecs::world ecs; struct Likes { }; auto Bob = ecs.entity().with([&]{ auto e1 = ecs.entity(); e1.set({e1}); auto e2 = ecs.entity(); e2.set({e2}); auto e3 = ecs.entity(); e3.set({e3}); }); // Ensures that while Self is (implicitly) registered within the with, it // does not get the tag. auto self = ecs.component(); test_assert(!self.has(Bob)); int count = 0; auto q = ecs.query_builder<>().term(Bob).build(); q.each([&](flecs::entity e) { test_assert(e.has(Bob)); test_bool(e.get([&](const Self& s){ test_assert(s.value == e); }), true); count ++; }); test_int(count, 3); } void Entity_with_relation_self(void) { flecs::world ecs; auto Likes = ecs.entity(); auto Bob = ecs.entity().with(Likes, [&]{ auto e1 = ecs.entity(); e1.set({e1}); auto e2 = ecs.entity(); e2.set({e2}); auto e3 = ecs.entity(); e3.set({e3}); }); // Ensures that while Self is (implicitly) registered within the with, it // does not get the tag. auto self = ecs.component(); test_assert(!self.has(Likes, Bob)); int count = 0; auto q = ecs.query_builder<>().term(Likes, Bob).build(); q.each([&](flecs::entity e) { test_assert(e.has(Likes, Bob)); test_bool(e.get([&](const Self& s){ test_assert(s.value == e); }), true); count ++; }); test_int(count, 3); } void Entity_with_self_w_name(void) { flecs::world ecs; auto Tier1 = ecs.entity("Tier1").with([&]{ auto Tier2 = ecs.entity("Tier2"); Tier2.set({Tier2}); }); auto Tier2 = ecs.lookup("Tier2"); test_assert(Tier2 != 0); test_assert(Tier2.has(Tier1)); } void Entity_with_self_nested(void) { flecs::world ecs; auto Tier1 = ecs.entity("Tier1").with([&]{ ecs.entity("Tier2").with([&]{ ecs.entity("Tier3"); }); }); auto Tier2 = ecs.lookup("Tier2"); test_assert(Tier2 != 0); auto Tier3 = ecs.lookup("Tier3"); test_assert(Tier3 != 0); test_assert(Tier2.has(Tier1)); test_assert(Tier3.has(Tier2)); } void Entity_with_scope(void) { flecs::world ecs; auto parent = ecs.entity("P").scope([&]{ auto e1 = ecs.entity("C1"); e1.set({e1}); auto e2 = ecs.entity("C2"); e2.set({e2}); auto e3 = ecs.entity("C3"); e3.set({e3}); // Ensure relative lookups work test_assert(ecs.lookup("C1") == e1); test_assert(ecs.lookup("C2") == e2); test_assert(ecs.lookup("C3") == e3); test_assert(ecs.lookup("::P::C1") == e1); test_assert(ecs.lookup("::P::C2") == e2); test_assert(ecs.lookup("::P::C3") == e3); }); // Ensure entities are created in correct scope test_assert(ecs.lookup("C1") == 0); test_assert(ecs.lookup("C2") == 0); test_assert(ecs.lookup("C3") == 0); test_assert(parent.lookup("C1") != 0); test_assert(parent.lookup("C2") != 0); test_assert(parent.lookup("C3") != 0); test_assert(ecs.lookup("P::C1") == parent.lookup("C1")); test_assert(ecs.lookup("P::C2") == parent.lookup("C2")); test_assert(ecs.lookup("P::C3") == parent.lookup("C3")); // Ensures that while Self is (implicitly) registered within the with, it // does not become a child of the parent. auto self = ecs.component(); test_assert(!self.has(flecs::ChildOf, parent)); int count = 0; auto q = ecs.query_builder<>().term(flecs::ChildOf, parent).build(); q.each([&](flecs::entity e) { test_assert(e.has(flecs::ChildOf, parent)); test_bool(e.get([&](const Self& s){ test_assert(s.value == e); }), true); count ++; }); test_int(count, 3); } void Entity_with_scope_nested(void) { flecs::world ecs; auto parent = ecs.entity("P").scope([&]{ auto child = ecs.entity("C").scope([&]{ auto gchild = ecs.entity("GC"); test_assert(gchild == ecs.lookup("GC")); test_assert(gchild == ecs.lookup("::P::C::GC")); }); // Ensure relative lookups work test_assert(ecs.lookup("C") == child); test_assert(ecs.lookup("::P::C") == child); test_assert(ecs.lookup("::P::C::GC") != 0); }); test_assert(0 == ecs.lookup("C")); test_assert(0 == ecs.lookup("GC")); test_assert(0 == ecs.lookup("C::GC")); auto child = ecs.lookup("P::C"); test_assert(0 != child); test_assert(child.has(flecs::ChildOf, parent)); auto gchild = ecs.lookup("P::C::GC"); test_assert(0 != gchild); test_assert(gchild.has(flecs::ChildOf, child)); } void Entity_with_scope_nested_same_name_as_parent(void) { flecs::world ecs; auto parent = ecs.entity("P").scope([&]{ auto child = ecs.entity("C").scope([&]{ auto gchild = ecs.entity("C"); test_assert(gchild == ecs.lookup("C")); test_assert(gchild == ecs.lookup("::P::C::C")); }); // Ensure relative lookups work test_assert(ecs.lookup("C") == child); test_assert(ecs.lookup("::P::C") == child); test_assert(ecs.lookup("::P::C::C") != 0); }); test_assert(0 == ecs.lookup("C")); test_assert(0 == ecs.lookup("C")); test_assert(0 == ecs.lookup("C::C")); auto child = ecs.lookup("P::C"); test_assert(0 != child); test_assert(child.has(flecs::ChildOf, parent)); auto gchild = ecs.lookup("P::C::C"); test_assert(0 != gchild); test_assert(gchild.has(flecs::ChildOf, child)); } void Entity_no_recursive_lookup(void) { flecs::world ecs; auto p = ecs.entity("P"); auto c = ecs.entity("C").child_of(p); auto gc = ecs.entity("GC").child_of(c); test_assert(c.lookup("GC") == gc); test_assert(c.lookup("C") == 0); test_assert(c.lookup("P") == 0); } void Entity_defer_new_w_name(void) { flecs::world ecs; flecs::entity e; ecs.defer([&]{ e = ecs.entity("Foo"); test_assert(e != 0); }); test_assert(e.has(flecs::Name)); test_str(e.name(), "Foo"); } void Entity_defer_new_w_nested_name(void) { flecs::world ecs; flecs::entity e; ecs.defer([&]{ e = ecs.entity("Foo::Bar"); test_assert(e != 0); }); test_assert(e.has(flecs::Name)); test_str(e.name(), "Bar"); test_str(e.path(), "::Foo::Bar"); } void Entity_defer_new_w_scope_name(void) { flecs::world ecs; flecs::entity e, parent = ecs.entity("Parent"); ecs.defer([&]{ parent.scope([&]{ e = ecs.entity("Foo"); test_assert(e != 0); }); }); test_assert(e.has(flecs::Name)); test_str(e.name(), "Foo"); test_str(e.path(), "::Parent::Foo"); } void Entity_defer_new_w_scope_nested_name(void) { flecs::world ecs; flecs::entity e, parent = ecs.entity("Parent"); ecs.defer([&]{ parent.scope([&]{ e = ecs.entity("Foo::Bar"); test_assert(e != 0); }); }); test_assert(e.has(flecs::Name)); test_str(e.name(), "Bar"); test_str(e.path(), "::Parent::Foo::Bar"); } void Entity_defer_new_w_deferred_scope_nested_name(void) { flecs::world ecs; flecs::entity e, parent; ecs.defer([&]{ parent = ecs.entity("Parent").scope([&]{ e = ecs.entity("Foo::Bar"); test_assert(e != 0); }); }); test_assert(parent.has(flecs::Name)); test_str(parent.name(), "Parent"); test_str(parent.path(), "::Parent"); test_assert(e.has(flecs::Name)); test_str(e.name(), "Bar"); test_str(e.path(), "::Parent::Foo::Bar"); } void Entity_defer_new_w_scope(void) { flecs::world ecs; flecs::entity e, parent = ecs.entity(); ecs.defer([&]{ parent.scope([&]{ e = ecs.entity(); test_assert(e != 0); }); }); test_assert(e.has(flecs::ChildOf, parent)); } void Entity_defer_new_w_with(void) { flecs::world ecs; flecs::entity e, Tag = ecs.entity(); ecs.defer([&]{ Tag.with([&]{ e = ecs.entity(); test_assert(e != 0); test_assert(!e.has(Tag)); }); }); test_assert(e.has(Tag)); } void Entity_defer_new_w_name_scope_with(void) { flecs::world ecs; flecs::entity e, Tag = ecs.entity(), parent = ecs.entity("Parent"); ecs.defer([&]{ Tag.with([&]{ parent.scope([&]{ e = ecs.entity("Foo"); test_assert(e != 0); test_assert(!e.has(Tag)); }); test_assert(!e.has(Tag)); }); test_assert(!e.has(Tag)); }); test_assert(e.has(Tag)); test_assert(e.has(flecs::Name)); test_str(e.name(), "Foo"); test_str(e.path(), "::Parent::Foo"); } void Entity_defer_new_w_nested_name_scope_with() { flecs::world ecs; flecs::entity e, Tag = ecs.entity(), parent = ecs.entity("Parent"); ecs.defer([&]{ Tag.with([&]{ parent.scope([&]{ e = ecs.entity("Foo::Bar"); test_assert(e != 0); test_assert(!e.has(Tag)); }); test_assert(!e.has(Tag)); }); test_assert(!e.has(Tag)); }); test_assert(e.has(Tag)); test_assert(e.has(flecs::Name)); test_str(e.name(), "Bar"); test_str(e.path(), "::Parent::Foo::Bar"); } void Entity_defer_w_with_implicit_component(void) { flecs::world ecs; struct Tag { }; flecs::entity e; ecs.defer([&]{ ecs.with([&]{ e = ecs.entity(); test_assert(!e.has()); }); test_assert(!e.has()); }); test_assert(e.has()); } void Entity_defer_suspend_resume(void) { flecs::world ecs; struct TagA { }; struct TagB { }; flecs::entity e = ecs.entity(); ecs.defer([&]{ e.add(); test_assert(!e.has()); ecs.defer_suspend(); e.add(); test_assert(!e.has()); test_assert(e.has()); ecs.defer_resume(); test_assert(!e.has()); test_assert(e.has()); }); test_assert(e.has()); test_assert(e.has()); } void Entity_with_after_builder_method(void) { flecs::world ecs; struct Likes { }; auto A = ecs.entity() .set({10, 20}) .with([&]{ ecs.entity("X"); }); auto B = ecs.entity().set({30, 40}) .with([&]{ ecs.entity("Y"); }); auto C = ecs.entity().set({50, 60}) .with(flecs::IsA, [&]{ ecs.entity("Z"); }); test_assert(A.get([](const Position& p) { test_int(p.x, 10); test_int(p.y, 20); })); test_assert(B.get([](const Position& p) { test_int(p.x, 30); test_int(p.y, 40); })); test_assert(C.get([](const Position& p) { test_int(p.x, 50); test_int(p.y, 60); })); auto X = ecs.lookup("X"); test_assert(X != 0); test_assert(X.has(A)); auto Y = ecs.lookup("Y"); test_assert(Y != 0); test_assert(Y.has(B)); auto Z = ecs.lookup("Z"); test_assert(Z != 0); test_assert(Z.has(flecs::IsA, C)); } void Entity_with_before_builder_method(void) { flecs::world ecs; struct Likes { }; auto A = ecs.entity() .with([&]{ ecs.entity("X"); }) .set({10, 20}); auto B = ecs.entity().with([&]{ ecs.entity("Y"); }) .set({30, 40}); auto C = ecs.entity().with(flecs::IsA, [&]{ ecs.entity("Z"); }) .set({50, 60}); test_assert(A.get([](const Position& p) { test_int(p.x, 10); test_int(p.y, 20); })); test_assert(B.get([](const Position& p) { test_int(p.x, 30); test_int(p.y, 40); })); test_assert(C.get([](const Position& p) { test_int(p.x, 50); test_int(p.y, 60); })); auto X = ecs.lookup("X"); test_assert(X != 0); test_assert(X.has(A)); auto Y = ecs.lookup("Y"); test_assert(Y != 0); test_assert(Y.has(B)); auto Z = ecs.lookup("Z"); test_assert(Z != 0); test_assert(Z.has(flecs::IsA, C)); } void Entity_scope_after_builder_method(void) { flecs::world ecs; ecs.entity("P") .set({10, 20}) .scope([&]{ ecs.entity("C"); }); auto C = ecs.lookup("P::C"); test_assert(C != 0); } void Entity_scope_before_builder_method(void) { flecs::world ecs; ecs.entity("P") .scope([&]{ ecs.entity("C"); }) .set({10, 20}); auto C = ecs.lookup("P::C"); test_assert(C != 0); } void Entity_emplace(void) { flecs::world ecs; auto e = ecs.entity() .emplace(10.0f, 20.0f); test_assert(e.has()); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Entity_entity_id_str(void) { flecs::world ecs; flecs::id id = ecs.entity("Foo"); test_str("Foo", id.str()); } void Entity_pair_id_str(void) { flecs::world ecs; flecs::id id = ecs.pair( ecs.entity("Rel"), ecs.entity("Obj") ); test_str("(Rel,Obj)", id.str()); } void Entity_role_id_str(void) { flecs::world ecs; flecs::id id = flecs::id(ecs, ECS_OVERRIDE | ecs.entity("Foo")); test_str("OVERRIDE|Foo", id.str()); } void Entity_id_str_from_entity_view(void) { flecs::world ecs; flecs::entity_view id = ecs.entity("Foo"); test_str("Foo", id.str()); } void Entity_id_str_from_entity(void) { flecs::world ecs; flecs::entity id = ecs.entity("Foo"); test_str("Foo", id.str()); } void Entity_null_entity(void) { flecs::entity e = flecs::entity::null(); test_assert(e.id() == 0); } void Entity_null_entity_w_world(void) { flecs::world ecs; flecs::entity e = flecs::entity::null(ecs); test_assert(e.id() == 0); test_assert(e.world().c_ptr() == ecs.c_ptr()); } void Entity_null_entity_w_0(void) { flecs::entity e = flecs::entity(static_cast(0)); test_assert(e.id() == 0); test_assert(e.world().c_ptr() == nullptr); } void Entity_null_entity_w_world_w_0(void) { flecs::world ecs; flecs::entity e = flecs::entity::null(ecs); test_assert(e.id() == 0); test_assert(e.world().c_ptr() == ecs.c_ptr()); } void Entity_entity_view_null_entity(void) { flecs::entity_view e = flecs::entity::null(); test_assert(e.id() == 0); } void Entity_entity_view_null_entity_w_world(void) { flecs::world ecs; flecs::entity_view e = flecs::entity::null(ecs); test_assert(e.id() == 0); test_assert(e.world().c_ptr() == ecs.c_ptr()); } void Entity_entity_view_null_entity_w_0(void) { flecs::entity_view e = flecs::entity(static_cast(0)); test_assert(e.id() == 0); test_assert(e.world().c_ptr() == nullptr); } void Entity_entity_view_null_entity_w_world_w_0(void) { flecs::world ecs; flecs::entity_view e = flecs::entity::null(ecs); test_assert(e.id() == 0); test_assert(e.world().c_ptr() == ecs.c_ptr()); } void Entity_is_wildcard(void) { flecs::world ecs; auto e1 = ecs.entity(); auto e2 = ecs.entity(); auto p0 = e1; auto p1 = ecs.pair(e1, e2); auto p2 = ecs.pair(e1, flecs::Wildcard); auto p3 = ecs.pair(flecs::Wildcard, e2); auto p4 = ecs.pair(flecs::Wildcard, flecs::Wildcard); test_bool(e1.is_wildcard(), false); test_bool(e2.is_wildcard(), false); test_bool(p0.is_wildcard(), false); test_bool(p1.is_wildcard(), false); test_bool(p2.is_wildcard(), true); test_bool(p3.is_wildcard(), true); test_bool(p4.is_wildcard(), true); } void Entity_has_id_t(void) { flecs::world ecs; flecs::id_t id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id_t id_2 = ecs.entity(); test_assert(id_2 != 0); auto e = ecs.entity() .add(id_1); test_assert(e != 0); test_bool(e.has(id_1), true); test_bool(e.has(id_2), false); } void Entity_has_pair_id_t(void) { flecs::world ecs; flecs::id_t id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id_t id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id_t id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_1, id_2); test_assert(e != 0); test_bool(e.has(id_1, id_2), true); test_bool(e.has(id_1, id_3), false); } void Entity_has_pair_id_t_w_type(void) { flecs::world ecs; struct Rel { }; flecs::id_t id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id_t id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_2); test_assert(e != 0); test_bool(e.has(id_2), true); test_bool(e.has(id_3), false); } void Entity_has_id(void) { flecs::world ecs; flecs::id id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id id_2 = ecs.entity(); test_assert(id_2 != 0); auto e = ecs.entity() .add(id_1); test_assert(e != 0); test_bool(e.has(id_1), true); test_bool(e.has(id_2), false); } void Entity_has_pair_id(void) { flecs::world ecs; flecs::id id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_1, id_2); test_assert(e != 0); test_bool(e.has(id_1, id_2), true); test_bool(e.has(id_1, id_3), false); } void Entity_has_pair_id_w_type(void) { flecs::world ecs; struct Rel { }; flecs::id id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_2); test_assert(e != 0); test_bool(e.has(id_2), true); test_bool(e.has(id_3), false); } void Entity_has_wildcard_id(void) { flecs::world ecs; flecs::id id = ecs.entity(); test_assert(id != 0); auto e1 = ecs.entity().add(id); auto e2 = ecs.entity(); test_assert(e1 != 0); test_assert(e2 != 0); test_bool(e1.has(flecs::Wildcard), true); test_bool(e2.has(flecs::Wildcard), false); } void Entity_has_wildcard_pair_id(void) { flecs::world ecs; flecs::id rel = ecs.entity(); test_assert(rel != 0); flecs::id obj = ecs.entity(); test_assert(obj != 0); flecs::id obj_2 = ecs.entity(); test_assert(obj_2 != 0); flecs::id w1 = ecs.id(rel, flecs::Wildcard); flecs::id w2 = ecs.id(flecs::Wildcard, obj); auto e1 = ecs.entity().add(rel, obj); auto e2 = ecs.entity().add(rel, obj_2); test_assert(e1 != 0); test_assert(e2 != 0); test_bool(e1.has(w1), true); test_bool(e1.has(w2), true); test_bool(e2.has(w1), true); test_bool(e2.has(w2), false); } void Entity_owns_id_t(void) { flecs::world ecs; flecs::id_t id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id_t id_2 = ecs.entity(); test_assert(id_2 != 0); auto e = ecs.entity() .add(id_1); test_assert(e != 0); test_bool(e.owns(id_1), true); test_bool(e.owns(id_2), false); } void Entity_owns_pair_id_t(void) { flecs::world ecs; flecs::id_t id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id_t id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id_t id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_1, id_2); test_assert(e != 0); test_bool(e.owns(id_1, id_2), true); test_bool(e.owns(id_1, id_3), false); } void Entity_owns_pair_id_t_w_type(void) { flecs::world ecs; struct Rel { }; flecs::id_t id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id_t id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_2); test_assert(e != 0); test_bool(e.owns(id_2), true); test_bool(e.owns(id_3), false); } void Entity_owns_id(void) { flecs::world ecs; flecs::id id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id id_2 = ecs.entity(); test_assert(id_2 != 0); auto e = ecs.entity() .add(id_1); test_assert(e != 0); test_bool(e.owns(id_1), true); test_bool(e.owns(id_2), false); } void Entity_owns_pair_id(void) { flecs::world ecs; flecs::id id_1 = ecs.entity(); test_assert(id_1 != 0); flecs::id id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_1, id_2); test_assert(e != 0); test_bool(e.owns(id_1, id_2), true); test_bool(e.owns(id_1, id_3), false); } void Entity_owns_wildcard_id(void) { flecs::world ecs; flecs::id id = ecs.entity(); test_assert(id != 0); auto e1 = ecs.entity().add(id); auto e2 = ecs.entity(); test_assert(e1 != 0); test_assert(e2 != 0); test_bool(e1.owns(flecs::Wildcard), true); test_bool(e2.owns(flecs::Wildcard), false); } void Entity_owns_wildcard_pair(void) { flecs::world ecs; flecs::id rel = ecs.entity(); test_assert(rel != 0); flecs::id obj = ecs.entity(); test_assert(obj != 0); flecs::id obj_2 = ecs.entity(); test_assert(obj_2 != 0); flecs::id w1 = ecs.id(rel, flecs::Wildcard); flecs::id w2 = ecs.id(flecs::Wildcard, obj); auto e1 = ecs.entity().add(rel, obj); auto e2 = ecs.entity().add(rel, obj_2); test_assert(e1 != 0); test_assert(e2 != 0); test_bool(e1.owns(w1), true); test_bool(e1.owns(w2), true); test_bool(e2.owns(w1), true); test_bool(e2.owns(w2), false); } void Entity_owns_pair_id_w_type(void) { flecs::world ecs; struct Rel { }; flecs::id id_2 = ecs.entity(); test_assert(id_2 != 0); flecs::id id_3 = ecs.entity(); test_assert(id_3 != 0); auto e = ecs.entity() .add(id_2); test_assert(e != 0); test_bool(e.owns(id_2), true); test_bool(e.owns(id_3), false); } void Entity_id_from_world(void) { flecs::world ecs; auto e = ecs.entity(); test_assert(e != 0); flecs::id id_1 = ecs.id(e); test_assert(id_1 != 0); test_assert(id_1 == e); test_assert(id_1.world() == ecs); test_bool(id_1.is_pair(), false); test_bool(id_1.is_wildcard(), false); flecs::id id_2 = ecs.id(flecs::Wildcard); test_assert(id_2 != 0); test_assert(id_2 == flecs::Wildcard); test_assert(id_2.world() == ecs); test_bool(id_2.is_pair(), false); test_bool(id_2.is_wildcard(), true); } void Entity_id_pair_from_world(void) { flecs::world ecs; auto rel = ecs.entity(); test_assert(rel != 0); auto obj = ecs.entity(); test_assert(obj != 0); flecs::id id_1 = ecs.id(rel, obj); test_assert(id_1 != 0); test_assert(id_1.first() == rel); test_assert(id_1.second() == obj); test_assert(id_1.world() == ecs); test_bool(id_1.is_pair(), true); test_bool(id_1.is_wildcard(), false); flecs::id id_2 = ecs.id(rel, flecs::Wildcard); test_assert(id_2 != 0); test_assert(id_2.first() == rel); test_assert(id_2.second() == flecs::Wildcard); test_assert(id_2.world() == ecs); test_bool(id_2.is_pair(), true); test_bool(id_2.is_wildcard(), true); } void Entity_id_default_from_world(void) { flecs::world ecs; flecs::id id_default = ecs.id(); test_assert(id_default == 0); } void Entity_is_a(void) { flecs::world world; auto base = world.entity(); auto e = world.entity().is_a(base); test_assert(e.has(flecs::IsA, base)); } void Entity_is_a_w_type(void) { flecs::world world; struct Prefab { }; auto base = world.entity(); auto e = world.entity().is_a(); test_assert(e.has(flecs::IsA, base)); test_assert(e.has_second(flecs::IsA)); } void Entity_child_of(void) { flecs::world world; auto base = world.entity(); auto e = world.entity().child_of(base); test_assert(e.has(flecs::ChildOf, base)); } void Entity_child_of_w_type(void) { flecs::world world; struct Parent { }; auto base = world.entity(); auto e = world.entity().child_of(); test_assert(e.has(flecs::ChildOf, base)); test_assert(e.has_second(flecs::ChildOf)); } void Entity_slot_of(void) { flecs::world world; auto base = world.prefab(); auto base_child = world.prefab() .child_of(base) .slot_of(base); test_assert(base_child.has(flecs::SlotOf, base)); auto inst = world.entity().is_a(base); test_assert(inst.has(base_child, flecs::Wildcard)); } void Entity_slot_of_w_type(void) { flecs::world world; struct Parent { }; auto base = world.prefab(); auto base_child = world.prefab() .child_of(base) .slot_of(); test_assert(base_child.has(flecs::SlotOf, base)); auto inst = world.entity().is_a(base); test_assert(inst.has(base_child, flecs::Wildcard)); } void Entity_slot(void) { flecs::world world; auto base = world.prefab(); auto base_child = world.prefab() .child_of(base).slot(); test_assert(base_child.has(flecs::SlotOf, base)); auto inst = world.entity().is_a(base); test_assert(inst.has(base_child, flecs::Wildcard)); } void Entity_id_get_entity(void) { flecs::world world; auto e = world.entity(); auto id = world.id(e); test_assert(id.entity() == e); } void Entity_id_get_invalid_entity(void) { install_test_abort(); flecs::world world; auto r = world.entity(); auto o = world.entity(); auto id = world.id(r, o); test_expect_abort(); id.entity(); } void Entity_each_in_stage(void) { flecs::world world; struct Rel { }; struct Obj { }; auto e = world.entity().add(); test_assert((e.has())); world.readonly_begin(); auto s = world.get_stage(0); auto em = e.mut(s); test_assert((em.has())); int count = 0; em.each([&](flecs::entity obj) { count ++; test_assert(obj == world.id()); }); test_int(count, 1); world.readonly_end(); } void Entity_iter_recycled_parent(void) { flecs::world ecs; auto e = ecs.entity(); e.destruct(); auto e2 = ecs.entity(); test_assert(e != e2); test_assert((uint32_t)e.id() == (uint32_t)e2.id()); auto e_child = ecs.entity().child_of(e2); int32_t count = 0; e2.children([&](flecs::entity child){ count ++; test_assert(child == e_child); }); test_int(count, 1); } void Entity_get_lambda_from_stage(void) { flecs::world ecs; auto e = ecs.entity().set({10, 20}); ecs.readonly_begin(); flecs::world stage = ecs.get_stage(0); bool invoked = false; e.mut(stage).get([&](const Position& p) { invoked = true; test_int(p.x, 10); test_int(p.y, 20); }); test_bool(invoked, true); ecs.readonly_end(); } void Entity_default_ctor(void) { flecs::world ecs; flecs::entity e1; flecs::entity e2 = {}; flecs::entity_view e3; flecs::entity_view e4 = {}; flecs::id id1; flecs::id id2 = {}; e1 = ecs.entity(); e2 = ecs.entity(); e3 = ecs.entity(); e4 = ecs.entity(); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(e4 != 0); test_assert(id2 == 0); } void Entity_get_obj_by_template(void) { flecs::world ecs; struct Rel {}; flecs::entity e1 = ecs.entity(); flecs::entity o1 = ecs.entity(); flecs::entity o2 = ecs.entity(); e1.add(o1); e1.add(o2); test_assert(o1 == e1.target()); test_assert(o1 == e1.target(0)); test_assert(o2 == e1.target(1)); } void Entity_create_named_twice_deferred(void) { flecs::world ecs; ecs.defer_begin(); auto e1 = ecs.entity("e"); auto e2 = ecs.entity("e"); auto f1 = ecs.entity("p::f"); auto f2 = ecs.entity("p::f"); auto g1 = ecs.scope(ecs.entity("q")).entity("g"); auto g2 = ecs.scope(ecs.entity("q")).entity("g"); ecs.defer_end(); test_str(e1.path().c_str(), "::e"); test_str(f1.path().c_str(), "::p::f"); test_str(g1.path().c_str(), "::q::g"); test_assert(e1 == e2); test_assert(f1 == f2); test_assert(g1 == g2); } struct PositionInitialized { PositionInitialized() { } PositionInitialized(float x_, float y_) : x(x_), y(y_) { } float x = -1.0; float y = -1.0; }; void Entity_clone(void) { flecs::world ecs; PositionInitialized v(10, 20); auto src = ecs.entity().add().set(v); auto dst = src.clone(false); test_assert(dst.has()); test_assert(dst.has()); const PositionInitialized *ptr = dst.get(); test_assert(ptr != NULL); test_int(ptr->x, -1); test_int(ptr->y, -1); } void Entity_clone_w_value(void) { flecs::world ecs; PositionInitialized v = {10, 20}; auto src = ecs.entity().add().set(v); auto dst = src.clone(); test_assert(dst.has()); test_assert(dst.has()); const PositionInitialized *ptr = dst.get(); test_assert(ptr != NULL); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_clone_to_existing(void) { flecs::world ecs; PositionInitialized v = {10, 20}; auto src = ecs.entity().add().set(v); auto dst = ecs.entity(); auto result = src.clone(true, dst); test_assert(result == dst); test_assert(dst.has()); test_assert(dst.has()); const PositionInitialized *ptr = dst.get(); test_assert(ptr != NULL); test_int(ptr->x, 10); test_int(ptr->y, 20); } void Entity_clone_to_existing_overlap(void) { install_test_abort(); flecs::world ecs; PositionInitialized v = {10, 20}; auto src = ecs.entity().add().set(v); auto dst = ecs.entity().add(); test_expect_abort(); src.clone(true, dst); } void Entity_set_doc_name(void) { flecs::world ecs; auto e = ecs.entity("foo_bar") .set_doc_name("Foo Bar"); test_str(e.name(), "foo_bar"); test_str(e.doc_name(), "Foo Bar"); } void Entity_set_doc_brief(void) { flecs::world ecs; auto e = ecs.entity("foo_bar") .set_doc_brief("Foo Bar"); test_str(e.name(), "foo_bar"); test_str(e.doc_brief(), "Foo Bar"); } void Entity_set_doc_detail(void) { flecs::world ecs; auto e = ecs.entity("foo_bar") .set_doc_detail("Foo Bar"); test_str(e.name(), "foo_bar"); test_str(e.doc_detail(), "Foo Bar"); } void Entity_set_doc_link(void) { flecs::world ecs; auto e = ecs.entity("foo_bar") .set_doc_link("Foo Bar"); test_str(e.name(), "foo_bar"); test_str(e.doc_link(), "Foo Bar"); } void Entity_entity_w_root_name(void) { flecs::world ecs; auto e = ecs.entity("::foo"); test_str(e.name(), "foo"); test_str(e.path(), "::foo"); } void Entity_entity_w_root_name_from_scope(void) { flecs::world ecs; auto p = ecs.entity("parent"); ecs.set_scope(p); auto e = ecs.entity("::foo"); ecs.set_scope(0); test_str(e.name(), "foo"); test_str(e.path(), "::foo"); } struct EntityType { }; void Entity_entity_w_type(void) { flecs::world ecs; auto e = ecs.entity(); test_str(e.name().c_str(), "EntityType"); test_str(e.path().c_str(), "::EntityType"); test_assert(!e.has()); auto e_2 = ecs.entity(); test_assert(e == e_2); } struct Turret { struct Base { }; }; struct Railgun { struct Base { }; struct Head { }; struct Beam { }; }; void Entity_prefab_hierarchy_w_types(void) { flecs::world ecs; auto turret = ecs.prefab(); auto turret_base = ecs.prefab(); test_assert(turret != 0); test_assert(turret_base != 0); test_assert(turret_base.has(flecs::ChildOf, turret)); test_str(turret.path().c_str(), "::Turret"); test_str(turret_base.path().c_str(), "::Turret::Base"); test_str(turret.symbol(), "Turret"); test_str(turret_base.symbol(), "Turret.Base"); auto railgun = ecs.prefab().is_a(); auto railgun_base = railgun.lookup("Base"); auto railgun_head = ecs.prefab(); auto railgun_beam = ecs.prefab(); test_assert(railgun != 0); test_assert(railgun_base != 0); test_assert(railgun_head != 0); test_assert(railgun_beam != 0); test_assert(railgun_base.has(flecs::ChildOf, railgun)); test_assert(railgun_head.has(flecs::ChildOf, railgun)); test_assert(railgun_beam.has(flecs::ChildOf, railgun)); test_str(railgun.path().c_str(), "::Railgun"); test_str(railgun_base.path().c_str(), "::Railgun::Base"); test_str(railgun_head.path().c_str(), "::Railgun::Head"); test_str(railgun_beam.path().c_str(), "::Railgun::Beam"); test_str(railgun.symbol().c_str(), "Railgun"); test_str(railgun_head.symbol().c_str(), "Railgun.Head"); test_str(railgun_beam.symbol().c_str(), "Railgun.Beam"); } struct Base { }; void Entity_prefab_hierarchy_w_root_types(void) { flecs::world ecs; auto turret = ecs.prefab(); auto turret_base = ecs.prefab().child_of(); test_assert(turret != 0); test_assert(turret_base != 0); test_assert(turret_base.has(flecs::ChildOf, turret)); test_str(turret.path().c_str(), "::Turret"); test_str(turret_base.path().c_str(), "::Turret::Base"); test_str(turret.symbol(), "Turret"); test_str(turret_base.symbol(), "Base"); auto inst = ecs.entity().is_a(); test_assert(inst != 0); auto inst_base = inst.lookup("Base"); test_assert(inst_base != 0); } void Entity_prefab_hierarchy_w_child_override(void) { flecs::world ecs; struct Foo {}; struct Bar {}; auto t = ecs.prefab(); auto tb = ecs.prefab().add(); test_assert(t != 0); test_assert(tb != 0); auto r = ecs.prefab().is_a(); auto rb = ecs.prefab().add(); test_assert(r != 0); test_assert(rb != 0); auto i = ecs.entity().is_a(); test_assert(i != 0); auto ib = i.lookup("Base"); test_assert(ib != 0); test_assert(ib.has()); test_assert(ib.has()); } void Entity_entity_w_nested_type(void) { flecs::world ecs; auto e = ecs.entity(); auto p = ecs.entity(); test_str(e.name().c_str(), "EntityType"); test_str(e.path().c_str(), "::Parent::EntityType"); test_assert(e.has(flecs::ChildOf, p)); test_assert(!e.has()); auto e_2 = ecs.entity(); test_assert(e == e_2); } void Entity_entity_array(void) { struct TagA {}; struct TagB {}; flecs::world ecs; flecs::to_array({ ecs.entity(), ecs.entity(), ecs.entity() }).each([](flecs::entity e) { e.add().add(); }); test_int( ecs.count(), 3 ); test_int( ecs.count(), 3 ); } void Entity_entity_w_type_defer(void) { flecs::world ecs; ecs.defer_begin(); auto e = ecs.entity(); ecs.defer_end(); test_str(e.name(), "Tag"); test_str(e.symbol(), "Tag"); test_assert(ecs.id() == e); } void Entity_add_if_true_T(void) { flecs::world ecs; auto e = ecs.entity(); e.add_if(true); test_assert( e.has()); } void Entity_add_if_false_T(void) { flecs::world ecs; auto e = ecs.entity(); e.add_if(false); test_assert( !e.has()); e.add(); test_assert( e.has()); e.add_if(false); test_assert( !e.has()); } void Entity_add_if_true_id(void) { flecs::world ecs; auto e = ecs.entity(); auto t = ecs.entity(); e.add_if(true, t); test_assert( e.has(t)); } void Entity_add_if_false_id(void) { flecs::world ecs; auto e = ecs.entity(); auto t = ecs.entity(); e.add_if(false, t); test_assert( !e.has(t)); e.add(t); test_assert( e.has(t)); e.add_if(false, t); test_assert( !e.has(t)); } void Entity_add_if_true_R_O(void) { flecs::world ecs; struct Rel { }; struct Obj { }; auto e = ecs.entity(); e.add_if(true); test_assert( (e.has()) ); } void Entity_add_if_false_R_O(void) { flecs::world ecs; struct Rel { }; struct Obj { }; auto e = ecs.entity(); e.add_if(false); test_assert( (!e.has())); e.add(); test_assert( (e.has())); e.add_if(false); test_assert( (!e.has())); } void Entity_add_if_true_R_o(void) { flecs::world ecs; struct Rel { }; auto e = ecs.entity(); auto o = ecs.entity(); e.add_if(true, o); test_assert( e.has(o)); } void Entity_add_if_false_R_o(void) { flecs::world ecs; struct Rel { }; auto e = ecs.entity(); auto o = ecs.entity(); e.add_if(false, o); test_assert( !e.has(o)); e.add(o); test_assert( e.has(o)); e.add_if(false, o); test_assert( !e.has(o)); } void Entity_add_if_true_r_o(void) { flecs::world ecs; auto e = ecs.entity(); auto r = ecs.entity(); auto o = ecs.entity(); e.add_if(true, r, o); test_assert( e.has(r, o)); } void Entity_add_if_false_r_o() { flecs::world ecs; auto e = ecs.entity(); auto r = ecs.entity(); auto o = ecs.entity(); e.add_if(false, r, o); test_assert( !e.has(r, o)); e.add(r, o); test_assert( e.has(r, o)); e.add_if(false, r, o); test_assert( !e.has(r, o)); } void Entity_add_if_exclusive_r_o(void) { flecs::world ecs; auto e = ecs.entity(); auto r = ecs.entity().add(flecs::Exclusive); auto o_1 = ecs.entity(); auto o_2 = ecs.entity(); e.add(r, o_1); test_assert(e.has(r, o_1)); e.add_if(true, r, o_2); test_assert(!e.has(r, o_1)); test_assert(e.has(r, o_2)); e.add_if(false, r, o_1); test_assert(!e.has(r, o_1)); test_assert(!e.has(r, o_2)); } void Entity_add_if_exclusive_R_o(void) { flecs::world ecs; struct First { }; ecs.component().add(flecs::Exclusive); auto e = ecs.entity(); auto o_1 = ecs.entity(); auto o_2 = ecs.entity(); e.add(o_1); test_assert(e.has(o_1)); e.add_if(true, o_2); test_assert(!e.has(o_1)); test_assert(e.has(o_2)); e.add_if(false, o_1); test_assert(!e.has(o_1)); test_assert(!e.has(o_2)); } void Entity_add_if_exclusive_R_O(void) { flecs::world ecs; struct R { }; struct O_1 { }; struct O_2 { }; ecs.component().add(flecs::Exclusive); auto e = ecs.entity(); e.add(); test_assert((e.has())); e.add_if(true); test_assert((!e.has())); test_assert((e.has())); e.add_if(false); test_assert((!e.has())); test_assert((!e.has())); } void Entity_add_if_pair_w_0_object(void) { flecs::world ecs; auto e = ecs.entity(); auto r = ecs.entity(); auto o_1 = ecs.entity(); e.add(r, o_1); test_assert(e.has(r, o_1)); e.add_if(0, r, 0); test_assert(!e.has(r, o_1)); test_assert(!e.has(r, flecs::Wildcard)); } void Entity_children_w_custom_relation(void) { flecs::world ecs; flecs::entity rel = ecs.entity(); flecs::entity parent = ecs.entity(); flecs::entity child_1 = ecs.entity().add(rel, parent); flecs::entity child_2 = ecs.entity().add(rel, parent); ecs.entity().child_of(parent); bool child_1_found = false; bool child_2_found = false; int32_t count = 0; parent.children(rel, [&](flecs::entity child) { if (child == child_1) { child_1_found = true; } else if (child == child_2) { child_2_found = true; } count ++; }); test_int(count, 2); test_assert(child_1_found == true); test_assert(child_2_found == true); } void Entity_children_w_custom_relation_type(void) { flecs::world ecs; struct Rel { }; flecs::entity parent = ecs.entity(); flecs::entity child_1 = ecs.entity().add(parent); flecs::entity child_2 = ecs.entity().add(parent); ecs.entity().child_of(parent); bool child_1_found = false; bool child_2_found = false; int32_t count = 0; parent.children([&](flecs::entity child) { if (child == child_1) { child_1_found = true; } else if (child == child_2) { child_2_found = true; } count ++; }); test_int(count, 2); test_assert(child_1_found == true); test_assert(child_2_found == true); } void Entity_children_w_this(void) { flecs::world ecs; int32_t count = 0; ecs.entity(flecs::This).children([&](flecs::entity) { count ++; }); test_assert(count == 0); } void Entity_children_w_wildcard(void) { flecs::world ecs; int32_t count = 0; ecs.entity(flecs::Wildcard).children([&](flecs::entity) { count ++; }); test_assert(count == 0); } void Entity_children_w_any(void) { flecs::world ecs; int32_t count = 0; ecs.entity(flecs::Any).children([&](flecs::entity) { count ++; }); test_assert(count == 0); } void Entity_children_from_root(void) { flecs::world ecs; int32_t count = 0; ecs.entity(0).children([&](flecs::entity e) { test_assert(e == ecs.entity("flecs")); count ++; }); test_assert(count == 1); } void Entity_children_from_root_world(void) { flecs::world ecs; int32_t count = 0; ecs.children([&](flecs::entity e) { test_assert(e == ecs.entity("flecs")); count ++; }); test_assert(count == 1); } void Entity_get_depth(void) { flecs::world world; flecs::entity e1 = world.entity(); flecs::entity e2 = world.entity().child_of(e1); flecs::entity e3 = world.entity().child_of(e2); flecs::entity e4 = world.entity().child_of(e3); test_int(0, e1.depth(flecs::ChildOf)); test_int(1, e2.depth(flecs::ChildOf)); test_int(2, e3.depth(flecs::ChildOf)); test_int(3, e4.depth(flecs::ChildOf)); } void Entity_get_depth_w_type(void) { flecs::world world; struct Rel { }; world.component().add(flecs::Traversable); flecs::entity e1 = world.entity(); flecs::entity e2 = world.entity().add(e1); flecs::entity e3 = world.entity().add(e2); flecs::entity e4 = world.entity().add(e3); test_int(0, e1.depth()); test_int(1, e2.depth()); test_int(2, e3.depth()); test_int(3, e4.depth()); } void Entity_to_view(void) { flecs::world world; flecs::entity e = world.entity(); flecs::entity_view ev = e.view(); test_assert(e == ev); } void Entity_to_view_from_stage(void) { flecs::world world; auto stage = world.get_stage(0); flecs::entity e = stage.entity(); flecs::entity_view ev = e.view(); test_assert(e == ev); test_assert(e.world() == stage); test_assert(ev.world() == world); } void Entity_set_alias(void) { flecs::world world; flecs::entity e = world.entity("parent::child"); e.set_alias("parent_child"); test_assert(e == world.lookup("parent::child")); test_assert(e == world.lookup("parent_child")); } void Entity_emplace_w_observer(void) { flecs::world ecs; ecs.observer() .event(flecs::OnAdd) .each([](flecs::entity e, Position&) { e.emplace(1.0f, 2.0f); }); auto e = ecs.entity() .emplace(10.0f, 20.0f); test_assert(e.has()); test_assert(e.has()); test_int(e.get()->x, 1); test_int(e.get()->y, 2); test_int(e.get()->x, 10); test_int(e.get()->y, 20); } void Entity_scoped_world(void) { flecs::world world; flecs::entity parent = world.entity(); flecs::entity child = parent.scope().entity(); test_assert(child.parent() == parent); } void Entity_entity_lookup_not_recursive(void) { flecs::world world; flecs::entity parent = world.entity("parent"); flecs::entity child = world.scope(parent).entity("child"); flecs::entity foo = world.scope(parent).entity("foo"); test_assert(child.lookup("foo") == 0); test_assert(child.lookup("foo", true) == foo); } void Entity_world_lookup_not_recursive(void) { flecs::world world; flecs::entity parent = world.entity("parent"); flecs::entity child = world.scope(parent).entity("child"); flecs::entity foo = world.scope(parent).entity("foo"); test_assert(world.scope(child).lookup("foo") == foo); test_assert(world.scope(child).lookup("foo", false) == 0); }