#include flecs::opaque std_string_support(flecs::world&) { flecs::opaque ts; // Let reflection framework know what kind of type this is ts.as_type(flecs::String); // Forward std::string value to (JSON/...) serializer ts.serialize([](const flecs::serializer *s, const std::string *data) { const char *value = data->c_str(); return s->value(flecs::String, &value); }); // Serialize string into std::string ts.assign_string([](std::string *data, const char *value) { *data = value; }); return ts; } template flecs::opaque, T> std_vector_support(flecs::world& world) { flecs::opaque, T> ts; // Let reflection framework know what kind of type this is ts.as_type(world.vector()); // Forward elements of std::vector value to (JSON/...) serializer ts.serialize([](const flecs::serializer *s, const std::vector *data) { for (const auto& el : *data) { s->value(el); } return 0; }); // Return vector count ts.count([](const std::vector *data) { return data->size(); }); // Ensure element exists, return ts.ensure_element([](std::vector *data, size_t elem) { if (data->size() <= elem) { data->resize(elem + 1); } return &data->data()[elem]; }); // Resize contents of vector ts.resize([](std::vector *data, size_t size) { data->resize(size); }); return ts; } void Meta_struct(void) { flecs::world ecs; struct Test { int32_t a; float b; }; auto c = ecs.component() .member("a") .member("b"); test_assert(c != 0); auto a = c.lookup("a"); test_assert(a != 0); test_assert( a.has() ); const flecs::Member *m = a.get(); test_uint(m->type, flecs::I32); auto b = c.lookup("b"); test_assert(b != 0); test_assert( b.has() ); m = b.get(); test_uint(m->type, flecs::F32); } void Meta_nested_struct(void) { flecs::world ecs; struct Test { int32_t x; }; struct Nested { Test a; }; auto t = ecs.component() .member("x"); auto n = ecs.component() .member(t, "a"); test_assert(n != 0); auto a = n.lookup("a"); test_assert(a != 0); test_assert( a.has() ); const flecs::Member *m = a.get(); test_uint(m->type, t); } void Meta_struct_w_portable_type(void) { flecs::world ecs; struct Test { uintptr_t a; uintptr_t b; flecs::entity_t c; flecs::entity_t d; }; auto t = ecs.component() .member("a") .member(flecs::Uptr, "b") .member("c") .member(flecs::Entity, "d"); test_assert(t != 0); auto a = t.lookup("a"); test_assert(a != 0); test_assert( a.has() ); const flecs::Member *m = a.get(); test_uint(m->type, ecs.component()); auto b = t.lookup("b"); test_assert(b != 0); test_assert( b.has() ); m = b.get(); test_uint(m->type, flecs::Uptr); auto c = t.lookup("c"); test_assert(c != 0); test_assert( c.has() ); m = c.get(); test_uint(m->type, flecs::U64); auto d = t.lookup("d"); test_assert(d != 0); test_assert( d.has() ); m = d.get(); test_uint(m->type, flecs::Entity); } void Meta_units(void) { struct Test { int32_t meters; int32_t custom_unit; }; flecs::world ecs; ecs.import(); auto custom_unit = ecs.entity("some_unit").unit("u"); test_assert(custom_unit != 0); test_str(custom_unit.name(), "some_unit"); const flecs::Unit *unit = custom_unit.get(); test_assert(unit != nullptr); test_str(unit->symbol, "u"); auto t = ecs.component() .member("meters") .member(custom_unit, "custom_unit"); test_assert(t != 0); flecs::entity m_meters = t.lookup("meters"); test_assert(m_meters != 0); const flecs::Member *m = m_meters.get(); test_assert(m != nullptr); test_uint(m->type, flecs::I32); test_uint(m->unit, ecs.id()); flecs::entity m_custom_unit = t.lookup("custom_unit"); test_assert(m_custom_unit != 0); m = m_custom_unit.get(); test_assert(m != nullptr); test_uint(m->type, flecs::I32); test_uint(m->unit, custom_unit); } void Meta_unit_w_quantity(void) { struct Test { int32_t m_1; int32_t m_2; }; flecs::world ecs; ecs.import(); auto custom_quantity = ecs.entity().quantity(); auto unit_1 = ecs.entity().unit("u1").quantity(custom_quantity); auto unit_2 = ecs.entity().unit("u2").quantity(); test_assert(unit_1.has(flecs::Quantity, custom_quantity)); test_assert(unit_2.has(flecs::Quantity, ecs.id())); auto t = ecs.component() .member(unit_1, "m_1") .member(unit_2, "m_2"); test_assert(t != 0); flecs::entity m_1 = t.lookup("m_1"); test_assert(m_1 != 0); const flecs::Member *m = m_1.get(); test_assert(m != nullptr); test_uint(m->type, flecs::I32); test_uint(m->unit, unit_1); flecs::entity m_2 = t.lookup("m_2"); test_assert(m_2 != 0); m = m_2.get(); test_assert(m != nullptr); test_uint(m->type, flecs::I32); test_uint(m->unit, unit_2); } void Meta_unit_w_prefix(void) { struct Test { int32_t m_1; int32_t m_2; }; flecs::world ecs; ecs.import(); auto prefix = ecs.entity().unit_prefix("p", 100, 1); auto unit_1 = ecs.entity().unit("U1"); const flecs::Unit *unit = unit_1.get(); test_assert(unit != nullptr); test_str(unit->symbol, "U1"); auto unit_2 = ecs.entity().unit(prefix, unit_1); unit = unit_2.get(); test_assert(unit != nullptr); test_str(unit->symbol, "pU1"); } void Meta_unit_w_over(void) { struct Test { int32_t m_1; int32_t m_2; }; flecs::world ecs; ecs.import(); auto prefix = ecs.entity().unit_prefix("p", 100, 1); auto unit_0 = ecs.entity().unit("U0"); const flecs::Unit *unit = unit_0.get(); test_assert(unit != nullptr); test_str(unit->symbol, "U0"); auto unit_1 = ecs.entity().unit("U1"); unit = unit_1.get(); test_assert(unit != nullptr); test_str(unit->symbol, "U1"); auto unit_2 = ecs.entity().unit(prefix, unit_1, unit_0); unit = unit_2.get(); test_assert(unit != nullptr); test_str(unit->symbol, "pU1/U0"); } void Meta_partial_struct(void) { flecs::world ecs; auto c = ecs.component() .member("x"); test_assert(c != 0); const flecs::Component *ptr = c.get(); test_int(ptr->size, 8); test_int(ptr->alignment, 4); auto xe = c.lookup("x"); test_assert(xe != 0); test_assert( xe.has() ); const flecs::Member *x = xe.get(); test_uint(x->type, flecs::F32); test_uint(x->offset, 0); } void Meta_partial_struct_custom_offset(void) { flecs::world ecs; auto c = ecs.component() .member("y", 1, offsetof(Position, y)); test_assert(c != 0); const flecs::Component *ptr = c.get(); test_int(ptr->size, 8); test_int(ptr->alignment, 4); auto xe = c.lookup("y"); test_assert(xe != 0); test_assert( xe.has() ); const flecs::Member *x = xe.get(); test_uint(x->type, flecs::F32); test_uint(x->offset, 4); } struct Toppings : flecs::bitmask { static constexpr uint32_t Bacon = 0x1; static constexpr uint32_t Lettuce = 0x2; static constexpr uint32_t Tomato = 0x4; }; struct Sandwich { uint32_t toppings; }; void Meta_bitmask(void) { flecs::world ecs; // Register components with reflection data ecs.component() .bit("Bacon", Toppings::Bacon) .bit("Lettuce", Toppings::Lettuce) .bit("Tomato", Toppings::Tomato); ecs.component() .member("toppings"); // Create entity with Position as usual auto e = ecs.entity() .set({Toppings::Bacon | Toppings::Lettuce}); // Convert position component to flecs expression string const Sandwich *ptr = e.get(); test_str(ecs.to_expr(ptr).c_str(), "{toppings: Lettuce|Bacon}"); } struct Int { int32_t v; }; struct TVector { std::vector v; }; struct TString { std::string v; }; struct TVectorString { std::vector v; std::string s; }; struct TStringVector { std::string s; std::vector v; }; struct TStringString { std::string s1; std::string s2; }; struct TVectorVector { std::vector v1; std::vector v2; }; struct TVectorVectorString { std::vector v1; std::vector v2; std::string s; }; struct TVectorStringVector { std::vector v1; std::string s; std::vector v2; }; static int Int_serialize(const flecs::serializer *s, const Int *data) { return s->value(data->v); } static int String_serialize(const flecs::serializer *s, const std::string *data) { const char *str = data->c_str(); return s->value(flecs::String, &str); } template int Vector_serialize(const flecs::serializer *ser, const std::vector *data) { for (const auto& el : *data) { if (ser->value(el)) { return -1; } } return 0; } void Meta_custom_i32_to_json(void) { flecs::world ecs; ecs.component().opaque(flecs::I32) .serialize(Int_serialize); Int v = {10}; flecs::string json = ecs.to_json(&v); test_str(json, "10"); } void Meta_custom_std_string_to_json(void) { flecs::world ecs; ecs.component().opaque(flecs::String) .serialize(String_serialize); std::string v = {"Hello World"}; flecs::string json = ecs.to_json(&v); test_str(json, "\"Hello World\""); } void Meta_custom_std_vector_i32_to_json(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); std::vector v = {1, 2, 3}; flecs::string json = ecs.to_json(&v); test_str(json, "[1, 2, 3]"); } void Meta_custom_std_vector_std_string_to_json(void) { flecs::world ecs; ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component>().opaque(ecs.vector(flecs::String)) .serialize(Vector_serialize); std::vector v = {"hello", "world", "foo"}; flecs::string json = ecs.to_json(&v); test_str(json, "[\"hello\", \"world\", \"foo\"]"); } void Meta_type_w_std_vector(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component() .member>("v"); TVector v = {{1, 2, 3}}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"v\":[1, 2, 3]}"); } void Meta_type_w_std_string(void) { flecs::world ecs; ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member("v"); TString v = {"hello world"}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"v\":\"hello world\"}"); } void Meta_type_w_std_vector_std_string(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member>("v") .member("s"); TVectorString v = {{1, 2, 3}, "hello world"}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"v\":[1, 2, 3], \"s\":\"hello world\"}"); } void Meta_type_w_std_string_std_vector(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member("s") .member>("v"); TStringVector v = {"hello world", {1, 2, 3}}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"s\":\"hello world\", \"v\":[1, 2, 3]}"); } void Meta_type_w_std_string_std_string(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member("s1") .member("s2"); TStringString v = {"hello world", "foo bar"}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"s1\":\"hello world\", \"s2\":\"foo bar\"}"); } void Meta_type_w_std_vector_std_vector(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member>("v1") .member>("v2"); TVectorVector v = {{1, 2, 3}, {4, 5, 6}}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"v1\":[1, 2, 3], \"v2\":[4, 5, 6]}"); } void Meta_type_w_std_vector_std_string_std_vector(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member>("v1") .member("s") .member>("v2"); TVectorStringVector v = {{1, 2, 3}, "hello world", {4, 5, 6}}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"v1\":[1, 2, 3], \"s\":\"hello world\", \"v2\":[4, 5, 6]}"); } void Meta_type_w_std_vector_std_vector_std_string(void) { flecs::world ecs; ecs.component>().opaque(ecs.vector()) .serialize(Vector_serialize); ecs.component().opaque(flecs::String) .serialize(String_serialize); ecs.component() .member>("v1") .member>("v2") .member("s"); TVectorVectorString v = {{1, 2, 3}, {4, 5, 6}, "hello world"}; flecs::string json = ecs.to_json(&v); test_str(json, "{\"v1\":[1, 2, 3], \"v2\":[4, 5, 6], \"s\":\"hello world\"}"); } void Meta_primitive_type(void) { flecs::world ecs; flecs::entity t = ecs.primitive(flecs::meta::I32); test_assert(t != 0); test_assert(t.has()); test_assert(t.has()); test_assert(t.has()); const flecs::Component *c = t.get(); test_assert(c != nullptr); test_int(c->size, 4); test_int(c->alignment, 4); const flecs::MetaType *mt = t.get(); test_assert(mt != nullptr); test_assert(mt->kind == flecs::meta::PrimitiveType); const flecs::Primitive *pt = t.get(); test_assert(pt != nullptr); test_assert(pt->kind == flecs::meta::I32); } void Meta_array_type(void) { flecs::world ecs; flecs::entity t = ecs.array(flecs::I32, 3); test_assert(t != 0); test_assert(t.has()); test_assert(t.has()); test_assert(t.has()); const flecs::Component *c = t.get(); test_assert(c != nullptr); test_int(c->size, 3 * 4); test_int(c->alignment, 4); const flecs::MetaType *mt = t.get(); test_assert(mt != nullptr); test_assert(mt->kind == flecs::meta::ArrayType); const flecs::Array *at = t.get(); test_assert(at != nullptr); test_assert(at->type == ecs.id()); test_int(at->count, 3); } void Meta_vector_type(void) { flecs::world ecs; flecs::entity t = ecs.vector(flecs::I32); test_assert(t != 0); test_assert(t.has()); test_assert(t.has()); test_assert(t.has()); const flecs::Component *c = t.get(); test_assert(c != nullptr); test_int(c->size, ECS_SIZEOF(ecs_vec_t)); test_int(c->alignment, ECS_SIZEOF(void*)); const flecs::MetaType *mt = t.get(); test_assert(mt != nullptr); test_assert(mt->kind == flecs::meta::VectorType); const flecs::Vector *vt = t.get(); test_assert(vt != nullptr); test_assert(vt->type == ecs.id()); } void Meta_i32_from_json(void) { flecs::world ecs; int32_t v = 0; const char *r = ecs.from_json(&v, "10"); test_str(r, ""); test_int(v, 10); } void Meta_struct_from_json(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); Position v = {}; const char *r = ecs.from_json(&v, "{\"x\":10, \"y\":20}"); test_str(r, ""); test_int(v.x, 10); test_int(v.y, 20); } void Meta_void_from_json(void) { flecs::world ecs; flecs::entity pos = ecs.component() .member("x") .member("y"); Position v = {}; void *ptr = &v; const char *r = ecs.from_json(pos, ptr, "{\"x\":10, \"y\":20}"); test_str(r, ""); test_int(v.x, 10); test_int(v.y, 20); } void Meta_entity_from_json_empty(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity(); const char *r = e.from_json("{}"); test_str(r, ""); } void Meta_entity_from_json_w_path(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity(); const char *r = e.from_json("{\"path\":\"ent\"}"); test_str(r, ""); test_assert(e != 0); test_str(e.name(), "ent"); } void Meta_entity_from_json_w_ids(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity(); const char *r = e.from_json("{\"path\":\"ent\", \"ids\":[[\"Position\"]]}"); test_str(r, ""); test_assert(e != 0); test_str(e.name(), "ent"); test_assert(e.has()); } void Meta_entity_from_json_w_values(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity(); const char *r = e.from_json("{\"path\":\"ent\", \"ids\":[[\"Position\"]], \"values\":[{\"x\":10, \"y\":20}]}"); test_str(r, ""); test_assert(e != 0); test_str(e.name(), "ent"); test_assert(e.has()); const Position *p = e.get(); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_type_json(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity() .set_json("{\"x\":10, \"y\":20}"); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_pair_R_T_json(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity() .set_json("{\"x\":10, \"y\":20}"); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_pair_R_t_json(void) { flecs::world ecs; ecs.component() .member("x") .member("y"); flecs::entity tgt = ecs.entity(); flecs::entity e = ecs.entity() .set_json(tgt, "{\"x\":10, \"y\":20}"); const Position *p = e.get(tgt); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_pair_r_T_json(void) { flecs::world ecs; flecs::entity pos = ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity() .set_json_second(pos, "{\"x\":10, \"y\":20}"); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_pair_r_t_json(void) { flecs::world ecs; flecs::entity pos = ecs.component() .member("x") .member("y"); flecs::entity tgt = ecs.entity(); flecs::entity e = ecs.entity() .set_json(pos, tgt, "{\"x\":10, \"y\":20}"); const Position *p = e.get(tgt); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_id_json(void) { flecs::world ecs; flecs::entity pos = ecs.component() .member("x") .member("y"); flecs::entity e = ecs.entity() .set_json(pos, "{\"x\":10, \"y\":20}"); const Position *p = e.get(); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } void Meta_ser_deser_std_string(void) { flecs::world world; world.component() .opaque(std_string_support); std::string v = "hello world"; test_str(world.to_json(&v).c_str(), "\"hello world\""); world.from_json(&v, "\"foo bar\""); test_str(world.to_json(&v).c_str(), "\"foo bar\""); } void Meta_ser_deser_std_vector_int(void) { flecs::world world; world.component>() .opaque(std_vector_support); std::vector v = {1, 2, 3}; test_str(world.to_json(&v).c_str(), "[1, 2, 3]"); world.from_json(&v, "[4, 5, 6]"); test_str(world.to_json(&v).c_str(), "[4, 5, 6]"); } void Meta_ser_deser_std_vector_std_string(void) { flecs::world world; world.component() .opaque(std_string_support); world.component>() .opaque(std_vector_support); std::vector v = {"foo", "bar"}; test_str(world.to_json(&v).c_str(), "[\"foo\", \"bar\"]"); world.from_json(&v, "[\"hello\", \"world\"]"); test_str(world.to_json(&v).c_str(), "[\"hello\", \"world\"]"); } struct CppTypes { std::string s; std::vector v; }; void Meta_ser_deser_type_w_std_string_std_vector_std_string(void) { flecs::world world; world.component() .opaque(std_string_support); world.component>() .opaque(std_vector_support); world.component() .member("s") .member>("v"); CppTypes v = {"hello", {"world"}}; test_str(world.to_json(&v).c_str(), "{\"s\":\"hello\", \"v\":[\"world\"]}"); world.from_json(&v, "{\"s\":\"foo\", \"v\":[\"bar\"]}"); test_str(world.to_json(&v).c_str(), "{\"s\":\"foo\", \"v\":[\"bar\"]}"); } void Meta_ser_deser_flecs_entity(void) { flecs::world world; flecs::entity e1 = world.entity("ent1"); flecs::entity e2 = world.entity("ent2"); flecs::entity v = e1; test_str(world.to_json(&v).c_str(), "\"ent1\""); world.from_json(&v, "\"ent2\""); test_str(world.to_json(&v).c_str(), "\"ent2\""); test_assert(v == e2); } struct CppEntity { flecs::entity entity; }; void Meta_world_ser_deser_flecs_entity(void) { flecs::world world; world.component() .member("entity"); flecs::entity e1 = world.entity("ent1"); flecs::entity e2 = world.entity("ent2").set({e1}); { const CppEntity *ptr = e2.get(); test_assert(ptr != nullptr); test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}"); } auto json = world.to_json(); world.from_json(json); test_assert(e1.is_alive()); test_assert(e2.is_alive()); { const CppEntity *ptr = e2.get(); test_assert(ptr != nullptr); test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}"); } } void Meta_new_world_ser_deser_flecs_entity(void) { flecs::world world; world.component() .member("entity"); flecs::entity e1 = world.entity("ent1"); flecs::entity e2 = world.entity("ent2").set({e1}); { const CppEntity *ptr = e2.get(); test_assert(ptr != nullptr); test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}"); } auto json = world.to_json(); flecs::world world2; world2.component() .member("entity"); world2.from_json(json); e1 = world2.lookup("ent1"); test_assert(e1 != 0); e2 = world2.lookup("ent2"); test_assert(e2 != 0); test_assert(e1.is_alive()); test_assert(e2.is_alive()); { const CppEntity *ptr = e2.get(); test_assert(ptr != nullptr); test_str(world2.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}"); } } void Meta_new_world_ser_deser_empty_flecs_entity(void) { flecs::world world; world.component() .member("entity"); flecs::entity e1 = world.entity("ent1").set({}); { const CppEntity *ptr = e1.get(); test_assert(ptr != nullptr); test_str(world.to_json(ptr).c_str(), "{\"entity\":0}"); } auto json = world.to_json(); flecs::world world2; world2.component() .member("entity"); world2.from_json(json); e1 = world2.lookup("ent1"); test_assert(e1 != 0); test_assert(e1.is_alive()); { const CppEntity *ptr = e1.get(); test_assert(ptr != nullptr); test_str(world2.to_json(ptr).c_str(), "{\"entity\":0}"); } } void Meta_opaque_vector_w_builder(void) { flecs::world world; world.component>().opaque(world.vector()) .serialize([](const flecs::serializer *s, const std::vector *data) { for (const auto& el : *data) { s->value(el); } return 0; }) .count([](const std::vector *data) { return data->size(); }) .ensure_element([](std::vector *data, size_t elem) { if (data->size() <= elem) { data->resize(elem + 1); } return &data->data()[elem]; }) .resize([](std::vector *data, size_t size) { data->resize(size); }); std::vector v = {}; world.from_json(&v, "[10, 20, 30]"); test_uint(v.size(), 3); test_int(v[0], 10); test_int(v[1], 20); test_int(v[2], 30); test_str(world.to_json(&v).c_str(), "[10, 20, 30]"); } void Meta_deser_entity_w_path(void) { flecs::world world; flecs::entity ent = world.entity("ent"); flecs::entity e; world.from_json(&e, "\"ent\""); test_assert(e == ent); test_str(e.path().c_str(), "::ent"); } enum class EnumWithBits : uint32_t { BitA = 0, BitB = 1 << 0, BitAll = 0xffffffff }; struct EnumWithBitsStruct { EnumWithBits bits = EnumWithBits::BitAll; }; void Meta_enum_w_bits(void) { flecs::world ecs; flecs::log::set_level(-4); /* It is illegal to register an enumeration as bitset, this test makes sure * the code doesn't crash. */ ecs.component() .bit("BitA", (uint32_t)EnumWithBits::BitA) .bit("BitB", (uint32_t)EnumWithBits::BitB) .bit("BitAll", (uint32_t)EnumWithBits::BitAll); ecs.component() .member("bits"); for (int i = 0; i < 30; i++) { ecs.entity() .child_of(ecs.entity()) .add(); } auto q = ecs.query(); auto s = q.iter().to_json(); test_str(s.c_str(), ""); } void Meta_value_range(void) { flecs::world ecs; flecs::entity s = ecs.component() .member("x").range(-1, 1) .member("y").range(-2, 2); flecs::entity x = s.lookup("x"); test_assert(x != 0); test_assert(x.has()); { const flecs::MemberRanges *ranges = x.get(); test_assert(ranges != nullptr); test_assert(ranges->value.min == -1); test_assert(ranges->value.max == 1); } flecs::entity y = s.lookup("y"); test_assert(y != 0); test_assert(y.has()); { const flecs::MemberRanges *ranges = y.get(); test_assert(ranges != nullptr); test_assert(ranges->value.min == -2); test_assert(ranges->value.max == 2); } } void Meta_warning_range(void) { flecs::world ecs; flecs::entity s = ecs.component() .member("x").warning_range(-1, 1) .member("y").warning_range(-2, 2); flecs::entity x = s.lookup("x"); test_assert(x != 0); test_assert(x.has()); { const flecs::MemberRanges *ranges = x.get(); test_assert(ranges != nullptr); test_assert(ranges->warning.min == -1); test_assert(ranges->warning.max == 1); } flecs::entity y = s.lookup("y"); test_assert(y != 0); test_assert(y.has()); { const flecs::MemberRanges *ranges = y.get(); test_assert(ranges != nullptr); test_assert(ranges->warning.min == -2); test_assert(ranges->warning.max == 2); } } void Meta_error_range(void) { flecs::world ecs; flecs::entity s = ecs.component() .member("x").error_range(-1, 1) .member("y").error_range(-2, 2); flecs::entity x = s.lookup("x"); test_assert(x != 0); test_assert(x.has()); { const flecs::MemberRanges *ranges = x.get(); test_assert(ranges != nullptr); test_assert(ranges->error.min == -1); test_assert(ranges->error.max == 1); } flecs::entity y = s.lookup("y"); test_assert(y != 0); test_assert(y.has()); { const flecs::MemberRanges *ranges = y.get(); test_assert(ranges != nullptr); test_assert(ranges->error.min == -2); test_assert(ranges->error.max == 2); } } void Meta_struct_member_ptr(void) { flecs::world ecs; struct Test { int32_t x; }; struct Test2 { double y; }; struct Nested { Test a; int pad; // This will be ignored Test2 b[2]; }; auto t = ecs.component() .member("x", &Test::x); auto t2 = ecs.component() .member("y", &Test2::y); auto n = ecs.component() .member("a", &Nested::a) .member("b", &Nested::b); { // Validate Test test_assert(t != 0); auto x = t.lookup("x"); test_assert(x != 0); test_assert(x.has()); const flecs::Member *xm = x.get(); test_uint(xm->type, flecs::I32); test_uint(xm->offset, offsetof(Test, x)); } { // Validate Test2 test_assert(t2 != 0); auto y = t2.lookup("y"); test_assert(y != 0); test_assert(y.has()); const flecs::Member *ym = y.get(); test_uint(ym->type, flecs::F64); test_uint(ym->offset, offsetof(Test2, y)); } // Validate Nested test_assert(n != 0); { auto a = n.lookup("a"); test_assert(a != 0); test_assert(a.has()); const flecs::Member *am = a.get(); test_uint(am->type, t); test_uint(am->offset, offsetof(Nested, a)); } { auto b = n.lookup("b"); test_assert(b != 0); test_assert(b.has()); const flecs::Member *bm = b.get(); test_uint(bm->type, t2); test_uint(bm->offset, offsetof(Nested, b)); test_uint(bm->count, 2); } } void Meta_struct_member_ptr_packed_struct(void) { flecs::world ecs; #if defined(__GNUC__) || defined(__clang__) struct PackedStruct { char a; int b; char pad[2]; double c; } __attribute__((__packed__)); #endif #if defined(_MSC_VER) #pragma pack(push, 1) struct PackedStruct { char a; int b; char pad[2]; double c; }; #pragma pack(pop) #endif auto s = ecs.component() .member("a", &PackedStruct::a) .member("b", &PackedStruct::b) .member("c", &PackedStruct::c); test_assert(s != 0); { auto a = s.lookup("a"); test_assert(a != 0); test_assert(a.has()); const flecs::Member *am = a.get(); test_uint(am->type, flecs::Char); test_uint(am->offset, offsetof(PackedStruct, a)); } { auto b = s.lookup("b"); test_assert(b != 0); test_assert(b.has()); const flecs::Member *bm = b.get(); test_uint(bm->type, flecs::I32); test_uint(bm->offset, offsetof(PackedStruct, b)); } { auto c = s.lookup("c"); test_assert(c != 0); test_assert(c.has()); const flecs::Member *cm = c.get(); test_uint(cm->type, flecs::F64); test_uint(cm->offset, offsetof(PackedStruct, c)); } } void Meta_component_as_array(void) { flecs::world ecs; flecs::entity c = ecs.component() .array(2); test_assert(c.has()); const flecs::Array *ptr = c.get(); test_assert(ptr != nullptr); test_assert(ptr->type == ecs.id()); test_int(ptr->count, 2); }