Files
PixelDefense/engine/libs/flecs/test/meta/src/SerializeIterToJson.c

2815 lines
74 KiB
C

#include <meta.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
void SerializeIterToJson_serialize_1_comps_empty(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_f32_t)},
{"y", ecs_id(ecs_f32_t)}
}
});
ecs_query_t *q = ecs_query_new(world, "Position");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_assert(json != NULL);
test_str(json, "{\"ids\":[[\"Position\"]], \"results\":[]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_1_comps_2_ents_same_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {30, 40});
ecs_query_t *q = ecs_query_new(world, "Position");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":10, \"y\":20}, "
"{\"x\":30, \"y\":40}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_2_comps_2_ents_same_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Mass);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Mass),
.members = {
{"value", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {30, 40});
ecs_set(world, e1, Mass, {1});
ecs_set(world, e2, Mass, {2});
ecs_query_t *q = ecs_query_new(world, "Position, Mass");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Mass\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Mass\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":10, \"y\":20}, "
"{\"x\":30, \"y\":40}"
"], ["
"{\"value\":1}, "
"{\"value\":2}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_1_tag_2_ents_same_table(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, MyTag);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, MyTag);
ecs_add(world, e2, MyTag);
ecs_query_t *q = ecs_query_new(world, "MyTag");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"MyTag\"]], "
"\"results\":[{"
"\"ids\":[[\"MyTag\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_1_tag_1_comp_2_ents_same_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_TAG(world, MyTag);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {30, 40});
ecs_add(world, e1, MyTag);
ecs_add(world, e2, MyTag);
ecs_query_t *q = ecs_query_new(world, "Position, MyTag");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"MyTag\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"MyTag\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":10, \"y\":20}, "
"{\"x\":30, \"y\":40}"
"], 0]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_1_tag_1_comp_4_ents_two_tables(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_TAG(world, TagA);
ECS_TAG(world, TagB);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_entity_t e3 = ecs_new_entity(world, "Hello");
ecs_entity_t e4 = ecs_new_entity(world, "World");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {30, 40});
ecs_set(world, e3, Position, {50, 60});
ecs_set(world, e4, Position, {70, 80});
ecs_add(world, e1, TagA);
ecs_add(world, e2, TagA);
ecs_add(world, e3, TagA);
ecs_add(world, e4, TagA);
ecs_add(world, e3, TagB);
ecs_add(world, e4, TagB);
ecs_query_t *q = ecs_query_new(world, "Position, TagA");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"TagA\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"TagA\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":10, \"y\":20}, "
"{\"x\":30, \"y\":40}"
"], 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"TagA\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Hello\", \"World\""
"], "
"\"values\":[["
"{\"x\":50, \"y\":60}, "
"{\"x\":70, \"y\":80}"
"], 0]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_2_comps_1_owned_2_ents(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Mass);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Mass),
.members = {
{"value", ecs_id(ecs_i32_t)},
}
});
ecs_entity_t base = ecs_new_entity(world, "Base");
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, base, Mass, {100});
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {30, 40});
ecs_add_pair(world, e1, EcsIsA, base);
ecs_add_pair(world, e2, EcsIsA, base);
ecs_query_t *q = ecs_query_new(world, "Position, Mass(up)");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Mass\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Mass\"]], "
"\"sources\":[0, \"Base\"], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":10, \"y\":20}, "
"{\"x\":30, \"y\":40}"
"], {"
"\"value\":100"
"}]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_pair_wildcard(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Rel);
ECS_TAG(world, ObjA);
ECS_TAG(world, ObjB);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add_pair(world, e1, Rel, ObjA);
ecs_add_pair(world, e2, Rel, ObjB);
ecs_query_t *q = ecs_query_new(world, "(Rel, *)");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Rel\",\"*\"]], "
"\"results\":[{"
"\"ids\":[[\"Rel\",\"ObjA\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\""
"]"
"}, {"
"\"ids\":[[\"Rel\",\"ObjB\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_var(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Rel);
ECS_TAG(world, ObjA);
ECS_TAG(world, ObjB);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add_pair(world, e1, Rel, ObjA);
ecs_add_pair(world, e2, Rel, ObjB);
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.expr = "(Rel, $X)"
});
ecs_iter_t it = ecs_rule_iter(world, r);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Rel\",\"*\"]], "
"\"vars\":[\"X\"], "
"\"results\":[{"
"\"ids\":[[\"Rel\",\"ObjA\"]], "
"\"sources\":[0], "
"\"vars\":[\"ObjA\"], "
"\"entities\":["
"\"Foo\""
"]"
"}, {"
"\"ids\":[[\"Rel\",\"ObjB\"]], "
"\"sources\":[0], "
"\"vars\":[\"ObjB\"], "
"\"entities\":["
"\"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_2_vars(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, RelX);
ECS_TAG(world, ObjA);
ECS_TAG(world, ObjB);
ECS_TAG(world, RelY);
ECS_TAG(world, ObjC);
ECS_TAG(world, ObjD);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add_pair(world, e1, RelX, ObjA);
ecs_add_pair(world, e2, RelX, ObjB);
ecs_add_pair(world, e1, RelY, ObjC);
ecs_add_pair(world, e2, RelY, ObjD);
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.expr = "(RelX, $X), (RelY, $Y)"
});
ecs_iter_t it = ecs_rule_iter(world, r);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"RelX\",\"*\"], [\"RelY\",\"*\"]], "
"\"vars\":[\"X\", \"Y\"], "
"\"results\":[{"
"\"ids\":[[\"RelX\",\"ObjA\"], [\"RelY\",\"ObjC\"]], "
"\"sources\":[0, 0], "
"\"vars\":[\"ObjA\", \"ObjC\"], "
"\"entities\":["
"\"Foo\""
"]"
"}, {"
"\"ids\":[[\"RelX\",\"ObjB\"], [\"RelY\",\"ObjD\"]], "
"\"sources\":[0, 0], "
"\"vars\":[\"ObjB\", \"ObjD\"], "
"\"entities\":["
"\"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_1_tags(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, TagA);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, TagA);
ecs_add(world, e2, TagA);
ecs_query_t *q = ecs_query_new(world, "TagA");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"TagA\"]], "
"\"results\":[{"
"\"ids\":[[\"TagA\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_2_tags(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, TagA);
ECS_TAG(world, TagB);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, TagA);
ecs_add(world, e1, TagB);
ecs_add(world, e2, TagA);
ecs_add(world, e2, TagB);
ecs_query_t *q = ecs_query_new(world, "TagA, TagB");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"TagA\"], [\"TagB\"]], "
"\"results\":[{"
"\"ids\":[[\"TagA\"], [\"TagB\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_1_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, Position);
ecs_add(world, e2, Position);
ecs_query_t *q = ecs_query_new(world, "Position");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Position\"]], "
"\"type_info\":{\"Position\":0}, "
"\"results\":[{"
"\"ids\":[[\"Position\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[0]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_2_components(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, Position);
ecs_add(world, e2, Position);
ecs_add(world, e1, Velocity);
ecs_add(world, e2, Velocity);
ecs_query_t *q = ecs_query_new(world, "Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"type_info\":{\"Position\":0, \"Velocity\":0}, "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[0, 0]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_1_struct(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "Position"}),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
test_assert(t == ecs_id(Position));
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, Position);
ecs_add(world, e2, Position);
ecs_query_t *q = ecs_query_new(world, "Position");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Position\"]], "
"\"type_info\":{\"Position\":{\"x\":[\"int\"], \"y\":[\"int\"]}}, "
"\"results\":[{"
"\"ids\":[[\"Position\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":0, \"y\":0}, "
"{\"x\":0, \"y\":0}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_1_component_1_struct(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "Position"}),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
test_assert(t == ecs_id(Position));
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, Position);
ecs_add(world, e2, Position);
ecs_add(world, e1, Velocity);
ecs_add(world, e2, Velocity);
ecs_query_t *q = ecs_query_new(world, "Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"type_info\":{"
"\"Position\":{\"x\":[\"int\"], \"y\":[\"int\"]}, "
"\"Velocity\":0"
"}, "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":0, \"y\":0}, "
"{\"x\":0, \"y\":0}"
"], 0]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_2_structs(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "Position"}),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
test_assert(t == ecs_id(Position));
t = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "Velocity"}),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
test_assert(t == ecs_id(Velocity));
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add(world, e1, Position);
ecs_add(world, e2, Position);
ecs_add(world, e1, Velocity);
ecs_add(world, e2, Velocity);
ecs_query_t *q = ecs_query_new(world, "Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"type_info\":{"
"\"Position\":{\"x\":[\"int\"], \"y\":[\"int\"]}, "
"\"Velocity\":{\"x\":[\"int\"], \"y\":[\"int\"]}"
"}, "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"x\":0, \"y\":0}, "
"{\"x\":0, \"y\":0}"
"], ["
"{\"x\":0, \"y\":0}, "
"{\"x\":0, \"y\":0}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_w_unit(void) {
typedef struct {
ecs_i32_t value;
} T;
ecs_world_t *world = ecs_init();
ecs_entity_t u = ecs_unit_init(world, &(ecs_unit_desc_t){
.entity = ecs_entity(world, {.name = "celsius"}),
.symbol = "°"
});
test_assert(u != 0);
ecs_entity_t ecs_id(T) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "T"}),
.members = {
{"value", ecs_id(ecs_i32_t), .unit = u}
}
});
test_assert(ecs_id(T) != 0);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, e1, T, {24});
ecs_set(world, e2, T, {16});
ecs_query_t *q = ecs_query_new(world, "T");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"T\"]], "
"\"type_info\":{"
"\"T\":{\"value\":[\"int\", {"
"\"unit\":\"celsius\", \"symbol\":\"°\"}]"
"}"
"}, "
"\"results\":[{"
"\"ids\":[[\"T\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"value\":24}, "
"{\"value\":16}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_w_unit_quantity(void) {
typedef struct {
ecs_i32_t value;
} T;
ecs_world_t *world = ecs_init();
ecs_entity_t qt = ecs_quantity_init(world, &(ecs_entity_desc_t){
.name = "temperature"
});
test_assert(qt != 0);
ecs_entity_t u = ecs_unit_init(world, &(ecs_unit_desc_t){
.entity = ecs_entity(world, {.name = "celsius"}),
.symbol = "°",
.quantity = qt
});
test_assert(u != 0);
ecs_entity_t ecs_id(T) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "T"}),
.members = {
{"value", ecs_id(ecs_i32_t), .unit = u}
}
});
test_assert(ecs_id(T) != 0);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, e1, T, {24});
ecs_set(world, e2, T, {16});
ecs_query_t *q = ecs_query_new(world, "T");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"T\"]], "
"\"type_info\":{"
"\"T\":{\"value\":[\"int\", {"
"\"unit\":\"celsius\", \"symbol\":\"°\", \"quantity\":\"temperature\"}]"
"}"
"}, "
"\"results\":[{"
"\"ids\":[[\"T\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"value\":24}, "
"{\"value\":16}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_type_info_w_unit_over(void) {
typedef struct {
ecs_i32_t value;
} T;
ecs_world_t *world = ecs_init();
ecs_entity_t u_1 = ecs_unit_init(world, &(ecs_unit_desc_t){
.entity = ecs_entity(world, {.name = "seconds"}),
.symbol = "s"
});
test_assert(u_1 != 0);
ecs_entity_t u_2 = ecs_unit_init(world, &(ecs_unit_desc_t){
.entity = ecs_entity(world, {.name = "meters"}),
.symbol = "m"
});
test_assert(u_2 != 0);
ecs_entity_t u_3 = ecs_unit_init(world, &(ecs_unit_desc_t){
.entity = ecs_entity(world, {.name = "meters_per_second"}),
.base = u_2,
.over = u_1
});
test_assert(u_3 != 0);
ecs_entity_t ecs_id(T) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "T"}),
.members = {
{"value", ecs_id(ecs_i32_t), .unit = u_3}
}
});
test_assert(ecs_id(T) != 0);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_set(world, e1, T, {24});
ecs_set(world, e2, T, {16});
ecs_query_t *q = ecs_query_new(world, "T");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_type_info = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"T\"]], "
"\"type_info\":{"
"\"T\":{\"value\":[\"int\", {"
"\"unit\":\"meters_per_second\", \"symbol\":\"m/s\"}]"
"}"
"}, "
"\"results\":[{"
"\"ids\":[[\"T\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"Foo\", \"Bar\""
"], "
"\"values\":[["
"{\"value\":24}, "
"{\"value\":16}"
"]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_entity_label(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e1 = ecs_new_entity(world, "foo_bar");
ecs_entity_t e2 = ecs_new_entity(world, "hello_world");
ecs_doc_set_name(world, e2, "Hello World");
ecs_add(world, e1, Tag);
ecs_add(world, e2, Tag);
ecs_query_t *q = ecs_query_new(world, "Tag");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_entity_labels = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Tag\"]], "
"\"results\":[{"
"\"ids\":[[\"Tag\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"foo_bar\""
"]"
"}, {"
"\"ids\":[[\"Tag\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"hello_world\""
"], "
"\"entity_labels\":["
"\"Hello World\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_var_labels(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Rel);
ECS_TAG(world, ObjA);
ECS_TAG(world, ObjB);
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_entity_t e2 = ecs_new_entity(world, "Bar");
ecs_add_pair(world, e1, Rel, ObjA);
ecs_add_pair(world, e2, Rel, ObjB);
ecs_doc_set_name(world, ObjA, "Object A");
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.expr = "(Rel, $X)"
});
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_variable_labels = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Rel\",\"*\"]], "
"\"vars\":[\"X\"], "
"\"results\":[{"
"\"ids\":[[\"Rel\",\"ObjA\"]], "
"\"sources\":[0], "
"\"vars\":[\"ObjA\"], "
"\"var_labels\":[\"Object A\"], "
"\"entities\":["
"\"Foo\""
"]"
"}, {"
"\"ids\":[[\"Rel\",\"ObjB\"]], "
"\"sources\":[0], "
"\"vars\":[\"ObjB\"], "
"\"var_labels\":[\"ObjB\"], "
"\"entities\":["
"\"Bar\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_color(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e1 = ecs_new_entity(world, "foo_bar");
ecs_entity_t e2 = ecs_new_entity(world, "hello_world");
ecs_doc_set_color(world, e2, "#47B576");
ecs_add(world, e1, Tag);
ecs_add(world, e2, Tag);
ecs_query_t *q = ecs_query_new(world, "Tag");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_colors = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{"
"\"ids\":[[\"Tag\"]], "
"\"results\":[{"
"\"ids\":[[\"Tag\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"foo_bar\""
"]"
"}, {"
"\"ids\":[[\"Tag\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"hello_world\""
"], "
"\"colors\":["
"\"#47B576\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_var_component(void) {
typedef struct {
ecs_i32_t x;
} T;
ecs_world_t *world = ecs_init();
ECS_TAG(world, Rel);
ECS_TAG(world, Obj);
ecs_entity_t ecs_id(T) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "T"}),
.members = {
{"x", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e = ecs_new_entity(world, "Foo");
ecs_add_pair(world, e, Rel, Obj);
ecs_set(world, Obj, T, {10});
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.expr = "(Rel, $X), T($X)"
});
ecs_iter_t it = ecs_rule_iter(world, r);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Rel\",\"*\"], [\"T\"]], "
"\"vars\":[\"X\"], "
"\"results\":[{"
"\"ids\":[[\"Rel\",\"Obj\"], [\"T\"]], "
"\"sources\":[0, \"Obj\"], "
"\"vars\":[\"Obj\"], "
"\"entities\":["
"\"Foo\""
"], "
"\"values\":[0, {\"x\":10}]"
"}]"
"}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_optional_tag(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, TagA);
ECS_TAG(world, TagB);
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_add(world, e1, TagB);
ecs_add(world, e1, TagA);
ecs_add(world, e2, TagA);
ecs_query_t *q = ecs_query_new(world, "TagA, ?TagB");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"TagA\"], [\"TagB\"]], "
"\"results\":[{"
"\"ids\":[[\"TagA\"], [\"TagB\"]], "
"\"sources\":[0, 0], "
"\"is_set\":[true, true], "
"\"entities\":["
"\"e1\""
"]"
"}, {"
"\"ids\":[[\"TagA\"], [\"TagB\"]], "
"\"sources\":[0, 0], "
"\"is_set\":[true, false], "
"\"entities\":["
"\"e2\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_optional_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_add(world, e1, Velocity);
ecs_add(world, e1, Position);
ecs_add(world, e2, Position);
ecs_query_t *q = ecs_query_new(world, "Position, ?Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"is_set\":[true, true], "
"\"entities\":["
"\"e1\""
"], "
"\"values\":[0, 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"is_set\":[true, false], "
"\"entities\":["
"\"e2\""
"], "
"\"values\":[0, 0]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_optional_reflected_component(void) {
ecs_world_t *world = ecs_init();
ecs_entity_t ecs_id(Position) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "Position"}),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t ecs_id(Velocity) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "Velocity"}),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_set(world, e1, Velocity, {1, 2});
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {10, 20});
ecs_query_t *q = ecs_query_new(world, "Position, ?Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"is_set\":[true, true], "
"\"entities\":["
"\"e1\""
"], "
"\"values\":[[{\"x\":10, \"y\":20}], [{\"x\":1, \"y\":2}]]"
"}, {"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"is_set\":[true, false], "
"\"entities\":["
"\"e2\""
"], "
"\"values\":[[{\"x\":10, \"y\":20}], []]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_inout_filter_tag(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, TagA);
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_add(world, e1, TagA);
ecs_query_t *q = ecs_query_new(world, "[none] TagA");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"TagA\"]], "
"\"results\":[{"
"\"ids\":[[\"TagA\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"e1\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_inout_filter_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e1, Velocity, {1, 2});
ecs_query_t *q = ecs_query_new(world, "[none] Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"e1\""
"], "
"\"values\":[0, [{\"x\":1, \"y\":2}]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_inout_filter_reflected_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e1, Velocity, {1, 2});
ecs_query_t *q = ecs_query_new(world, "[none] Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"e1\""
"], "
"\"values\":[0, [{\"x\":1, \"y\":2}]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_inout_out_tag(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, TagA);
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_add(world, e1, TagA);
ecs_query_t *q = ecs_query_new(world, "[out] TagA");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"TagA\"]], "
"\"results\":[{"
"\"ids\":[[\"TagA\"]], "
"\"sources\":[0], "
"\"entities\":["
"\"e1\""
"]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_inout_out_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e1, Velocity, {1, 2});
ecs_query_t *q = ecs_query_new(world, "[out] Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"e1\""
"], "
"\"values\":[0, [{\"x\":1, \"y\":2}]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_inout_out_reflected_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e1, Velocity, {1, 2});
ecs_query_t *q = ecs_query_new(world, "[out] Position, Velocity");
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"results\":[{"
"\"ids\":[[\"Position\"], [\"Velocity\"]], "
"\"sources\":[0, 0], "
"\"entities\":["
"\"e1\""
"], "
"\"values\":[0, [{\"x\":1, \"y\":2}]]"
"}]"
"}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_component_from_var(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {10, 20});
ecs_rule_t *r = ecs_rule_new(world, "Position($E)");
ecs_iter_t it = ecs_rule_iter(world, r);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"]], "
"\"vars\":[\"E\"], "
"\"results\":[{"
"\"ids\":[[\"Position\"]], "
"\"sources\":[\"e1\"], "
"\"vars\":[\"e1\"], "
"\"values\":[{\"x\":10, \"y\":20}]"
"}]"
"}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_ids(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_query_t *q = ecs_query_new(world, "Tag");
ecs_entity_t e = ecs_new_entity(world, "e");
ecs_add(world, e, Tag);
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_ids = false;
desc.serialize_entity_ids = true;
desc.serialize_values = false;
desc.serialize_is_set = false;
desc.serialize_sources = false;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
char *expect = ecs_asprintf(
"{\"ids\":[[\"Tag\"]], \"results\":[{\"entities\":[\"e\"], \"entity_ids\":[%u]}]}",
(uint32_t)e);
test_str(json, expect);
ecs_os_free(json);
ecs_os_free(expect);
ecs_fini(world);
}
void SerializeIterToJson_serialize_ids_2_entities(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_query_t *q = ecs_query_new(world, "Tag");
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_add(world, e1, Tag);
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_add(world, e2, Tag);
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_ids = false;
desc.serialize_entity_ids = true;
desc.serialize_values = false;
desc.serialize_is_set = false;
desc.serialize_sources = false;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
char *expect = ecs_asprintf(
"{\"ids\":[[\"Tag\"]], \"results\":[{\"entities\":[\"e1\", \"e2\"], \"entity_ids\":[%u, %u]}]}",
(uint32_t)e1, (uint32_t)e2);
test_str(json, expect);
ecs_os_free(json);
ecs_os_free(expect);
ecs_fini(world);
}
void SerializeIterToJson_serialize_variable_ids(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_rule_t *q = ecs_rule_new(world, "Tag($Entity)");
ecs_entity_t e = ecs_new_entity(world, "e");
ecs_add(world, e, Tag);
ecs_iter_t it = ecs_rule_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_ids = false;
desc.serialize_variable_ids = true;
desc.serialize_values = false;
desc.serialize_is_set = false;
desc.serialize_sources = false;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
char *expect = ecs_asprintf(
"{\"ids\":[[\"Tag\"]], \"vars\":[\"Entity\"], \"results\":[{\"vars\":[\"e\"], \"var_ids\":[%u]}]}",
(uint32_t)e);
test_str(json, expect);
ecs_os_free(json);
ecs_os_free(expect);
ecs_rule_fini(q);
ecs_fini(world);
}
void SerializeIterToJson_serialize_variable_ids_2_entities(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_rule_t *q = ecs_rule_new(world, "Tag($Entity)");
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_add(world, e1, Tag);
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_add(world, e2, Tag);
ecs_iter_t it = ecs_rule_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_ids = false;
desc.serialize_variable_ids = true;
desc.serialize_values = false;
desc.serialize_is_set = false;
desc.serialize_sources = false;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
char *expect = ecs_asprintf(
"{\"ids\":[[\"Tag\"]], \"vars\":[\"Entity\"], \"results\":[{\"vars\":[\"e1\"], \"var_ids\":[%u]}, {\"vars\":[\"e2\"], \"var_ids\":[%u]}]}",
(uint32_t)e1, (uint32_t)e2);
test_str(json, expect);
ecs_os_free(json);
ecs_os_free(expect);
ecs_rule_fini(q);
ecs_fini(world);
}
void SerializeIterToJson_serialize_invalid_value(void) {
typedef enum {
Red, Blue, Green
} E;
typedef struct {
E x;
} T;
ecs_world_t *world = ecs_init();
ecs_entity_t e = ecs_enum_init(world, &(ecs_enum_desc_t){
.constants = {
{"Red"}, {"Blue"}, {"Green"}
}
});
ecs_entity_t ecs_id(T) = ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_entity(world, {.name = "T"}),
.members = {
{"x", e}
}
});
for (int i = 0; i < 10; i ++) {
ecs_entity_t p = ecs_new_id(world);
ecs_entity_t e = ecs_new_w_pair(world, EcsChildOf, p);
ecs_set(world, e, T, {4});
}
ecs_query_t *q = ecs_query_new(world, "T");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_log_set_level(-4);
char *json = ecs_iter_to_json(world, &it, NULL);
test_assert(json == NULL);
ecs_fini(world);
}
void SerializeIterToJson_serialize_recycled_pair_id(void) {
ecs_world_t *world = ecs_init();
ecs_entity_t rel = ecs_new_entity(world, "Rel");
ecs_entity_t tgt = ecs_new_entity(world, "Tgt");
ecs_delete(world, tgt);
tgt = ecs_new_entity(world, "Tgt");
ecs_entity_t e = ecs_new_w_pair(world, rel, tgt);
ecs_set_name(world, e, "ent");
ecs_query_t *q = ecs_query(world, {
.filter.terms[0] = {
.first.id = rel,
.second.id = tgt
}
});
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_assert(json != NULL);
test_str(json, "{\"ids\":[[\"Rel\",\"Tgt\"]], \"results\":["
"{\"ids\":[[\"Rel\",\"Tgt\"]], \"sources\":[0], \"entities\":[\"ent\"]}"
"]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_alert(void) {
ecs_world_t *world = ecs_init();
ECS_IMPORT(world, FlecsAlerts);
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_alert(world, {
.entity = ecs_new_entity(world, "position_without_velocity"),
.filter.expr = "Position, !Velocity",
});
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {30, 40});
ecs_set(world, e1, Velocity, {1, 2});
ecs_progress(world, 1.0); /* Evaluate alert logic */
ecs_query_t *q = ecs_query_new(world, "Position");
test_assert(q != NULL);
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = ECS_ITER_TO_JSON_INIT;
desc.serialize_ids = false;
desc.serialize_values = false;
desc.serialize_is_set = false;
desc.serialize_sources = false;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"ids\":[[\"Position\"]], \"results\":["
"{\"entities\":[\"e1\"]}, "
"{\"entities\":[\"e2\"], \"alerts\":true}]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_no_this_alert_imported(void) {
ecs_world_t *world = ecs_init();
ECS_IMPORT(world, FlecsAlerts);
ECS_COMPONENT(world, Position);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "Foo");
ecs_set(world, e1, Position, {10, 20});
ecs_rule_t *q = ecs_rule(world, {
.expr = "Position($x)"
});
ecs_iter_t it = ecs_rule_iter(world, q);
char *json = ecs_iter_to_json(world, &it, NULL);
test_str(json,
"{"
"\"ids\":[[\"Position\"]], "
"\"vars\":[\"x\"], "
"\"results\":[{"
"\"ids\":[[\"Position\"]], "
"\"sources\":[\"Foo\"], "
"\"vars\":[\"Foo\"], "
"\"values\":["
"{\"x\":10, \"y\":20}"
"]"
"}]"
"}");
ecs_os_free(json);
ecs_rule_fini(q);
ecs_fini(world);
}
void SerializeIterToJson_serialize_paged_iterator(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_set(world, 0, Position, {10, 20});
ecs_entity_t e2 = ecs_set(world, 0, Position, {10, 20});
ecs_entity_t e3 = ecs_set(world, 0, Position, {20, 30});
ecs_entity_t e4 = ecs_set(world, 0, Position, {30, 40});
ecs_set(world, 0, Position, {10, 20});
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.terms = {{ .id = ecs_id(Position) }}
});
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_t pit = ecs_page_iter(&it, 1, 3);
test_bool(true, ecs_page_next(&pit));
test_int(3, pit.count);
test_uint(e2, pit.entities[0]);
test_uint(e3, pit.entities[1]);
test_uint(e4, pit.entities[2]);
Position *p = ecs_field(&pit, Position, 1);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_int(p[2].x, 30);
test_int(p[2].y, 40);
test_bool(false, ecs_page_next(&pit));
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_paged_iterator_w_optional_component(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ecs_set(world, 0, Position, {10, 20});
ecs_entity_t e2 = ecs_set(world, 0, Position, {10, 20});
ecs_entity_t e3 = ecs_set(world, 0, Position, {20, 30});
ecs_entity_t e4 = ecs_set(world, 0, Position, {30, 40});
ecs_entity_t e5 = ecs_set(world, 0, Position, {40, 50});
ecs_set(world, e4, Velocity, {1, 2});
ecs_set(world, e5, Velocity, {2, 3});
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.terms = {
{ .id = ecs_id(Position) },
{ .id = ecs_id(Velocity), .oper = EcsOptional }
}
});
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_t pit = ecs_page_iter(&it, 1, 3);
test_bool(true, ecs_page_next(&pit));
test_int(2, pit.count);
test_bool(true, ecs_field_is_set(&pit, 1));
test_bool(false, ecs_field_is_set(&pit, 2));
test_uint(e2, pit.entities[0]);
test_uint(e3, pit.entities[1]);
Position *p = ecs_field(&pit, Position, 1);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_bool(true, ecs_page_next(&pit));
test_int(1, pit.count);
test_bool(true, ecs_field_is_set(&pit, 1));
test_bool(true, ecs_field_is_set(&pit, 2));
test_uint(e4, pit.entities[0]);
p = ecs_field(&pit, Position, 1);
test_int(p[0].x, 30);
test_int(p[0].y, 40);
Velocity *v = ecs_field(&pit, Velocity, 2);
test_int(v[0].x, 1);
test_int(v[0].y, 2);
test_bool(false, ecs_page_next(&pit));
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_paged_iterator_w_optional_tag(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_TAG(world, Tag);
ecs_set(world, 0, Position, {10, 20});
ecs_entity_t e2 = ecs_set(world, 0, Position, {10, 20});
ecs_entity_t e3 = ecs_set(world, 0, Position, {20, 30});
ecs_entity_t e4 = ecs_set(world, 0, Position, {30, 40});
ecs_entity_t e5 = ecs_set(world, 0, Position, {40, 50});
ecs_add(world, e4, Tag);
ecs_add(world, e5, Tag);
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.terms = {
{ .id = ecs_id(Position) },
{ .id = Tag, .oper = EcsOptional }
}
});
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_t pit = ecs_page_iter(&it, 1, 3);
test_bool(true, ecs_page_next(&pit));
test_int(2, pit.count);
test_bool(true, ecs_field_is_set(&pit, 1));
test_bool(false, ecs_field_is_set(&pit, 2));
test_uint(e2, pit.entities[0]);
test_uint(e3, pit.entities[1]);
Position *p = ecs_field(&pit, Position, 1);
test_int(p[0].x, 10);
test_int(p[0].y, 20);
test_int(p[1].x, 20);
test_int(p[1].y, 30);
test_bool(true, ecs_page_next(&pit));
test_int(1, pit.count);
test_bool(true, ecs_field_is_set(&pit, 1));
test_bool(true, ecs_field_is_set(&pit, 2));
test_uint(e4, pit.entities[0]);
p = ecs_field(&pit, Position, 1);
test_int(p[0].x, 30);
test_int(p[0].y, 40);
test_bool(false, ecs_page_next(&pit));
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_paged_iterator_w_vars(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Rel);
ECS_TAG(world, ObjA);
ECS_TAG(world, ObjB);
ecs_new_w_pair(world, Rel, ObjA);
ecs_entity_t e2 = ecs_new_w_pair(world, Rel, ObjA);
ecs_entity_t e3 = ecs_new_w_pair(world, Rel, ObjA);
ecs_entity_t e4 = ecs_new_w_pair(world, Rel, ObjB);
ecs_new_w_pair(world, Rel, ObjB);
ecs_rule_t *r = ecs_rule_init(world, &(ecs_filter_desc_t){
.expr = "(Rel, $Var)"
});
int32_t var = ecs_rule_find_var(r, "Var");
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_t pit = ecs_page_iter(&it, 1, 3);
test_assert(var < pit.variable_count);
test_str("Var", pit.variable_names[var]);
test_bool(true, ecs_page_next(&pit));
test_int(2, pit.count);
test_uint(e2, pit.entities[0]);
test_uint(e3, pit.entities[1]);
test_uint(ObjA, ecs_iter_get_var(&pit, var));
test_bool(true, ecs_page_next(&pit));
test_int(1, pit.count);
test_uint(e4, pit.entities[0]);
test_uint(ObjB, ecs_iter_get_var(&pit, var));
test_bool(false, ecs_page_next(&pit));
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_table(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ECS_COMPONENT(world, Mass);
ECS_TAG(world, Foo);
ECS_TAG(world, Bar);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Mass),
.members = {
{"value", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_entity_t e3 = ecs_new_entity(world, "e3");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {20, 30});
ecs_set(world, e3, Position, {30, 40});
ecs_add(world, e1, Foo);
ecs_add(world, e2, Foo);
ecs_add(world, e2, Bar);
ecs_set(world, e2, Velocity, {1, 1});
ecs_set(world, e3, Mass, {100});
ecs_filter_t *f = ecs_filter(world, {
.terms = {
{ .id = ecs_id(Position) }
}
});
ecs_iter_t it = ecs_filter_iter(world, f);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_table = true;
desc.serialize_ids = true;
desc.serialize_entities = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":["
"{"
"\"ids\":[[\"Position\"], [\"Foo\"]], "
"\"entities\":[\"e1\"], "
"\"values\":[[{\"x\":10, \"y\":20}], 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Velocity\"], [\"Foo\"], [\"Bar\"]], "
"\"entities\":[\"e2\"], "
"\"values\":[[{\"x\":20, \"y\":30}], [{\"x\":1, \"y\":1}], 0, 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Mass\"]], "
"\"entities\":[\"e3\"], "
"\"values\":[[{\"x\":30, \"y\":40}], [{\"value\":100}]]}]"
"}");
ecs_os_free(json);
ecs_filter_fini(f);
ecs_fini(world);
}
void SerializeIterToJson_serialize_table_w_id_labels(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ECS_COMPONENT(world, Mass);
ECS_TAG(world, Foo);
ECS_TAG(world, Bar);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Mass),
.members = {
{"value", ecs_id(ecs_i32_t)}
}
});
ecs_doc_set_name(world, ecs_id(Position), "position");
ecs_doc_set_name(world, ecs_id(Velocity), "velocity");
ecs_doc_set_name(world, ecs_id(Mass), "mass");
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_entity_t e3 = ecs_new_entity(world, "e3");
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {20, 30});
ecs_set(world, e3, Position, {30, 40});
ecs_add(world, e1, Foo);
ecs_add(world, e2, Foo);
ecs_add(world, e2, Bar);
ecs_set(world, e2, Velocity, {1, 1});
ecs_set(world, e3, Mass, {100});
ecs_filter_t *f = ecs_filter(world, {
.terms = {
{ .id = ecs_id(Position) }
}
});
ecs_iter_t it = ecs_filter_iter(world, f);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_table = true;
desc.serialize_entities = true;
desc.serialize_id_labels = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":["
"{"
"\"id_labels\":[[\"position\"], [\"Foo\"]], "
"\"entities\":[\"e1\"], "
"\"values\":[[{\"x\":10, \"y\":20}], 0]"
"}, {"
"\"id_labels\":[[\"position\"], [\"velocity\"], [\"Foo\"], [\"Bar\"]], "
"\"entities\":[\"e2\"], "
"\"values\":[[{\"x\":20, \"y\":30}], [{\"x\":1, \"y\":1}], 0, 0]"
"}, {"
"\"id_labels\":[[\"position\"], [\"mass\"]], "
"\"entities\":[\"e3\"], "
"\"values\":[[{\"x\":30, \"y\":40}], [{\"value\":100}]]}]"
"}");
ecs_os_free(json);
ecs_filter_fini(f);
ecs_fini(world);
}
void SerializeIterToJson_serialize_table_w_var_labels(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ECS_COMPONENT(world, Mass);
ECS_TAG(world, Foo);
ECS_TAG(world, Bar);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Mass),
.members = {
{"value", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t parent = ecs_new_entity(world, "Parent");
ecs_doc_set_name(world, parent, "parent");
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_entity_t e3 = ecs_new_entity(world, "e3");
ecs_add_pair(world, e1, EcsChildOf, parent);
ecs_add_pair(world, e2, EcsChildOf, parent);
ecs_add_pair(world, e3, EcsChildOf, parent);
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {20, 30});
ecs_set(world, e3, Position, {30, 40});
ecs_add(world, e1, Foo);
ecs_add(world, e2, Foo);
ecs_add(world, e2, Bar);
ecs_set(world, e2, Velocity, {1, 1});
ecs_set(world, e3, Mass, {100});
ecs_rule_t *f = ecs_rule(world, {
.terms = {
{ .id = ecs_id(Position) },
{ .first.id = EcsChildOf, .second.name = "p", .second.flags = EcsIsVariable }
}
});
ecs_iter_t it = ecs_rule_iter(world, f);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_table = true;
desc.serialize_entities = true;
desc.serialize_variable_labels = true;
desc.serialize_ids = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"vars\":[\"p\"], \"results\":["
"{"
"\"ids\":[[\"Position\"], [\"Foo\"]], "
"\"var_labels\":[\"parent\"], "
"\"parent\":\"Parent\", "
"\"entities\":[\"e1\"], "
"\"values\":[[{\"x\":10, \"y\":20}], 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Velocity\"], [\"Foo\"], [\"Bar\"]], "
"\"var_labels\":[\"parent\"], "
"\"parent\":\"Parent\", "
"\"entities\":[\"e2\"], "
"\"values\":[[{\"x\":20, \"y\":30}], [{\"x\":1, \"y\":1}], 0, 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Mass\"]], "
"\"var_labels\":[\"parent\"], "
"\"parent\":\"Parent\", "
"\"entities\":[\"e3\"], "
"\"values\":[[{\"x\":30, \"y\":40}], [{\"value\":100}]]}]"
"}");
ecs_os_free(json);
ecs_rule_fini(f);
ecs_fini(world);
}
void SerializeIterToJson_serialize_table_w_private(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);
ECS_COMPONENT(world, Mass);
ECS_TAG(world, Foo);
ECS_TAG(world, Bar);
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Velocity),
.members = {
{"x", ecs_id(ecs_i32_t)},
{"y", ecs_id(ecs_i32_t)}
}
});
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Mass),
.members = {
{"value", ecs_id(ecs_i32_t)}
}
});
ecs_entity_t parent = ecs_new_entity(world, "Parent");
ecs_doc_set_name(world, parent, "parent");
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_entity_t e3 = ecs_new_entity(world, "e3");
ecs_add_pair(world, e1, EcsChildOf, parent);
ecs_add_pair(world, e2, EcsChildOf, parent);
ecs_add_pair(world, e3, EcsChildOf, parent);
ecs_set(world, e1, Position, {10, 20});
ecs_set(world, e2, Position, {20, 30});
ecs_set(world, e3, Position, {30, 40});
ecs_add(world, e1, Foo);
ecs_add(world, e2, Foo);
ecs_add(world, e2, Bar);
ecs_set(world, e2, Velocity, {1, 1});
ecs_set(world, e3, Mass, {100});
ecs_rule_t *f = ecs_rule(world, {
.terms = {
{ .id = ecs_id(Position) },
{ .first.id = EcsChildOf, .second.name = "p", .second.flags = EcsIsVariable }
}
});
ecs_iter_t it = ecs_rule_iter(world, f);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_table = true;
desc.serialize_entities = true;
desc.serialize_variable_labels = true;
desc.serialize_ids = true;
desc.serialize_private = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"vars\":[\"p\"], \"results\":["
"{"
"\"ids\":[[\"Position\"], [\"Foo\"], [\"flecs.core.Identifier\",\"flecs.core.Name\"], [\"flecs.core.ChildOf\",\"Parent\"]], "
"\"var_labels\":[\"parent\"], "
"\"parent\":\"Parent\", "
"\"entities\":[\"e1\"], "
"\"values\":[[{\"x\":10, \"y\":20}], 0, 0, 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Velocity\"], [\"Foo\"], [\"Bar\"], [\"flecs.core.Identifier\",\"flecs.core.Name\"], [\"flecs.core.ChildOf\",\"Parent\"]], "
"\"var_labels\":[\"parent\"], "
"\"parent\":\"Parent\", "
"\"entities\":[\"e2\"], "
"\"values\":[[{\"x\":20, \"y\":30}], [{\"x\":1, \"y\":1}], 0, 0, 0, 0]"
"}, {"
"\"ids\":[[\"Position\"], [\"Mass\"], [\"flecs.core.Identifier\",\"flecs.core.Name\"], [\"flecs.core.ChildOf\",\"Parent\"]], "
"\"var_labels\":[\"parent\"], "
"\"parent\":\"Parent\", "
"\"entities\":[\"e3\"], "
"\"values\":[[{\"x\":30, \"y\":40}], [{\"value\":100}], 0, 0]}]"
"}");
ecs_os_free(json);
ecs_rule_fini(f);
ecs_fini(world);
}
void SerializeIterToJson_serialize_world(void) {
ecs_world_t *world = ecs_init();
/* We can't test if the output for an exact value as this would change any
* time something is added/removed to the world. */
char *json_1 = ecs_world_to_json(world, NULL);
test_assert(json_1 != NULL);
char *json_2 = ecs_world_to_json(world, NULL);
test_assert(json_2 != NULL);
test_assert(json_1 != json_2);
test_str(json_1, json_2);
ecs_os_free(json_1);
ecs_os_free(json_2);
ecs_fini(world);
}
void SerializeIterToJson_serialize_w_offset(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_add(world, e1, Tag);
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_add(world, e2, Tag);
ecs_rule_t *r = ecs_rule_new(world, "Tag($this), ?$this(_)");
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entities = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{\"results\":[{\"entities\":[\"e1\"]}, {\"entities\":[\"e2\"]}]}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_labels_w_offset(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e1 = ecs_new_id(world);
ecs_add(world, e1, Tag);
ecs_doc_set_name(world, e1, "e1");
ecs_entity_t e2 = ecs_new_id(world);
ecs_add(world, e2, Tag);
ecs_doc_set_name(world, e2, "e2");
ecs_rule_t *r = ecs_rule_new(world, "Tag($this), ?$this(_)");
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entity_labels = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{\"results\":[{\"entity_labels\":[\"e1\"]}, {\"entity_labels\":[\"e2\"]}]}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_colors_w_offset(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e1 = ecs_new_id(world);
ecs_add(world, e1, Tag);
ecs_doc_set_color(world, e1, "e1");
ecs_entity_t e2 = ecs_new_id(world);
ecs_add(world, e2, Tag);
ecs_doc_set_color(world, e2, "e2");
ecs_rule_t *r = ecs_rule_new(world, "Tag($this), ?$this(_)");
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_colors = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_str(json,
"{\"results\":[{\"colors\":[\"e1\"]}, {\"colors\":[\"e2\"]}]}");
ecs_os_free(json);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_anonymous_entities_w_offset(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e1 = ecs_new_id(world);
ecs_add(world, e1, Tag);
ecs_entity_t e2 = ecs_new_id(world);
ecs_add(world, e2, Tag);
ecs_rule_t *r = ecs_rule_new(world, "Tag($this), ?$this(_)");
ecs_iter_t it = ecs_rule_iter(world, r);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entities = true;
char *json = ecs_iter_to_json(world, &it, &desc);
char *expect = ecs_asprintf(
"{\"results\":[{\"entities\":[%u]}, {\"entities\":[%u]}]}",
(uint32_t)e1, (uint32_t)e2);
test_str(json, expect);
ecs_os_free(json);
ecs_os_free(expect);
ecs_rule_fini(r);
ecs_fini(world);
}
void SerializeIterToJson_serialize_term_labels(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_doc_set_name(world, ecs_id(Position), "position");
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_f32_t)},
{"y", ecs_id(ecs_f32_t)}
}
});
ecs_query_t *q = ecs_query_new(world, "Position");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_term_labels = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"id_labels\":[[\"position\"]], \"results\":[]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_id_labels(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_doc_set_name(world, ecs_id(Position), "position");
ecs_struct_init(world, &(ecs_struct_desc_t){
.entity = ecs_id(Position),
.members = {
{"x", ecs_id(ecs_f32_t)},
{"y", ecs_id(ecs_f32_t)}
}
});
ecs_entity_t e = ecs_new_entity(world, "ent");
ecs_set(world, e, Position, {1, 2});
ecs_query_t *q = ecs_query_new(world, "Position");
ecs_iter_t it = ecs_query_iter(world, q);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_id_labels = true;
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":[{\"id_labels\":[[\"position\"]]}]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_vars_for_query(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_query_t *q = ecs_query(world, {
.filter.terms[0] = {
.id = ecs_id(Position)
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {1, 2});
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_set(world, e2, Position, {3, 4});
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entities = true;
desc.serialize_variables = true;
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":[{\"entities\":[\"e1\", \"e2\"]}]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_var_labels_for_query(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_query_t *q = ecs_query(world, {
.filter.terms[0] = {
.id = ecs_id(Position)
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {1, 2});
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_set(world, e2, Position, {3, 4});
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entities = true;
desc.serialize_variable_labels = true;
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":[{\"entities\":[\"e1\", \"e2\"]}]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_var_ids_for_query(void) {
ecs_world_t *world = ecs_init();
ECS_COMPONENT(world, Position);
ecs_query_t *q = ecs_query(world, {
.filter.terms[0] = {
.id = ecs_id(Position)
}
});
ecs_entity_t e1 = ecs_new_entity(world, "e1");
ecs_set(world, e1, Position, {1, 2});
ecs_entity_t e2 = ecs_new_entity(world, "e2");
ecs_set(world, e2, Position, {3, 4});
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entities = true;
desc.serialize_variable_ids = true;
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":[{\"entities\":[\"e1\", \"e2\"]}]}");
ecs_os_free(json);
ecs_fini(world);
}
void SerializeIterToJson_serialize_null_doc_name(void) {
ecs_world_t *world = ecs_init();
ECS_TAG(world, Tag);
ecs_entity_t e = ecs_new_entity(world, "foo");
ecs_doc_set_name(world, e, "bar");
ecs_doc_set_name(world, e, NULL);
ecs_add(world, e, Tag);
ecs_query_t *q = ecs_query(world, {
.filter.terms[0] = {
.id = Tag
}
});
test_assert(q != NULL);
ecs_iter_to_json_desc_t desc = {0};
desc.serialize_entities = true;
desc.serialize_entity_labels = true;
ecs_iter_t it = ecs_query_iter(world, q);
char *json = ecs_iter_to_json(world, &it, &desc);
test_assert(json != NULL);
test_str(json, "{\"results\":[{\"entities\":[\"foo\"]}]}");
ecs_os_free(json);
ecs_fini(world);
}