/
d.vision
/
division_engine_cpp
Обзор
Документация
Войти
/
d.vision
/
division_engine_cpp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
third_party/flecs-3.2.11/test/cpp_api/src/Meta.cpp
1 371 строка
34 KB
Den163
Added flecs and glm to the repo
31 май 2024, 23:08
31 май 2024, 23:08
5d252b3
Код
Авторство
О чём код?
#include <cpp_api.h> flecs::opaque<std::string> std_string_support(flecs::world&) { flecs::opaque<std::string> 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 <typename T> flecs::opaque<std::vector<T>, T> std_vector_support(flecs::world& world) { flecs::opaque<std::vector<T>, T> ts; // Let reflection framework know what kind of type this is ts.as_type(world.vector<T>()); // Forward elements of std::vector value to (JSON/...) serializer ts.serialize([](const flecs::serializer *s, const std::vector<T> *data) { for (const auto& el : *data) { s->value(el); } return 0; }); // Return vector count ts.count([](const std::vector<T> *data) { return data->size(); }); // Ensure element exists, return ts.ensure_element([](std::vector<T> *data, size_t elem) { if (data->size() <= elem) { data->resize(elem + 1); } return &data->data()[elem]; }); // Resize contents of vector ts.resize([](std::vector<T> *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<Test>() .member<int32_t>("a") .member<float>("b"); test_assert(c != 0); auto a = c.lookup("a"); test_assert(a != 0); test_assert( a.has<flecs::Member>() ); const flecs::Member *m = a.get<flecs::Member>(); test_uint(m->type, flecs::I32); auto b = c.lookup("b"); test_assert(b != 0); test_assert( b.has<flecs::Member>() ); m = b.get<flecs::Member>(); 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<Test>() .member<int32_t>("x"); auto n = ecs.component<Nested>() .member(t, "a"); test_assert(n != 0); auto a = n.lookup("a"); test_assert(a != 0); test_assert( a.has<flecs::Member>() ); const flecs::Member *m = a.get<flecs::Member>(); 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<Test>() .member<uintptr_t>("a") .member(flecs::Uptr, "b") .member<flecs::entity_t>("c") .member(flecs::Entity, "d"); test_assert(t != 0); auto a = t.lookup("a"); test_assert(a != 0); test_assert( a.has<flecs::Member>() ); const flecs::Member *m = a.get<flecs::Member>(); test_uint(m->type, ecs.component<uintptr_t>()); auto b = t.lookup("b"); test_assert(b != 0); test_assert( b.has<flecs::Member>() ); m = b.get<flecs::Member>(); test_uint(m->type, flecs::Uptr); auto c = t.lookup("c"); test_assert(c != 0); test_assert( c.has<flecs::Member>() ); m = c.get<flecs::Member>(); test_uint(m->type, flecs::U64); auto d = t.lookup("d"); test_assert(d != 0); test_assert( d.has<flecs::Member>() ); m = d.get<flecs::Member>(); test_uint(m->type, flecs::Entity); } void Meta_units(void) { struct Test { int32_t meters; int32_t custom_unit; }; flecs::world ecs; ecs.import<flecs::units>(); 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<flecs::Unit>(); test_assert(unit != nullptr); test_str(unit->symbol, "u"); auto t = ecs.component<Test>() .member<int32_t, flecs::units::length::Meters>("meters") .member<int32_t>(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<flecs::Member>(); test_assert(m != nullptr); test_uint(m->type, flecs::I32); test_uint(m->unit, ecs.id<flecs::units::length::Meters>()); flecs::entity m_custom_unit = t.lookup("custom_unit"); test_assert(m_custom_unit != 0); m = m_custom_unit.get<flecs::Member>(); 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<flecs::units>(); auto custom_quantity = ecs.entity().quantity(); auto unit_1 = ecs.entity().unit("u1").quantity(custom_quantity); auto unit_2 = ecs.entity().unit("u2").quantity<flecs::units::Length>(); test_assert(unit_1.has(flecs::Quantity, custom_quantity)); test_assert(unit_2.has(flecs::Quantity, ecs.id<flecs::units::Length>())); auto t = ecs.component<Test>() .member<int32_t>(unit_1, "m_1") .member<int32_t>(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<flecs::Member>(); 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<flecs::Member>(); 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<flecs::units>(); auto prefix = ecs.entity().unit_prefix("p", 100, 1); auto unit_1 = ecs.entity().unit("U1"); const flecs::Unit *unit = unit_1.get<flecs::Unit>(); test_assert(unit != nullptr); test_str(unit->symbol, "U1"); auto unit_2 = ecs.entity().unit(prefix, unit_1); unit = unit_2.get<flecs::Unit>(); 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<flecs::units>(); auto prefix = ecs.entity().unit_prefix("p", 100, 1); auto unit_0 = ecs.entity().unit("U0"); const flecs::Unit *unit = unit_0.get<flecs::Unit>(); test_assert(unit != nullptr); test_str(unit->symbol, "U0"); auto unit_1 = ecs.entity().unit("U1"); unit = unit_1.get<flecs::Unit>(); test_assert(unit != nullptr); test_str(unit->symbol, "U1"); auto unit_2 = ecs.entity().unit(prefix, unit_1, unit_0); unit = unit_2.get<flecs::Unit>(); test_assert(unit != nullptr); test_str(unit->symbol, "pU1/U0"); } void Meta_partial_struct(void) { flecs::world ecs; auto c = ecs.component<Position>() .member<float>("x"); test_assert(c != 0); const flecs::Component *ptr = c.get<flecs::Component>(); test_int(ptr->size, 8); test_int(ptr->alignment, 4); auto xe = c.lookup("x"); test_assert(xe != 0); test_assert( xe.has<flecs::Member>() ); const flecs::Member *x = xe.get<flecs::Member>(); 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<Position>() .member<float>("y", 1, offsetof(Position, y)); test_assert(c != 0); const flecs::Component *ptr = c.get<flecs::Component>(); test_int(ptr->size, 8); test_int(ptr->alignment, 4); auto xe = c.lookup("y"); test_assert(xe != 0); test_assert( xe.has<flecs::Member>() ); const flecs::Member *x = xe.get<flecs::Member>(); 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<Toppings>() .bit("Bacon", Toppings::Bacon) .bit("Lettuce", Toppings::Lettuce) .bit("Tomato", Toppings::Tomato); ecs.component<Sandwich>() .member<Toppings>("toppings"); // Create entity with Sandwich as usual auto e = ecs.entity() .set<Sandwich>({Toppings::Bacon | Toppings::Lettuce}); // Convert Sandwidth component to flecs expression string const Sandwich *ptr = e.get<Sandwich>(); test_str(ecs.to_expr(ptr).c_str(), "{toppings: Lettuce|Bacon}"); } struct Int { int32_t v; }; struct TVector { std::vector<int> v; }; struct TString { std::string v; }; struct TVectorString { std::vector<int> v; std::string s; }; struct TStringVector { std::string s; std::vector<int> v; }; struct TStringString { std::string s1; std::string s2; }; struct TVectorVector { std::vector<int> v1; std::vector<int> v2; }; struct TVectorVectorString { std::vector<int> v1; std::vector<int> v2; std::string s; }; struct TVectorStringVector { std::vector<int> v1; std::string s; std::vector<int> 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 <typename Elem> int Vector_serialize(const flecs::serializer *ser, const std::vector<Elem> *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<Int>().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<std::string>().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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); std::vector<int> 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<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<std::vector<std::string>>().opaque(ecs.vector(flecs::String)) .serialize(Vector_serialize<std::string>); std::vector<std::string> 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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<TVector>() .member<std::vector<int>>("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<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TString>() .member<std::string>("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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TVectorString>() .member<std::vector<int>>("v") .member<std::string>("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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TStringVector>() .member<std::string>("s") .member<std::vector<int>>("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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TStringString>() .member<std::string>("s1") .member<std::string>("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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TVectorVector>() .member<std::vector<int>>("v1") .member<std::vector<int>>("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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TVectorStringVector>() .member<std::vector<int>>("v1") .member<std::string>("s") .member<std::vector<int>>("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<std::vector<int>>().opaque(ecs.vector<int>()) .serialize(Vector_serialize<int>); ecs.component<std::string>().opaque(flecs::String) .serialize(String_serialize); ecs.component<TVectorVectorString>() .member<std::vector<int>>("v1") .member<std::vector<int>>("v2") .member<std::string>("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<flecs::Component>()); test_assert(t.has<flecs::MetaType>()); test_assert(t.has<flecs::Primitive>()); const flecs::Component *c = t.get<flecs::Component>(); test_assert(c != nullptr); test_int(c->size, 4); test_int(c->alignment, 4); const flecs::MetaType *mt = t.get<flecs::MetaType>(); test_assert(mt != nullptr); test_assert(mt->kind == flecs::meta::PrimitiveType); const flecs::Primitive *pt = t.get<flecs::Primitive>(); 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<flecs::Component>()); test_assert(t.has<flecs::MetaType>()); test_assert(t.has<flecs::Array>()); const flecs::Component *c = t.get<flecs::Component>(); test_assert(c != nullptr); test_int(c->size, 3 * 4); test_int(c->alignment, 4); const flecs::MetaType *mt = t.get<flecs::MetaType>(); test_assert(mt != nullptr); test_assert(mt->kind == flecs::meta::ArrayType); const flecs::Array *at = t.get<flecs::Array>(); test_assert(at != nullptr); test_assert(at->type == ecs.id<int32_t>()); 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<flecs::Component>()); test_assert(t.has<flecs::MetaType>()); test_assert(t.has<flecs::Vector>()); const flecs::Component *c = t.get<flecs::Component>(); 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<flecs::MetaType>(); test_assert(mt != nullptr); test_assert(mt->kind == flecs::meta::VectorType); const flecs::Vector *vt = t.get<flecs::Vector>(); test_assert(vt != nullptr); test_assert(vt->type == ecs.id<int32_t>()); } 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<Position>() .member<float>("x") .member<float>("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<Position>() .member<float>("x") .member<float>("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<Position>() .member<float>("x") .member<float>("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<Position>() .member<float>("x") .member<float>("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<Position>() .member<float>("x") .member<float>("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<Position>()); } void Meta_entity_from_json_w_values(void) { flecs::world ecs; ecs.component<Position>() .member<float>("x") .member<float>("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<Position>()); const Position *p = e.get<Position>(); test_int(p->x, 10); test_int(p->y, 20); } void Meta_set_type_json(void) { flecs::world ecs; ecs.component<Position>() .member<float>("x") .member<float>("y"); flecs::entity e = ecs.entity() .set_json<Position>("{\"x\":10, \"y\":20}"); const Position *p = e.get<Position>(); 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<Position>() .member<float>("x") .member<float>("y"); flecs::entity e = ecs.entity() .set_json<Position, Tag>("{\"x\":10, \"y\":20}"); const Position *p = e.get<Position, Tag>(); 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<Position>() .member<float>("x") .member<float>("y"); flecs::entity tgt = ecs.entity(); flecs::entity e = ecs.entity() .set_json<Position>(tgt, "{\"x\":10, \"y\":20}"); const Position *p = e.get<Position>(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<Position>() .member<float>("x") .member<float>("y"); flecs::entity e = ecs.entity() .set_json_second<Tag>(pos, "{\"x\":10, \"y\":20}"); const Position *p = e.get<Position, Tag>(); 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<Position>() .member<float>("x") .member<float>("y"); flecs::entity tgt = ecs.entity(); flecs::entity e = ecs.entity() .set_json(pos, tgt, "{\"x\":10, \"y\":20}"); const Position *p = e.get<Position>(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<Position>() .member<float>("x") .member<float>("y"); flecs::entity e = ecs.entity() .set_json(pos, "{\"x\":10, \"y\":20}"); const Position *p = e.get<Position>(); 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<std::string>() .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<std::vector<int>>() .opaque(std_vector_support<int>); std::vector<int> 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<std::string>() .opaque(std_string_support); world.component<std::vector<std::string>>() .opaque(std_vector_support<std::string>); std::vector<std::string> 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<std::string> v; }; void Meta_ser_deser_type_w_std_string_std_vector_std_string(void) { flecs::world world; world.component<std::string>() .opaque(std_string_support); world.component<std::vector<std::string>>() .opaque(std_vector_support<std::string>); world.component<CppTypes>() .member<std::string>("s") .member<std::vector<std::string>>("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<CppEntity>() .member<flecs::entity>("entity"); flecs::entity e1 = world.entity("ent1"); flecs::entity e2 = world.entity("ent2").set<CppEntity>({e1}); { const CppEntity *ptr = e2.get<CppEntity>(); 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<CppEntity>(); 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<CppEntity>() .member<flecs::entity>("entity"); flecs::entity e1 = world.entity("ent1"); flecs::entity e2 = world.entity("ent2").set<CppEntity>({e1}); { const CppEntity *ptr = e2.get<CppEntity>(); test_assert(ptr != nullptr); test_str(world.to_json(ptr).c_str(), "{\"entity\":\"ent1\"}"); } auto json = world.to_json(); flecs::world world2; world2.component<CppEntity>() .member<flecs::entity>("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<CppEntity>(); 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<CppEntity>() .member<flecs::entity>("entity"); flecs::entity e1 = world.entity("ent1").set<CppEntity>({}); { const CppEntity *ptr = e1.get<CppEntity>(); test_assert(ptr != nullptr); test_str(world.to_json(ptr).c_str(), "{\"entity\":0}"); } auto json = world.to_json(); flecs::world world2; world2.component<CppEntity>() .member<flecs::entity>("entity"); world2.from_json(json); e1 = world2.lookup("ent1"); test_assert(e1 != 0); test_assert(e1.is_alive()); { const CppEntity *ptr = e1.get<CppEntity>(); 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<std::vector<int>>().opaque<int>(world.vector<int>()) .serialize([](const flecs::serializer *s, const std::vector<int> *data) { for (const auto& el : *data) { s->value(el); } return 0; }) .count([](const std::vector<int> *data) { return data->size(); }) .ensure_element([](std::vector<int> *data, size_t elem) { if (data->size() <= elem) { data->resize(elem + 1); } return &data->data()[elem]; }) .resize([](std::vector<int> *data, size_t size) { data->resize(size); }); std::vector<int> 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<EnumWithBits>() .bit("BitA", (uint32_t)EnumWithBits::BitA) .bit("BitB", (uint32_t)EnumWithBits::BitB) .bit("BitAll", (uint32_t)EnumWithBits::BitAll); ecs.component<EnumWithBitsStruct>() .member<EnumWithBits>("bits"); for (int i = 0; i < 30; i++) { ecs.entity() .child_of(ecs.entity()) .add<EnumWithBitsStruct>(); } auto q = ecs.query<EnumWithBitsStruct>(); auto s = q.iter().to_json(); test_str(s.c_str(), ""); } void Meta_value_range(void) { flecs::world ecs; flecs::entity s = ecs.component<Position>() .member<float>("x").range(-1, 1) .member<float>("y").range(-2, 2); flecs::entity x = s.lookup("x"); test_assert(x != 0); test_assert(x.has<flecs::MemberRanges>()); { const flecs::MemberRanges *ranges = x.get<flecs::MemberRanges>(); 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<flecs::MemberRanges>()); { const flecs::MemberRanges *ranges = y.get<flecs::MemberRanges>(); 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<Position>() .member<float>("x").warning_range(-1, 1) .member<float>("y").warning_range(-2, 2); flecs::entity x = s.lookup("x"); test_assert(x != 0); test_assert(x.has<flecs::MemberRanges>()); { const flecs::MemberRanges *ranges = x.get<flecs::MemberRanges>(); 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<flecs::MemberRanges>()); { const flecs::MemberRanges *ranges = y.get<flecs::MemberRanges>(); 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<Position>() .member<float>("x").error_range(-1, 1) .member<float>("y").error_range(-2, 2); flecs::entity x = s.lookup("x"); test_assert(x != 0); test_assert(x.has<flecs::MemberRanges>()); { const flecs::MemberRanges *ranges = x.get<flecs::MemberRanges>(); 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<flecs::MemberRanges>()); { const flecs::MemberRanges *ranges = y.get<flecs::MemberRanges>(); 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<Test>() .member("x", &Test::x); auto t2 = ecs.component<Test2>() .member("y", &Test2::y); auto n = ecs.component<Nested>() .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<flecs::Member>()); const flecs::Member *xm = x.get<flecs::Member>(); 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<flecs::Member>()); const flecs::Member *ym = y.get<flecs::Member>(); 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<flecs::Member>()); const flecs::Member *am = a.get<flecs::Member>(); 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<flecs::Member>()); const flecs::Member *bm = b.get<flecs::Member>(); 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<PackedStruct>() .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<flecs::Member>()); const flecs::Member *am = a.get<flecs::Member>(); 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<flecs::Member>()); const flecs::Member *bm = b.get<flecs::Member>(); 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<flecs::Member>()); const flecs::Member *cm = c.get<flecs::Member>(); 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<Position>() .array<float>(2); test_assert(c.has<flecs::Array>()); const flecs::Array *ptr = c.get<flecs::Array>(); test_assert(ptr != nullptr); test_assert(ptr->type == ecs.id<float>()); test_int(ptr->count, 2); }