#include void DeserializeFromJson_struct_bool(void) { typedef struct { bool v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_bool_t)} } }); test_assert(t != 0); T value = {false}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": true}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_bool(value.v, true); ecs_fini(world); } void DeserializeFromJson_struct_byte(void) { typedef struct { ecs_byte_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_byte_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_char(void) { typedef struct { ecs_char_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_char_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_char_literal(void) { typedef struct { ecs_char_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_char_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"a\"}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 'a'); ecs_fini(world); } void DeserializeFromJson_struct_i8(void) { typedef struct { ecs_i8_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i8_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_i16(void) { typedef struct { ecs_i16_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i16_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_i32(void) { typedef struct { ecs_i32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_i64(void) { typedef struct { ecs_i64_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i64_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_iptr(void) { typedef struct { ecs_iptr_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_iptr_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_u8(void) { typedef struct { ecs_u8_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_u8_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_u16(void) { typedef struct { ecs_u16_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_u16_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_u32(void) { typedef struct { ecs_u32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_u32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_u64(void) { typedef struct { ecs_u64_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_u64_t)} } }); test_assert(t != 0); { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 0}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 0); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); } { T value = {0}; const char *ptr = ecs_ptr_from_json( world, t, &value, "{\"v\": 2366700781656087864}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 2366700781656087864); } { T value = {0}; const char *ptr = ecs_ptr_from_json( world, t, &value, "{\"v\": \"2366700781656087864\"}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 2366700781656087864); } ecs_fini(world); } void DeserializeFromJson_struct_uptr(void) { typedef struct { ecs_uptr_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_uptr_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, 10); ecs_fini(world); } void DeserializeFromJson_struct_float(void) { typedef struct { ecs_f32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_f32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10.5}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_flt(value.v, 10.5); ecs_fini(world); } void DeserializeFromJson_struct_double(void) { typedef struct { ecs_f64_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_f64_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10.5}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_flt(value.v, 10.5); ecs_fini(world); } void DeserializeFromJson_struct_negative_int(void) { typedef struct { ecs_i32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": -10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, -10); ecs_fini(world); } void DeserializeFromJson_struct_negative_float(void) { typedef struct { ecs_f32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_f32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": -10.5}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_flt(value.v, -10.5); ecs_fini(world); } void DeserializeFromJson_struct_string(void) { typedef struct { char* v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_string_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Hello World\"}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_str(value.v, "Hello World"); ecs_os_free(value.v); ecs_fini(world); } void DeserializeFromJson_struct_entity(void) { typedef struct { ecs_entity_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_entity_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"flecs.core\"}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, EcsFlecsCore); ecs_fini(world); } void DeserializeFromJson_struct_id(void) { typedef struct { ecs_id_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_id_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"flecs.core\"}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_uint(value.v, EcsFlecsCore); ecs_fini(world); } void DeserializeFromJson_struct_enum(void) { typedef enum { Red, Blue, Green } E; typedef struct { E v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t e = ecs_enum_init(world, &(ecs_enum_desc_t){ .constants = { {"Red"}, {"Blue"}, {"Green"} } }); test_assert(e != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", e} } }); test_assert(t != 0); { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Red\"}", NULL); test_assert(ptr != NULL); test_int(value.v, Red); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Blue\"}", NULL); test_assert(ptr != NULL); test_int(value.v, Blue); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Green\"}", NULL); test_assert(ptr != NULL); test_int(value.v, Green); } { ecs_log_set_level(-4); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Black\"}", NULL); test_assert(ptr == NULL); } ecs_fini(world); } void DeserializeFromJson_struct_enum_underlying_i8(void) { typedef enum { Red, Blue, Green } E; typedef struct { int8_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t e = ecs_enum_init(world, &(ecs_enum_desc_t){ .constants = { {"Red"}, {"Blue"}, {"Green"} }, .underlying_type = ecs_id(ecs_i8_t) }); test_assert(e != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", e} } }); test_assert(t != 0); { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Red\"}", NULL); test_assert(ptr != NULL); test_int(value.v, Red); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Blue\"}", NULL); test_assert(ptr != NULL); test_int(value.v, Blue); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Green\"}", NULL); test_assert(ptr != NULL); test_int(value.v, Green); } { ecs_log_set_level(-4); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": \"Black\"}", NULL); test_assert(ptr == NULL); } ecs_fini(world); } void DeserializeFromJson_struct_bitmask(void) { uint32_t Lettuce = 0x1; uint32_t Bacon = 0x1 << 1; uint32_t Tomato = 0x1 << 2; uint32_t Cheese = 0x1 << 3; typedef struct { ecs_u32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t b = ecs_bitmask_init(world, &(ecs_bitmask_desc_t){ .constants = { {"Lettuce"}, {"Bacon"}, {"Tomato"}, {"Cheese"}, {"BLT", Bacon | Lettuce | Tomato} } }); test_assert(b != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", b} } }); test_assert(t != 0); { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\":\"Lettuce\"}", NULL); test_assert(ptr != NULL); test_uint(value.v, Lettuce); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\":\"Lettuce|Bacon\"}", NULL); test_assert(ptr != NULL); test_uint(value.v, Lettuce|Bacon); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\":\"Lettuce|Bacon|Tomato|Cheese\"}", NULL); test_assert(ptr != NULL); test_uint(value.v, Lettuce|Bacon|Tomato|Cheese); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\":\"BLT\"}", NULL); test_assert(ptr != NULL); test_uint(value.v, Lettuce|Bacon|Tomato); } { T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\":0}", NULL); test_assert(ptr != NULL); test_uint(value.v, 0); } { ecs_log_set_level(-4); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\":\"Foo\"}", NULL); test_assert(ptr == NULL); } ecs_fini(world); } void DeserializeFromJson_struct_i32_i32(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"x\": 10, \"y\": 20}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.x, 10); test_int(value.y, 20); ecs_fini(world); } void DeserializeFromJson_struct_nested_i32(void) { typedef struct { ecs_i32_t x; } N1; typedef struct { N1 n_1; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N1"}), .members = { {"x", ecs_id(ecs_i32_t)} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1}, } }); T value = {{0}}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": {\"x\": 10}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1.x, 10); ecs_fini(world); } void DeserializeFromJson_struct_nested_i32_i32(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N1; typedef struct { N1 n_1; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N1"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1}, } }); T value = {{0}}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": {\"x\": 10, \"y\": 20}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1.x, 10); test_int(value.n_1.y, 20); ecs_fini(world); } void DeserializeFromJson_struct_2_nested_i32_i32(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N1; typedef struct { N1 n_1; N1 n_2; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N1"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1}, {"n_2", n1} } }); T value = {{0}}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": {\"x\": 10, \"y\": 20}, \"n_2\": {\"x\": 30, \"y\": 40}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1.x, 10); test_int(value.n_1.y, 20); test_int(value.n_2.x, 30); test_int(value.n_2.y, 40); ecs_fini(world); } void DeserializeFromJson_struct_i32_array_3(void) { typedef struct { ecs_entity_t x[3]; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"x", ecs_id(ecs_entity_t), 3} } }); test_assert(t != 0); T value = {0}; ecs_make_alive(world, 10); ecs_make_alive(world, 20); ecs_make_alive(world, 30); const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"x\": [10, 20, 30]}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.x[0], 10); test_int(value.x[1], 20); test_int(value.x[2], 30); ecs_fini(world); } void DeserializeFromJson_struct_struct_i32_array_3(void) { typedef struct { ecs_i32_t x; } N1; typedef struct { N1 n_1[3]; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N1"}), .members = { {"x", ecs_id(ecs_i32_t)} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1, 3} } }); T value = {{{0}}}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": [{\"x\": 10}, {\"x\": 20}, {\"x\": 30}]}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1[0].x, 10); test_int(value.n_1[1].x, 20); test_int(value.n_1[2].x, 30); ecs_fini(world); } void DeserializeFromJson_struct_struct_i32_i32_array_3(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N1; typedef struct { N1 n_1[3]; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N1"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1, 3} } }); T value = {{{0}}}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": [{\"x\": 10, \"y\": 20}, {\"x\": 30, \"y\": 40}, {\"x\": 50, \"y\": 60}]}" , NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1[0].x, 10); test_int(value.n_1[0].y, 20); test_int(value.n_1[1].x, 30); test_int(value.n_1[1].y, 40); test_int(value.n_1[2].x, 50); test_int(value.n_1[2].y, 60); ecs_fini(world); } void DeserializeFromJson_struct_w_array_type_i32_i32(void) { typedef int32_t N1[2]; typedef struct { N1 n_1; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_array_init(world, &(ecs_array_desc_t){ .entity = ecs_entity(world, {.name = "vec2"}), .type = ecs_id(ecs_i32_t), .count = 2 }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1} } }); T value = {{ 0 }}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": [10, 20]}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1[0], 10); test_int(value.n_1[1], 20); ecs_fini(world); } void DeserializeFromJson_struct_w_2_array_type_i32_i32(void) { typedef int32_t N1[2]; typedef struct { N1 n_1; N1 n_2; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n1 = ecs_array_init(world, &(ecs_array_desc_t){ .entity = ecs_entity(world, {.name = "vec2"}), .type = ecs_id(ecs_i32_t), .count = 2 }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1}, {"n_2", n1} } }); T value = {{ 0 }}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"n_1\": [10, 20], \"n_2\": [30, 40]}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.n_1[0], 10); test_int(value.n_1[1], 20); test_int(value.n_2[0], 30); test_int(value.n_2[1], 40); ecs_fini(world); } void DeserializeFromJson_struct_w_nested_member_i32(void) { ecs_world_t *world = ecs_init(); ecs_entity_t ecs_id(Point) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Point"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(ecs_id(Point) != 0); ecs_entity_t ecs_id(Line) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Line"}), .members = { {"start", ecs_id(Point)}, {"stop", ecs_id(Point)} } }); test_assert(ecs_id(Line) != 0); Line value = {0}; const char *ptr = ecs_ptr_from_json(world, ecs_id(Line), &value, "{\"start.x\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.start.x, 10); ecs_fini(world); } void DeserializeFromJson_struct_w_2_nested_members_i32(void) { ecs_world_t *world = ecs_init(); ecs_entity_t ecs_id(Point) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Point"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(ecs_id(Point) != 0); ecs_entity_t ecs_id(Line) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Line"}), .members = { {"start", ecs_id(Point)}, {"stop", ecs_id(Point)} } }); test_assert(ecs_id(Line) != 0); Line value = {0}; const char *ptr = ecs_ptr_from_json(world, ecs_id(Line), &value, "{\"start.x\": 10, \"start.y\": 20, \"stop.x\": 30, \"stop.y\": 40}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.start.x, 10); test_int(value.start.y, 20); test_int(value.stop.x, 30); test_int(value.stop.y, 40); ecs_fini(world); } void DeserializeFromJson_struct_w_nested_members_struct(void) { ecs_world_t *world = ecs_init(); typedef struct { Line left; Line right; } TwoLines; ecs_entity_t ecs_id(Point) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Point"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(ecs_id(Point) != 0); ecs_entity_t ecs_id(Line) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Line"}), .members = { {"start", ecs_id(Point)}, {"stop", ecs_id(Point)} } }); test_assert(ecs_id(Line) != 0); ecs_entity_t ecs_id(TwoLines) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "TwoLines"}), .members = { {"left", ecs_id(Line)}, {"right", ecs_id(Line)} } }); test_assert(ecs_id(TwoLines) != 0); TwoLines value = {0}; const char *ptr = ecs_ptr_from_json(world, ecs_id(TwoLines), &value, "{\"left.start\": {\"x\": 10, \"y\": 20}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.left.start.x, 10); test_int(value.left.start.y, 20); ecs_fini(world); } void DeserializeFromJson_struct_w_2_nested_members_struct(void) { ecs_world_t *world = ecs_init(); typedef struct { Line left; Line right; } TwoLines; ecs_entity_t ecs_id(Point) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Point"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(ecs_id(Point) != 0); ecs_entity_t ecs_id(Line) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Line"}), .members = { {"start", ecs_id(Point)}, {"stop", ecs_id(Point)} } }); test_assert(ecs_id(Line) != 0); ecs_entity_t ecs_id(TwoLines) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "TwoLines"}), .members = { {"left", ecs_id(Line)}, {"right", ecs_id(Line)} } }); test_assert(ecs_id(TwoLines) != 0); TwoLines value = {0}; const char *ptr = ecs_ptr_from_json(world, ecs_id(TwoLines), &value, "{\"left.start\": {\"x\": 10, \"y\": 20}, \"right.start\": {\"x\": 30, \"y\": 40}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.left.start.x, 10); test_int(value.left.start.y, 20); test_int(value.right.start.x, 30); test_int(value.right.start.y, 40); ecs_fini(world); } void DeserializeFromJson_ser_deser_entity_named(void) { ecs_world_t *world = ecs_init(); ecs_entity_t e = ecs_entity(world, { .name = "e" }); char *json = ecs_entity_to_json(world, e, NULL); const char *r = ecs_entity_from_json(world, e, json, NULL); test_assert(r != NULL); ecs_os_free(json); test_str(ecs_get_name(world, e), "e"); ecs_fini(world); } void DeserializeFromJson_ser_deser_entity_named_child(void) { ecs_world_t *world = ecs_init(); ecs_entity_t e = ecs_entity(world, { .name = "parent.e" }); char *json = ecs_entity_to_json(world, e, NULL); const char *r = ecs_entity_from_json(world, e, json, NULL); test_assert(r != NULL); ecs_os_free(json); ecs_entity_t parent = ecs_lookup(world, "parent"); test_assert(parent != 0); test_str(ecs_get_name(world, e), "e"); test_uint(parent, ecs_get_target(world, e, EcsChildOf, 0)); ecs_fini(world); } void DeserializeFromJson_ser_deser_entity_namespaced_component(void) { ecs_world_t *world = ecs_init(); ecs_entity_t ecs_id(Position) = ecs_struct(world, { .entity = ecs_entity(world, { .name = "ns.Position" }), .members = { { "x", .type = ecs_id(ecs_i32_t) }, { "y", .type = ecs_id(ecs_i32_t) } } }); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_set(world, e, Position, {10, 20}); char *json = ecs_entity_to_json(world, e, NULL); ecs_set(world, e, Position, {0, 0}); const char *r = ecs_entity_from_json(world, e, json, NULL); test_assert(r != NULL); ecs_os_free(json); test_str(ecs_get_name(world, e), "e"); { const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } ecs_fini(world); } void DeserializeFromJson_deser_entity_1_component_1_member(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)} } }); test_assert(ecs_id(Position) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"Position\": {\"x\": 10}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Position *pos = ecs_get(world, e, Position); test_assert(pos != NULL); test_int(pos->x, 10); ecs_fini(world); } void DeserializeFromJson_deser_entity_1_component_1_member_w_spaces(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)} } }); test_assert(ecs_id(Position) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{ \"components\" : { \"Position\" : { \"x\" : 10 } } }", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Position *pos = ecs_get(world, e, Position); test_assert(pos != NULL); test_int(pos->x, 10); ecs_fini(world); } void DeserializeFromJson_deser_entity_1_component_2_members(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)} } }); test_assert(ecs_id(Position) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"Position\": {\"x\": 10, \"y\": 20}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Position *pos = ecs_get(world, e, Position); test_assert(pos != NULL); test_int(pos->x, 10); test_int(pos->y, 20); ecs_fini(world); } void DeserializeFromJson_deser_entity_2_components_missing_object_close(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)} } }); test_assert(ecs_id(Position) != 0); 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)} } }); test_assert(ecs_id(Velocity) != 0); ecs_entity_t e = ecs_new(world); ecs_log_set_level(-4); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"Position\": {\"x\": 10, \"y\": 20}, \"Velocity\": {\"x\": 1, \"y\": 2}}", NULL); test_assert(ptr == NULL); ecs_fini(world); } void DeserializeFromJson_deser_entity_2_components(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)} } }); test_assert(ecs_id(Position) != 0); 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)} } }); test_assert(ecs_id(Velocity) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"Position\": {\"x\": 10, \"y\": 20}, \"Velocity\": {\"x\": 1, \"y\": 2}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Position *pos = ecs_get(world, e, Position); test_assert(pos != NULL); test_int(pos->x, 10); test_int(pos->y, 20); const Velocity *vel = ecs_get(world, e, Velocity); test_assert(vel != NULL); test_int(vel->x, 1); test_int(vel->y, 2); ecs_fini(world); } void DeserializeFromJson_deser_entity_1_component_composite_member(void) { ecs_world_t *world = ecs_init(); ecs_entity_t ecs_id(Point) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Point"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(ecs_id(Point) != 0); ecs_entity_t ecs_id(Line) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Line"}), .members = { {"start", ecs_id(Point)}, {"stop", ecs_id(Point)} } }); test_assert(ecs_id(Line) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"Line\": {\"start\": {\"x\": 10, \"y\": 20}, \"stop\": {\"x\": 30, \"y\": 40}}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Line *line = ecs_get(world, e, Line); test_assert(line != NULL); test_int(line->start.x, 10); test_int(line->start.y, 20); test_int(line->stop.x, 30); test_int(line->stop.y, 40); ecs_fini(world); } void DeserializeFromJson_deser_entity_1_component_nested_member(void) { ecs_world_t *world = ecs_init(); ecs_entity_t ecs_id(Point) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Point"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); test_assert(ecs_id(Point) != 0); ecs_entity_t ecs_id(Line) = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "Line"}), .members = { {"start", ecs_id(Point)}, {"stop", ecs_id(Point)} } }); test_assert(ecs_id(Line) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"Line\": {\"start.x\": 10, \"start.y\": 20, \"stop.x\": 30, \"stop.y\": 40}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Line *line = ecs_get(world, e, Line); test_assert(line != NULL); test_int(line->start.x, 10); test_int(line->start.y, 20); test_int(line->stop.x, 30); test_int(line->stop.y, 40); ecs_fini(world); } void DeserializeFromJson_deser_entity_1_pair(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Tgt); 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)} } }); test_assert(ecs_id(Position) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"(Position,Tgt)\": {\"x\": 10, \"y\": 20}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Position *pos = ecs_get_pair(world, e, Position, Tgt); test_assert(pos != NULL); test_int(pos->x, 10); test_int(pos->y, 20); ecs_fini(world); } void DeserializeFromJson_deser_entity_2_pairs(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Tgt); 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)} } }); test_assert(ecs_id(Position) != 0); 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)} } }); test_assert(ecs_id(Velocity) != 0); ecs_entity_t e = ecs_new(world); const char *ptr = ecs_entity_from_json(world, e, "{\"components\": {\"(Position,Tgt)\": {\"x\": 10, \"y\": 20}, \"(Velocity,Tgt)\": {\"x\": 1, \"y\": 2}}}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); const Position *pos = ecs_get_pair(world, e, Position, Tgt); test_assert(pos != NULL); test_int(pos->x, 10); test_int(pos->y, 20); const Velocity *vel = ecs_get_pair(world, e, Velocity, Tgt); test_assert(vel != NULL); test_int(vel->x, 1); test_int(vel->y, 2); ecs_fini(world); } void DeserializeFromJson_deser_entity_empty(void) { ecs_world_t *world = ecs_init(); ecs_entity_t e = ecs_new(world); const char *r = ecs_entity_from_json(world, e, "{}", NULL); test_str(r, ""); ecs_fini(world); } void DeserializeFromJson_deser_entity_w_path(void) { ecs_world_t *world = ecs_init(); ecs_entity_t e = ecs_new(world); const char *r = ecs_entity_from_json(world, e, "{\"name\":\"ent\"}", NULL); test_str(r, ""); test_str(ecs_get_name(world, e), "ent"); ecs_fini(world); } void DeserializeFromJson_deser_entity_w_path_and_ids(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world); const char *r = ecs_entity_from_json(world, e, "{\"name\": \"ent\", \"components\": {\"Position\": null}}", NULL); test_str(r, ""); test_str(ecs_get_name(world, e), "ent"); test_assert(ecs_has(world, e, Position)); ecs_fini(world); } void DeserializeFromJson_deser_entity_w_path_and_ids_and_values(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { { "x", .type = ecs_id(ecs_i32_t) }, { "y", .type = ecs_id(ecs_i32_t) } } }); ecs_entity_t e = ecs_new(world); const char *r = ecs_entity_from_json(world, e, "{\"name\": \"ent\", \"components\": {\"Position\":{\"x\": 10, \"y\": 20}}}", NULL); test_str(r, ""); test_str(ecs_get_name(world, e), "ent"); test_assert(ecs_has(world, e, Position)); const Position *p = ecs_get(world, e, Position); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_deser_entity_w_ids(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new(world); const char *r = ecs_entity_from_json(world, e, "{\"tags\": [\"Position\"]}", NULL); test_str(r, ""); test_str(ecs_get_name(world, e), NULL); test_assert(ecs_has(world, e, Position)); ecs_fini(world); } void DeserializeFromJson_deser_entity_1_pair_2_targets(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Rel); ECS_TAG(world, TgtA); ECS_TAG(world, TgtB); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add_pair(world, e, Rel, TgtA); ecs_add_pair(world, e, Rel, TgtB); char *json = ecs_entity_to_json(world, e, NULL); ecs_remove_pair(world, e, Rel, EcsWildcard); test_assert(!ecs_has_pair(world, e, Rel, TgtA)); test_assert(!ecs_has_pair(world, e, Rel, TgtB)); const char *r = ecs_entity_from_json(world, e, json, NULL); test_assert(r != NULL); ecs_os_free(json); test_assert(ecs_has_pair(world, e, Rel, TgtA)); test_assert(ecs_has_pair(world, e, Rel, TgtB)); ecs_fini(world); } void DeserializeFromJson_ser_deser_mini(void) { ecs_world_t *world = ecs_mini(); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_init(void) { ecs_world_t *world = ecs_init(); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_mini_serialize_builtin(void) { ecs_world_t *world = ecs_mini(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_mini_serialize_modules(void) { ecs_world_t *world = ecs_mini(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_mini_serialize_builtin_modules(void) { ecs_world_t *world = ecs_mini(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_init_serialize_builtin(void) { ecs_world_t *world = ecs_init(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_init_serialize_modules(void) { ecs_world_t *world = ecs_init(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_init_serialize_builtin_modules(void) { ecs_world_t *world = ecs_init(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world(void) { ecs_world_t *world = ecs_init(); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); // printf("%s\n", json); ecs_fini(world); world = ecs_init(); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_entity_w_tag(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Tag); ecs_entity_t e = ecs_new_w(world, Tag); test_assert(e != 0); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_TAG_DEFINE(world, Tag); /* pin Tag */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, Tag)); test_assert(ecs_has(world, e, Tag)); test_str(ecs_get_name(world, Tag), "Tag"); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_entity_w_component(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new_w(world, Position); test_assert(e != 0); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_entity_w_component_meta(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e = ecs_insert(world, ecs_value(Position, {10, 20})); test_assert(e != 0); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_named_entity_w_tag(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Tag); ecs_entity_t e = ecs_entity(world, { .name = "foo" }); ecs_add(world, e, Tag); test_assert(e != 0); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_TAG_DEFINE(world, Tag); /* pin Tag */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e = ecs_lookup(world, "foo"); test_assert(e != 0); test_assert(ecs_is_alive(world, Tag)); test_assert(ecs_has(world, e, Tag)); test_str(ecs_get_name(world, Tag), "Tag"); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_named_entity_w_component(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_entity(world, { .name = "foo" }); ecs_add(world, e, Position); test_assert(e != 0); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e = ecs_lookup(world, "foo"); test_assert(e != 0); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_named_entity_w_component_meta(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e = ecs_entity(world, { .name = "foo" }); ecs_set(world, e, Position, {10, 20}); test_assert(e != 0); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e = ecs_lookup(world, "foo"); test_assert(e != 0); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_entity_w_tag_serialize_all(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Tag); ecs_entity_t e = ecs_new_w(world, Tag); test_assert(e != 0); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_TAG_DEFINE(world, Tag); /* pin Tag */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, Tag)); test_assert(ecs_has(world, e, Tag)); test_str(ecs_get_name(world, Tag), "Tag"); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_entity_w_component_serialize_all(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_new_w(world, Position); test_assert(e != 0); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_entity_w_component_meta_serialize_all(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e = ecs_insert(world, ecs_value(Position, {10, 20})); test_assert(e != 0); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_named_entity_w_tag_serialize_all(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Tag); ecs_entity_t e = ecs_entity(world, { .name = "foo" }); ecs_add(world, e, Tag); test_assert(e != 0); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_TAG_DEFINE(world, Tag); /* pin Tag */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e = ecs_lookup(world, "foo"); test_assert(e != 0); test_assert(ecs_is_alive(world, Tag)); test_assert(ecs_has(world, e, Tag)); test_str(ecs_get_name(world, Tag), "Tag"); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_named_entity_w_component_serialize_all(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_entity_t e = ecs_entity(world, { .name = "foo" }); ecs_add(world, e, Position); test_assert(e != 0); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e = ecs_lookup(world, "foo"); test_assert(e != 0); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_1_named_entity_w_component_meta_serialize_all(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e = ecs_entity(world, { .name = "foo" }); ecs_set(world, e, Position, {10, 20}); test_assert(e != 0); ecs_world_to_json_desc_t desc = {0}; desc.serialize_builtin = true; desc.serialize_modules = true; char *json = ecs_world_to_json(world, &desc); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e = ecs_lookup(world, "foo"); test_assert(e != 0); test_assert(ecs_is_alive(world, e)); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_has(world, e, Position)); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_3_entities_w_component_meta(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e3, Position, {50, 60}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_3_entities_w_2_components_meta(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e3, Position, {50, 60}); ecs_set(world, e1, Mass, {100}); ecs_set(world, e2, Mass, {200}); ecs_set(world, e3, Mass, {300}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT_DEFINE(world, Mass); /* pin Mass id */ ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } test_assert(ecs_has(world, e1, Mass)); test_assert(ecs_has(world, e2, Mass)); test_assert(ecs_has(world, e3, Mass)); { const Mass *m = ecs_get(world, e1, Mass); test_assert(m != NULL); test_int(m->value, 100); } { const Mass *m = ecs_get(world, e2, Mass); test_assert(m != NULL); test_int(m->value, 200); } { const Mass *m = ecs_get(world, e3, Mass); test_assert(m != NULL); test_int(m->value, 300); } ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_4_entities_2_tables_w_component_meta(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, Tag); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); 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, e3, Tag); ecs_add(world, e4, Tag); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, Position); /* pin Position id */ ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG_DEFINE(world, Tag); /* pin Tag id */ const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); e4 = ecs_lookup(world, "e4"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(e4 != 0); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); test_assert(ecs_has(world, e4, Position)); test_assert(!ecs_has(world, e1, Tag)); test_assert(!ecs_has(world, e2, Tag)); test_assert(ecs_has(world, e3, Tag)); test_assert(ecs_has(world, e4, Tag)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } { const Position *p = ecs_get(world, e4, Position); test_assert(p != NULL); test_int(p->x, 70); test_int(p->y, 80); } ecs_fini(world); } typedef struct EntityType { ecs_entity_t a; ecs_entity_t b; } EntityType; void DeserializeFromJson_ser_deser_new_world_component_w_anon_entity_member(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, EntityType); ecs_struct(world, { .entity = ecs_id(EntityType), .members = { {"a", ecs_id(ecs_entity_t)}, {"b", ecs_id(ecs_entity_t)} } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t a1 = ecs_new(world); ecs_entity_t a2 = ecs_new(world); ecs_set(world, e1, EntityType, {a1, a2}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_id(world, e2, a1); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_add_id(world, e3, a2); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, EntityType); /* pin EntityType id */ ecs_struct(world, { .entity = ecs_id(EntityType), .members = { {"a", ecs_id(ecs_entity_t)}, {"b", ecs_id(ecs_entity_t)} } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(ecs_has(world, e1, EntityType)); const EntityType *et = ecs_get(world, e1, EntityType); test_assert(et != NULL); test_assert(et->a != 0); test_assert(et->b != 0); test_assert(et->a != et->b); test_assert(ecs_get_table(world, et->a) != NULL); test_int(ecs_get_type(world, et->a)->count, 0); test_assert(ecs_get_table(world, et->b) != NULL); test_int(ecs_get_type(world, et->b)->count, 0); test_assert(ecs_has_id(world, e2, et->a)); test_assert(!ecs_has_id(world, e3, et->a)); test_assert(!ecs_has_id(world, e2, et->b)); test_assert(ecs_has_id(world, e3, et->b)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_component_w_named_entity_member(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, EntityType); ecs_struct(world, { .entity = ecs_id(EntityType), .members = { {"a", ecs_id(ecs_entity_t)}, {"b", ecs_id(ecs_entity_t)} } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t n1 = ecs_entity(world, { .name = "n1" }); ecs_entity_t n2 = ecs_entity(world, { .name = "n2" }); ecs_set(world, e1, EntityType, {n1, n2}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_id(world, e2, n1); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_add_id(world, e3, n2); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, EntityType); /* pin EntityType id */ ecs_struct(world, { .entity = ecs_id(EntityType), .members = { {"a", ecs_id(ecs_entity_t)}, {"b", ecs_id(ecs_entity_t)} } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(ecs_has(world, e1, EntityType)); const EntityType *et = ecs_get(world, e1, EntityType); test_assert(et != NULL); test_assert(et->a != 0); test_assert(et->b != 0); test_assert(et->a != et->b); test_str(ecs_get_name(world, et->a), "n1"); test_str(ecs_get_name(world, et->b), "n2"); test_assert(ecs_has_id(world, e2, et->a)); test_assert(!ecs_has_id(world, e3, et->a)); test_assert(!ecs_has_id(world, e2, et->b)); test_assert(ecs_has_id(world, e3, et->b)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_component_w_anon_and_named_entity_member(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, EntityType); ecs_struct(world, { .entity = ecs_id(EntityType), .members = { {"a", ecs_id(ecs_entity_t)}, {"b", ecs_id(ecs_entity_t)} } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t n1 = ecs_entity(world, { .name = "n1" }); ecs_entity_t a1 = ecs_new(world); ecs_set(world, e1, EntityType, {n1, a1}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_id(world, e2, n1); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_add_id(world, e3, a1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_COMPONENT_DEFINE(world, EntityType); /* pin EntityType id */ ecs_struct(world, { .entity = ecs_id(EntityType), .members = { {"a", ecs_id(ecs_entity_t)}, {"b", ecs_id(ecs_entity_t)} } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(ecs_has(world, e1, EntityType)); const EntityType *et = ecs_get(world, e1, EntityType); test_assert(et != NULL); test_assert(et->a != 0); test_assert(et->b != 0); test_assert(et->a != et->b); test_str(ecs_get_name(world, et->a), "n1"); test_assert(ecs_get_table(world, et->b) != NULL); test_int(ecs_get_type(world, et->b)->count, 0); test_assert(ecs_has_id(world, e2, et->a)); test_assert(!ecs_has_id(world, e3, et->a)); test_assert(!ecs_has_id(world, e2, et->b)); test_assert(ecs_has_id(world, e3, et->b)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_component_w_anon_entity_with_self(void) { ecs_world_t *world = ecs_init(); ecs_entity_t e1 = ecs_new(world); ecs_add_id(world, e1, e1); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_id(world, e2, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e2 = ecs_lookup(world, "e2"); test_assert(e2 != 0); const ecs_type_t *type = ecs_get_type(world, e2); test_assert(type != NULL); test_int(type->count, 2); ecs_entity_t e = type->array[0]; test_assert(e != 0); test_assert(ecs_is_valid(world, e)); test_assert(ecs_has_id(world, e, e)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_component_w_named_entity_with_self(void) { ecs_world_t *world = ecs_init(); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_add_id(world, e1, e1); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_id(world, e2, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); test_assert(e1 != 0); e2 = ecs_lookup(world, "e2"); test_assert(e2 != 0); test_assert(ecs_has_id(world, e2, e1)); test_assert(ecs_has_id(world, e1, e1)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_2_entities_w_anon_parent(void) { char *json; { ecs_world_t *world = ecs_init(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t parent = ecs_new(world); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_pair(world, e1, EcsChildOf, parent); ecs_add_pair(world, e2, EcsChildOf, parent); ecs_add(world, e1, TagA); ecs_add(world, e2, TagB); ecs_entity_t foo = ecs_entity(world, { .name = "foo" }); ecs_add_pair(world, foo, TagA, e1); ecs_add_pair(world, foo, TagB, e2); json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); } { ecs_world_t *world = ecs_init(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t foo = ecs_lookup(world, "foo"); test_assert(foo != 0); ecs_entity_t e1 = ecs_get_target(world, foo, TagA, 0); test_assert(e1 != 0); test_str(ecs_get_name(world, e1), "e1"); test_assert(ecs_has(world, e1, TagA)); ecs_entity_t e2 = ecs_get_target(world, foo, TagB, 0); test_assert(e2 != 0); test_str(ecs_get_name(world, e2), "e2"); test_assert(ecs_has(world, e2, TagB)); test_assert(ecs_get_target(world, e1, EcsChildOf, 0) != 0); test_assert(ecs_get_target(world, e2, EcsChildOf, 0) != 0); test_assert(ecs_get_target(world, e1, EcsChildOf, 0) == ecs_get_target(world, e2, EcsChildOf, 0)); ecs_fini(world); } } void DeserializeFromJson_ser_deser_new_world_2_entities_w_named_parent(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t parent = ecs_entity(world, { .name = "parent" }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_pair(world, e1, EcsChildOf, parent); ecs_add_pair(world, e2, EcsChildOf, parent); ecs_add(world, e1, TagA); ecs_add(world, e2, TagB); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); parent = ecs_lookup(world, "parent"); test_assert(parent != 0); test_str(ecs_get_name(world, parent), "parent"); e1 = ecs_lookup(world, "parent.e1"); test_assert(e1 != 0); test_str(ecs_get_name(world, e1), "e1"); e2 = ecs_lookup(world, "parent.e2"); test_assert(e2 != 0); test_str(ecs_get_name(world, e2), "e2"); test_assert(ecs_get_target(world, e1, EcsChildOf, 0) == parent); test_assert(ecs_get_target(world, e2, EcsChildOf, 0) == parent); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_2_entities_w_anon_parent_w_cycle(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t parent = ecs_new(world); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_pair(world, e1, EcsChildOf, parent); ecs_add_pair(world, e2, EcsChildOf, parent); ecs_add(world, e1, TagA); ecs_add(world, e2, TagB); ecs_entity_t foo = ecs_entity(world, { .name = "foo" }); ecs_add_pair(world, foo, TagA, e1); ecs_add_pair(world, foo, TagB, e2); ecs_add_pair(world, parent, TagA, e1); ecs_add_pair(world, parent, TagB, e2); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); foo = ecs_lookup(world, "foo"); test_assert(foo != 0); e1 = ecs_get_target(world, foo, TagA, 0); test_assert(e1 != 0); test_str(ecs_get_name(world, e1), "e1"); test_assert(ecs_has(world, e1, TagA)); e2 = ecs_get_target(world, foo, TagB, 0); test_assert(e2 != 0); test_str(ecs_get_name(world, e2), "e2"); test_assert(ecs_has(world, e2, TagB)); test_assert(ecs_get_target(world, e1, EcsChildOf, 0) != 0); test_assert(ecs_get_target(world, e2, EcsChildOf, 0) != 0); test_assert(ecs_get_target(world, e1, EcsChildOf, 0) == ecs_get_target(world, e2, EcsChildOf, 0)); parent = ecs_get_target(world, e1, EcsChildOf, 0); test_assert(ecs_has_pair(world, parent, TagA, e1)); test_assert(ecs_has_pair(world, parent, TagB, e2)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_2_entities_w_named_parent_w_cycle(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, TagA); ECS_TAG(world, TagB); ecs_entity_t parent = ecs_entity(world, { .name = "parent" }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_add_pair(world, e1, EcsChildOf, parent); ecs_add_pair(world, e2, EcsChildOf, parent); ecs_add(world, e1, TagA); ecs_add(world, e2, TagB); ecs_add_pair(world, parent, TagA, e1); ecs_add_pair(world, parent, TagB, e2); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); parent = ecs_lookup(world, "parent"); test_assert(parent != 0); test_str(ecs_get_name(world, parent), "parent"); e1 = ecs_lookup(world, "parent.e1"); test_assert(e1 != 0); test_str(ecs_get_name(world, e1), "e1"); e2 = ecs_lookup(world, "parent.e2"); test_assert(e2 != 0); test_str(ecs_get_name(world, e2), "e2"); test_assert(ecs_get_target(world, e1, EcsChildOf, 0) == parent); test_assert(ecs_get_target(world, e2, EcsChildOf, 0) == parent); test_assert(ecs_has_pair(world, parent, TagA, e1)); test_assert(ecs_has_pair(world, parent, TagB, e2)); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_w_prefab(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Foo); ECS_TAG(world, Bar); ecs_entity_t b = ecs_new_w(world, Foo); test_assert(b != 0); ecs_add_id(world, b, EcsPrefab); ecs_entity_t e = ecs_new_w(world, Bar); test_assert(e != 0); ecs_add_pair(world, e, EcsIsA, b); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_TAG_DEFINE(world, Foo); /* pin tags */ ECS_TAG_DEFINE(world, Bar); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, Foo)); test_assert(ecs_is_alive(world, Bar)); test_assert(ecs_is_alive(world, b)); test_assert(ecs_is_alive(world, e)); test_assert(ecs_has(world, b, Foo)); test_assert(ecs_has_id(world, b, EcsPrefab)); test_assert(ecs_has(world, e, Foo)); test_assert(ecs_has(world, e, Bar)); test_assert(ecs_has_pair(world, e, EcsIsA, b)); test_str(ecs_get_name(world, Foo), "Foo"); test_str(ecs_get_name(world, Bar), "Bar"); ecs_fini(world); } void DeserializeFromJson_ser_deser_new_world_w_disabled(void) { ecs_world_t *world = ecs_init(); ECS_TAG(world, Foo); ECS_TAG(world, Bar); ecs_entity_t b = ecs_new_w(world, Foo); test_assert(b != 0); ecs_enable(world, b, false); test_assert(ecs_has_id(world, b, EcsDisabled)); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); ECS_TAG_DEFINE(world, Foo); /* pin tags */ ECS_TAG_DEFINE(world, Bar); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, Foo)); test_assert(ecs_is_alive(world, Bar)); test_assert(ecs_is_alive(world, b)); test_assert(ecs_has(world, b, Foo)); test_assert(ecs_has_id(world, b, EcsDisabled)); test_str(ecs_get_name(world, Foo), "Foo"); ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_entity_to_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e2, Velocity, {3, 4}); ecs_set(world, e1, Velocity, {1, 2}); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(e1 == ecs_lookup(world, "e1")); test_assert(e2 == ecs_lookup(world, "e2")); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(!ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Velocity *v = ecs_get(world, e2, Velocity); test_assert(v != NULL); test_int(v->x, 3); test_int(v->y, 4); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_entity_to_non_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e2, Velocity, {3, 4}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_remove(world, e1, Position); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(e1 == ecs_lookup(world, "e1")); test_assert(e2 == ecs_lookup(world, "e2")); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Velocity *v = ecs_get(world, e1, Velocity); test_assert(v != NULL); test_int(v->x, 1); test_int(v->y, 2); } { const Velocity *v = ecs_get(world, e2, Velocity); test_assert(v != NULL); test_int(v->x, 3); test_int(v->y, 4); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_anon_entity_to_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_entity_t e2 = ecs_new(world); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e2, Velocity, {3, 4}); ecs_set(world, e1, Velocity, {1, 2}); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(!ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Velocity *v = ecs_get(world, e2, Velocity); test_assert(v != NULL); test_int(v->x, 3); test_int(v->y, 4); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_anon_entity_to_non_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_entity_t e2 = ecs_new(world); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e2, Velocity, {3, 4}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_remove(world, e1, Position); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Velocity *v = ecs_get(world, e1, Velocity); test_assert(v != NULL); test_int(v->x, 1); test_int(v->y, 2); } { const Velocity *v = ecs_get(world, e2, Velocity); test_assert(v != NULL); test_int(v->x, 3); test_int(v->y, 4); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_entity_to_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); test_assert(e1 != 0); test_assert(ecs_has(world, e1, Position)); const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_entity_to_non_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {30, 40}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); test_assert(e1 != 0); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_has(world, e2, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_anon_entity_to_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_iter_t it = ecs_each(world, Position); e1 = ecs_iter_first(&it); test_assert(e1 != 0); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_has(world, e1, Position)); const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_anon_entity_to_non_empty_table(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_new(world); ecs_set(world, e2, Position, {30, 40}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_iter_t it = ecs_each(world, Position); test_assert(ecs_each_next(&it) == true); test_int(it.count, 2); if (it.entities[0] == e2) { e1 = it.entities[1]; } else { e1 = it.entities[0]; } test_assert(ecs_each_next(&it) == false); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_has(world, e2, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_w_ref(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, TagA); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {30, 40}); ecs_add_pair(world, e2, TagA, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); test_assert(ecs_get_target(world, e2, TagA, 0) == 0); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); test_assert(e1 != 0); test_assert(ecs_get_target(world, e2, TagA, 0) == e1); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_anon_w_ref(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, TagA); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_new(world); ecs_set(world, e2, Position, {30, 40}); ecs_add_pair(world, e2, TagA, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_get_target(world, e2, TagA, 0) != 0); e1 = ecs_get_target(world, e2, TagA, 0); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_w_cycle_ref(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, TagA); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {30, 40}); ecs_add_pair(world, e1, TagA, e2); ecs_add_pair(world, e2, TagA, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); test_assert(ecs_get_target(world, e2, TagA, 0) == 0); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); test_assert(e1 != 0); test_assert(ecs_get_target(world, e2, TagA, 0) == e1); test_assert(ecs_get_target(world, e1, TagA, 0) == e2); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_anon_w_cycle_ref(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, TagA); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_new(world); ecs_set(world, e2, Position, {30, 40}); ecs_add_pair(world, e1, TagA, e2); ecs_add_pair(world, e2, TagA, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); test_assert(ecs_get_target(world, e2, TagA, 0) == 0); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t tagA = ecs_lookup(world, "TagA"); test_assert(tagA != 0); test_assert(tagA == TagA); e1 = ecs_get_target(world, e2, TagA, 0); test_assert(e1 != 0); test_assert(ecs_get_target(world, e1, TagA, 0) == e2); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_w_recycled(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, TagA); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {30, 40}); ecs_add_pair(world, e1, TagA, e2); ecs_add_pair(world, e2, TagA, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); test_assert(ecs_get_target(world, e2, TagA, 0) == 0); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {50, 60}); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); test_assert(e1 != 0); test_assert(e1 != e3); test_assert(ecs_get_target(world, e2, TagA, 0) == e1); test_assert(ecs_get_target(world, e1, TagA, 0) == e2); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); test_str(ecs_get_name(world, e3), "e3"); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } ecs_fini(world); } void DeserializeFromJson_ser_deser_restore_1_deleted_anon_w_recycled(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, TagA); ecs_entity_t e1 = ecs_new(world); ecs_set(world, e1, Position, {10, 20}); ecs_entity_t e2 = ecs_new(world); ecs_set(world, e2, Position, {30, 40}); ecs_add_pair(world, e1, TagA, e2); ecs_add_pair(world, e2, TagA, e1); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete(world, e1); test_assert(!ecs_is_alive(world, e1)); test_assert(ecs_get_target(world, e2, TagA, 0) == 0); ecs_entity_t e3 = ecs_new(world); ecs_set(world, e3, Position, {50, 60}); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_get_target(world, e2, TagA, 0); test_assert(e1 != 0); test_assert(e1 != e3); test_assert(ecs_get_target(world, e1, TagA, 0) == e2); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } ecs_fini(world); } void OnSet_count(ecs_iter_t *it) { int32_t *count = it->ctx; test_assert(count != NULL); *count += it->count; } void DeserializeFromJson_ser_deser_on_set_3_entities(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); int32_t count = 0; ecs_observer(world, { .query.terms[0].id = ecs_id(Position), .events = { EcsOnSet }, .callback = OnSet_count, .ctx = &count }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e3, Position, {50, 60}); test_int(count, 3); count = 0; char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_int(count, 3); ecs_fini(world); } void DeserializeFromJson_ser_deser_on_set_3_entities_2_restored(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); int32_t count = 0; ecs_observer(world, { .query.terms[0].id = ecs_id(Position), .events = { EcsOnSet }, .callback = OnSet_count, .ctx = &count }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e2, Position, {30, 40}); test_int(count, 2); count = 0; char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {50, 60}); test_int(count, 1); count = 0; const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_int(count, 2); ecs_fini(world); } void DeserializeFromJson_ser_deser_on_set_3_entities_1_restored(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); int32_t count = 0; ecs_observer(world, { .query.terms[0].id = ecs_id(Position), .events = { EcsOnSet }, .callback = OnSet_count, .ctx = &count }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {10, 20}); test_int(count, 1); count = 0; char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e3, Position, {50, 60}); test_int(count, 2); count = 0; const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_int(count, 1); ecs_fini(world); } void DeserializeFromJson_ser_deser_3_entities_after_remove_all(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e3, Position, {50, 60}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_remove_all(world, ecs_id(Position)); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(!ecs_has(world, e1, Position)); test_assert(!ecs_has(world, e2, Position)); test_assert(!ecs_has(world, e3, Position)); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } ecs_fini(world); } void DeserializeFromJson_ser_deser_3_entities_after_delete_with(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e1, Position, {10, 20}); ecs_set(world, e2, Position, {30, 40}); ecs_set(world, e3, Position, {50, 60}); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_delete_with(world, ecs_id(Position)); test_assert(!ecs_is_alive(world, e1)); test_assert(!ecs_is_alive(world, e2)); test_assert(!ecs_is_alive(world, e3)); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); e1 = ecs_lookup(world, "e1"); e2 = ecs_lookup(world, "e2"); e3 = ecs_lookup(world, "e3"); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 30); test_int(p->y, 40); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 50); test_int(p->y, 60); } ecs_fini(world); } typedef struct StringType { char *value; } StringType; static int StringType_ctor_invoked = 0; ECS_CTOR(StringType, ptr, { ptr->value = NULL; StringType_ctor_invoked ++; }) ECS_DTOR(StringType, ptr, { ecs_os_free(ptr->value); }) ECS_MOVE(StringType, dst, src, { if (dst->value) { ecs_os_free(dst->value); } dst->value = src->value; src->value = NULL; }) ECS_COPY(StringType, dst, src, { if (dst->value) { ecs_os_free(dst->value); } dst->value = ecs_os_strdup(src->value); }) void DeserializeFromJson_ser_deser_w_hooks(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, StringType); ecs_struct(world, { .entity = ecs_id(StringType), .members = { {"value", ecs_id(ecs_string_t)} } }); ecs_set_hooks(world, StringType, { .ctor = flecs_default_ctor, .dtor = ecs_dtor(StringType), .move = ecs_move(StringType), .copy = ecs_copy(StringType) }); ecs_entity_t e1 = ecs_insert(world, ecs_value(StringType, {"foo"})); ecs_entity_t e2 = ecs_insert(world, ecs_value(StringType, {"bar"})); ecs_entity_t e3 = ecs_insert(world, ecs_value(StringType, {"hello"})); ecs_entity_t e4 = ecs_insert(world, ecs_value(StringType, {"world"})); ecs_set_name(world, e1, "e1"); ecs_set_name(world, e2, "e2"); ecs_set_name(world, e3, "e3"); ecs_set_name(world, e4, "e4"); char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_remove(world, e1, StringType); ecs_set(world, e2, StringType, { NULL }); ecs_set(world, e3, StringType, { "zoo" }); ecs_delete(world, e4); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_lookup(world, "e1") == e1); test_assert(ecs_lookup(world, "e2") == e2); test_assert(ecs_lookup(world, "e3") == e3); e4 = ecs_lookup(world, "e4"); test_assert(e4 != 0); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_is_alive(world, e4)); test_assert(ecs_has(world, e1, StringType)); test_assert(ecs_has(world, e2, StringType)); test_assert(ecs_has(world, e3, StringType)); test_assert(ecs_has(world, e4, StringType)); { const StringType *st = ecs_get(world, e1, StringType); test_assert(st != NULL); test_str(st->value, "foo"); } { const StringType *st = ecs_get(world, e2, StringType); test_assert(st != NULL); test_str(st->value, "bar"); } { const StringType *st = ecs_get(world, e3, StringType); test_assert(st != NULL); test_str(st->value, "hello"); } { const StringType *st = ecs_get(world, e4, StringType); test_assert(st != NULL); test_str(st->value, "world"); } ecs_fini(world); } void DeserializeFromJson_ser_deser_large_data(void) { typedef struct { char* v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_string_t)} } }); test_assert(t != 0); char *long_str = ecs_os_malloc_n(char, 1024); ecs_os_memset(long_str, 'a', 1023); long_str[1023] = '\0'; T value = { .v = long_str }; char *long_str_ser = flecs_asprintf("{\"v\":\"%s\"}", long_str); char *json = ecs_ptr_to_json(world, t, &value); test_assert(json != NULL); test_str(json, long_str_ser); ecs_os_free(long_str_ser); value.v = NULL; const char *ptr = ecs_ptr_from_json(world, t, &value, json, NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_str(value.v, long_str); ecs_os_free(value.v); ecs_os_free(long_str); ecs_os_free(json); ecs_fini(world); } void DeserializeFromJson_ser_deser_different_component_order(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_is_alive(world, ecs_id(Velocity))); test_assert(ecs_is_alive(world, ecs_id(Mass))); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); test_str(ecs_get_name(world, ecs_id(Velocity)), "Velocity"); test_str(ecs_get_name(world, ecs_id(Mass)), "Mass"); ecs_entity_t e1 = ecs_lookup(world, "e1"); ecs_entity_t e2 = ecs_lookup(world, "e2"); ecs_entity_t e3 = ecs_lookup(world, "e3"); ecs_entity_t e4 = ecs_lookup(world, "e4"); ecs_entity_t e5 = ecs_lookup(world, "e5"); ecs_entity_t e6 = ecs_lookup(world, "e6"); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_is_alive(world, e4)); test_assert(ecs_is_alive(world, e5)); test_assert(ecs_is_alive(world, e6)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); test_str(ecs_get_name(world, e3), "e3"); test_str(ecs_get_name(world, e4), "e4"); test_str(ecs_get_name(world, e5), "e5"); test_str(ecs_get_name(world, e6), "e6"); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); test_assert(ecs_has(world, e4, Position)); test_assert(ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); test_assert(ecs_has(world, e5, Velocity)); test_assert(ecs_has(world, e6, Velocity)); test_assert(ecs_has(world, e1, Mass)); test_assert(ecs_has(world, e2, Mass)); test_assert(ecs_has(world, e3, Mass)); test_assert(ecs_has(world, e4, Mass)); test_assert(ecs_has(world, e5, Mass)); test_assert(ecs_has(world, e6, Mass)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 11); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 12); test_int(p->y, 20); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 13); test_int(p->y, 20); } { const Position *p = ecs_get(world, e4, Position); test_assert(p != NULL); test_int(p->x, 14); test_int(p->y, 20); } { const Velocity *v = ecs_get(world, e1, Velocity); test_assert(v != NULL); test_int(v->x, 1); test_int(v->y, 2); } { const Velocity *v = ecs_get(world, e2, Velocity); test_assert(v != NULL); test_int(v->x, 2); test_int(v->y, 2); } { const Velocity *v = ecs_get(world, e5, Velocity); test_assert(v != NULL); test_int(v->x, 5); test_int(v->y, 2); } { const Velocity *v = ecs_get(world, e6, Velocity); test_assert(v != NULL); test_int(v->x, 6); test_int(v->y, 2); } { const Mass *m = ecs_get(world, e1, Mass); test_assert(m != NULL); test_int(m->value, 100); } { const Mass *m = ecs_get(world, e2, Mass); test_assert(m != NULL); test_int(m->value, 200); } { const Mass *m = ecs_get(world, e3, Mass); test_assert(m != NULL); test_int(m->value, 300); } { const Mass *m = ecs_get(world, e4, Mass); test_assert(m != NULL); test_int(m->value, 400); } { const Mass *m = ecs_get(world, e5, Mass); test_assert(m != NULL); test_int(m->value, 500); } { const Mass *m = ecs_get(world, e6, Mass); test_assert(m != NULL); test_int(m->value, 600); } } ecs_fini(world); } void DeserializeFromJson_ser_deser_no_reflection_data(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_log_set_level(-4); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_is_alive(world, ecs_id(Velocity))); test_assert(ecs_is_alive(world, ecs_id(Mass))); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); test_str(ecs_get_name(world, ecs_id(Velocity)), "Velocity"); test_str(ecs_get_name(world, ecs_id(Mass)), "Mass"); ecs_entity_t e1 = ecs_lookup(world, "e1"); ecs_entity_t e2 = ecs_lookup(world, "e2"); ecs_entity_t e3 = ecs_lookup(world, "e3"); ecs_entity_t e4 = ecs_lookup(world, "e4"); ecs_entity_t e5 = ecs_lookup(world, "e5"); ecs_entity_t e6 = ecs_lookup(world, "e6"); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_is_alive(world, e4)); test_assert(ecs_is_alive(world, e5)); test_assert(ecs_is_alive(world, e6)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); test_str(ecs_get_name(world, e3), "e3"); test_str(ecs_get_name(world, e4), "e4"); test_str(ecs_get_name(world, e5), "e5"); test_str(ecs_get_name(world, e6), "e6"); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); test_assert(ecs_has(world, e4, Position)); test_assert(ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); test_assert(ecs_has(world, e5, Velocity)); test_assert(ecs_has(world, e6, Velocity)); test_assert(ecs_has(world, e1, Mass)); test_assert(ecs_has(world, e2, Mass)); test_assert(ecs_has(world, e3, Mass)); test_assert(ecs_has(world, e4, Mass)); test_assert(ecs_has(world, e5, Mass)); test_assert(ecs_has(world, e6, Mass)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 11); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 12); test_int(p->y, 20); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 13); test_int(p->y, 20); } { const Position *p = ecs_get(world, e4, Position); test_assert(p != NULL); test_int(p->x, 14); test_int(p->y, 20); } { const Mass *m = ecs_get(world, e1, Mass); test_assert(m != NULL); test_int(m->value, 100); } { const Mass *m = ecs_get(world, e2, Mass); test_assert(m != NULL); test_int(m->value, 200); } { const Mass *m = ecs_get(world, e3, Mass); test_assert(m != NULL); test_int(m->value, 300); } { const Mass *m = ecs_get(world, e4, Mass); test_assert(m != NULL); test_int(m->value, 400); } { const Mass *m = ecs_get(world, e5, Mass); test_assert(m != NULL); test_int(m->value, 500); } { const Mass *m = ecs_get(world, e6, Mass); test_assert(m != NULL); test_int(m->value, 600); } } ecs_fini(world); } void DeserializeFromJson_ser_deser_no_reflection_data_strict(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_log_set_level(-4); ecs_from_json_desc_t desc = { .strict = true }; const char *r = ecs_world_from_json(world, json, &desc); test_assert(r == NULL); ecs_os_free(json); } ecs_fini(world); } void DeserializeFromJson_ser_deser_value_for_tag(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, Velocity); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_log_set_level(-4); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_is_alive(world, ecs_id(Velocity))); test_assert(ecs_is_alive(world, ecs_id(Mass))); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); test_str(ecs_get_name(world, ecs_id(Velocity)), "Velocity"); test_str(ecs_get_name(world, ecs_id(Mass)), "Mass"); ecs_entity_t e1 = ecs_lookup(world, "e1"); ecs_entity_t e2 = ecs_lookup(world, "e2"); ecs_entity_t e3 = ecs_lookup(world, "e3"); ecs_entity_t e4 = ecs_lookup(world, "e4"); ecs_entity_t e5 = ecs_lookup(world, "e5"); ecs_entity_t e6 = ecs_lookup(world, "e6"); test_assert(e1 != 0); test_assert(e2 != 0); test_assert(e3 != 0); test_assert(e4 != 0); test_assert(e5 != 0); test_assert(e6 != 0); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_is_alive(world, e4)); test_assert(ecs_is_alive(world, e5)); test_assert(ecs_is_alive(world, e6)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); test_str(ecs_get_name(world, e3), "e3"); test_str(ecs_get_name(world, e4), "e4"); test_str(ecs_get_name(world, e5), "e5"); test_str(ecs_get_name(world, e6), "e6"); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); test_assert(ecs_has(world, e4, Position)); test_assert(ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); test_assert(ecs_has(world, e5, Velocity)); test_assert(ecs_has(world, e6, Velocity)); test_assert(ecs_has(world, e1, Mass)); test_assert(ecs_has(world, e2, Mass)); test_assert(ecs_has(world, e3, Mass)); test_assert(ecs_has(world, e4, Mass)); test_assert(ecs_has(world, e5, Mass)); test_assert(ecs_has(world, e6, Mass)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 11); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 12); test_int(p->y, 20); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 13); test_int(p->y, 20); } { const Position *p = ecs_get(world, e4, Position); test_assert(p != NULL); test_int(p->x, 14); test_int(p->y, 20); } { const Mass *m = ecs_get(world, e1, Mass); test_assert(m != NULL); test_int(m->value, 100); } { const Mass *m = ecs_get(world, e2, Mass); test_assert(m != NULL); test_int(m->value, 200); } { const Mass *m = ecs_get(world, e3, Mass); test_assert(m != NULL); test_int(m->value, 300); } { const Mass *m = ecs_get(world, e4, Mass); test_assert(m != NULL); test_int(m->value, 400); } { const Mass *m = ecs_get(world, e5, Mass); test_assert(m != NULL); test_int(m->value, 500); } { const Mass *m = ecs_get(world, e6, Mass); test_assert(m != NULL); test_int(m->value, 600); } } ecs_fini(world); } void DeserializeFromJson_ser_deser_value_for_tag_strict(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_TAG(world, Velocity); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_log_set_level(-4); ecs_from_json_desc_t desc = { .strict = true }; const char *r = ecs_world_from_json(world, json, &desc); test_assert(r == NULL); ecs_os_free(json); } ecs_fini(world); } void DeserializeFromJson_ser_deser_value_for_non_existing(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_log_set_level(-4); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t ecs_id(Velocity) = ecs_lookup( world, "module.Velocity"); test_assert(ecs_id(Velocity) != 0); test_assert(ecs_is_alive(world, ecs_id(Position))); test_assert(ecs_is_alive(world, ecs_id(Velocity))); test_assert(ecs_is_alive(world, ecs_id(Mass))); test_str(ecs_get_name(world, ecs_id(Position)), "Position"); test_str(ecs_get_name(world, ecs_id(Velocity)), "Velocity"); test_str(ecs_get_name(world, ecs_id(Mass)), "Mass"); ecs_entity_t e1 = ecs_lookup(world, "e1"); ecs_entity_t e2 = ecs_lookup(world, "e2"); ecs_entity_t e3 = ecs_lookup(world, "e3"); ecs_entity_t e4 = ecs_lookup(world, "e4"); ecs_entity_t e5 = ecs_lookup(world, "e5"); ecs_entity_t e6 = ecs_lookup(world, "e6"); test_assert(ecs_is_alive(world, e1)); test_assert(ecs_is_alive(world, e2)); test_assert(ecs_is_alive(world, e3)); test_assert(ecs_is_alive(world, e4)); test_assert(ecs_is_alive(world, e5)); test_assert(ecs_is_alive(world, e6)); test_str(ecs_get_name(world, e1), "e1"); test_str(ecs_get_name(world, e2), "e2"); test_str(ecs_get_name(world, e3), "e3"); test_str(ecs_get_name(world, e4), "e4"); test_str(ecs_get_name(world, e5), "e5"); test_str(ecs_get_name(world, e6), "e6"); test_assert(ecs_has(world, e1, Position)); test_assert(ecs_has(world, e2, Position)); test_assert(ecs_has(world, e3, Position)); test_assert(ecs_has(world, e4, Position)); test_assert(ecs_has(world, e1, Velocity)); test_assert(ecs_has(world, e2, Velocity)); test_assert(ecs_has(world, e5, Velocity)); test_assert(ecs_has(world, e6, Velocity)); test_assert(ecs_has(world, e1, Mass)); test_assert(ecs_has(world, e2, Mass)); test_assert(ecs_has(world, e3, Mass)); test_assert(ecs_has(world, e4, Mass)); test_assert(ecs_has(world, e5, Mass)); test_assert(ecs_has(world, e6, Mass)); { const Position *p = ecs_get(world, e1, Position); test_assert(p != NULL); test_int(p->x, 11); test_int(p->y, 20); } { const Position *p = ecs_get(world, e2, Position); test_assert(p != NULL); test_int(p->x, 12); test_int(p->y, 20); } { const Position *p = ecs_get(world, e3, Position); test_assert(p != NULL); test_int(p->x, 13); test_int(p->y, 20); } { const Position *p = ecs_get(world, e4, Position); test_assert(p != NULL); test_int(p->x, 14); test_int(p->y, 20); } { const Mass *m = ecs_get(world, e1, Mass); test_assert(m != NULL); test_int(m->value, 100); } { const Mass *m = ecs_get(world, e2, Mass); test_assert(m != NULL); test_int(m->value, 200); } { const Mass *m = ecs_get(world, e3, Mass); test_assert(m != NULL); test_int(m->value, 300); } { const Mass *m = ecs_get(world, e4, Mass); test_assert(m != NULL); test_int(m->value, 400); } { const Mass *m = ecs_get(world, e5, Mass); test_assert(m != NULL); test_int(m->value, 500); } { const Mass *m = ecs_get(world, e6, Mass); test_assert(m != NULL); test_int(m->value, 600); } } ecs_fini(world); } void DeserializeFromJson_ser_deser_value_for_non_existing_strict(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Velocity); ecs_struct(world, { .entity = ecs_id(Velocity), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_entity_t e1 = ecs_entity(world, { .name = "e1" }); ecs_set(world, e1, Position, {11, 20}); ecs_set(world, e1, Velocity, {1, 2}); ecs_set(world, e1, Mass, {100}); ecs_add(world, e1, Foo); ecs_entity_t e2 = ecs_entity(world, { .name = "e2" }); ecs_set(world, e2, Position, {12, 20}); ecs_set(world, e2, Velocity, {2, 2}); ecs_set(world, e2, Mass, {200}); ecs_add(world, e2, Foo); ecs_entity_t e3 = ecs_entity(world, { .name = "e3" }); ecs_set(world, e3, Position, {13, 20}); ecs_set(world, e3, Mass, {300}); ecs_add(world, e3, Foo); ecs_entity_t e4 = ecs_entity(world, { .name = "e4" }); ecs_set(world, e4, Position, {14, 20}); ecs_set(world, e4, Mass, {400}); ecs_add(world, e4, Foo); ecs_entity_t e5 = ecs_entity(world, { .name = "e5" }); ecs_set(world, e5, Velocity, {5, 2}); ecs_set(world, e5, Mass, {500}); ecs_add(world, e5, Foo); ecs_entity_t e6 = ecs_entity(world, { .name = "e6" }); ecs_set(world, e6, Velocity, {6, 2}); ecs_set(world, e6, Mass, {600}); ecs_add(world, e6, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ecs_entity_t module = ecs_entity(world, { .name = "module" }); ecs_add_id(world, module, EcsModule); ecs_set_scope(world, module); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_set_scope(world, 0); ecs_log_set_level(-4); ecs_from_json_desc_t desc = { .strict = true }; const char *r = ecs_world_from_json(world, json, &desc); test_assert(r == NULL); ecs_os_free(json); } ecs_fini(world); } static void ser_deser_cpp_name_test( const char *typename) { ecs_world_t *world = ecs_init(); { ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_entity_t t = ecs_new_low_id(world); ecs_set_name(world, t, typename); test_assert(t != 0); test_str(ecs_get_name(world, t), typename); ecs_entity_t child = ecs_entity(world, { .name = "c" }); ecs_add_pair(world, child, EcsChildOf, t); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_set(world, e, Position, {10, 20}); ecs_set(world, e, Mass, {100}); ecs_add_id(world, e, t); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ECS_COMPONENT(world, Mass); ecs_struct(world, { .entity = ecs_id(Mass), .members = { {"value", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t t = ecs_lookup(world, typename); test_assert(t != 0); ecs_entity_t e = ecs_lookup(world, "e"); test_assert(e != 0); ecs_entity_t c = ecs_lookup_child(world, t, "c"); test_assert(c != 0); test_assert(ecs_has_id(world, e, t)); { const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); } { const Mass *m = ecs_get(world, e, Mass); test_assert(m != NULL); test_int(m->value, 100); } } ecs_fini(world); } void DeserializeFromJson_ser_deser_cpp_typename(void) { ser_deser_cpp_name_test("std::vector"); } void DeserializeFromJson_ser_deser_cpp_template(void) { ser_deser_cpp_name_test("std::vector<>"); } void DeserializeFromJson_ser_deser_cpp_template_1_param(void) { ser_deser_cpp_name_test("std::vector"); } void DeserializeFromJson_ser_deser_cpp_template_n_params(void) { ser_deser_cpp_name_test("std::vector"); } void DeserializeFromJson_ser_deser_cpp_template_nested(void) { ser_deser_cpp_name_test("std::vector >"); } void DeserializeFromJson_ser_deser_cpp_template_n_params_nested(void) { ser_deser_cpp_name_test("std::vector, std::vector >"); } void DeserializeFromJson_ser_deser_long_name(void) { ser_deser_cpp_name_test( "std::vector::anothertype, " "std::allocator::anothertype> >"); } void DeserializeFromJson_ser_deser_long_name_256_chars(void) { ser_deser_cpp_name_test( "abcdefghij1234567890abcdefghij1234567890" "abcdefghij1234567890abcdefghij1234567890" "abcdefghij1234567890abcdefghij1234567890" "abcdefghij1234567890abcdefghij1234567890" "abcdefghij1234567890abcdefghij1234567890" "abcdefghij1234567890abcdefghij1234567890" "abcdefghij123456"); } void DeserializeFromJson_ser_deser_w_alerts(void) { ecs_world_t *world = ecs_init(); { ECS_IMPORT(world, FlecsAlerts); ECS_TAG(world, Foo); ECS_TAG(world, Bar); ecs_entity_t alert = ecs_alert(world, { .entity = ecs_entity(world, { .name = "module.my_alert" }), .query.expr = "Foo, !Bar" }); test_assert(alert != 0); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add(world, e, Foo); ecs_progress(world, 2.0); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_IMPORT(world, FlecsAlerts); ECS_TAG(world, Foo); ECS_TAG(world, Bar); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t e = ecs_lookup(world, "e"); test_assert(e != 0); test_assert(ecs_has(world, e, Foo)); test_assert(!ecs_has(world, e, Bar)); } ecs_fini(world); } void DeserializeFromJson_ser_deser_struct(void) { ecs_world_t *world = ecs_init(); { ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t t = ecs_lookup(world, "Position"); test_assert(t != 0); const EcsComponent *c = ecs_get(world, t, EcsComponent); test_assert(c != NULL); test_int(c->size, 8); test_int(c->alignment, 4); ecs_entity_t x = ecs_lookup_child(world, t, "x"); test_assert(x != 0); ecs_entity_t y = ecs_lookup_child(world, t, "y"); test_assert(y != 0); test_assert(ecs_has(world, x, EcsMember)); test_assert(ecs_has(world, y, EcsMember)); { const EcsMember *m = ecs_get(world, x, EcsMember); test_assert(m != NULL); test_int(m->offset, 0); test_uint(m->type, ecs_id(ecs_i32_t)); } { const EcsMember *m = ecs_get(world, y, EcsMember); test_assert(m != NULL); test_int(m->offset, 4); test_uint(m->type, ecs_id(ecs_i32_t)); } } ecs_fini(world); } void DeserializeFromJson_ser_deser_w_alerts_w_progress(void) { ecs_world_t *world = ecs_init(); { ECS_IMPORT(world, FlecsAlerts); ECS_TAG(world, Foo); ECS_TAG(world, Bar); ecs_entity_t alert = ecs_alert(world, { .entity = ecs_entity(world, { .name = "module.my_alert" }), .query.expr = "Foo, !Bar" }); test_assert(alert != 0); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add(world, e, Foo); ecs_progress(world, 2.0); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_IMPORT(world, FlecsAlerts); ECS_TAG(world, Foo); ECS_TAG(world, Bar); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t e = ecs_lookup(world, "e"); test_assert(e != 0); test_assert(ecs_has(world, e, Foo)); test_assert(!ecs_has(world, e, Bar)); } ecs_progress(world, 2.0); test_assert(true); ecs_fini(world); } void DeserializeFromJson_ser_deser_anon_w_same_id_as_existing_named(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ECS_TAG(world, Bar); ecs_entity_t e = 2000; ecs_make_alive(world, e); ecs_add(world, e, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_IMPORT(world, FlecsAlerts); ECS_TAG(world, Foo); ECS_TAG(world, Bar); ecs_entity_t e = 2000; ecs_make_alive(world, e); ecs_set_name(world, e, "e"); ecs_add(world, e, Bar); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(!ecs_has(world, e, Foo)); test_assert(ecs_has(world, e, Bar)); test_int(ecs_count(world, Foo), 1); } ecs_fini(world); } void DeserializeFromJson_deser_invalid_entity_name(void) { char *json = "{\"results\":[" "{\"ids\":[[\"flecs.core.Identifier\",\"flecs.core.Name\"]], \"entities\":[\"Foo\"], \"values\":[0]}, " "{\"ids\":[[\"Foo\"]], \"entities\":[\"1e4\", 20000]}]}"; ecs_world_t *world = ecs_init(); { ecs_log_set_level(-4); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, NULL); } ecs_fini(world); } void DeserializeFromJson_ser_deser_named_to_different_table(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add(world, e, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t e = ecs_entity(world, { .name = "e" }); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_has(world, e, Foo)); } ecs_fini(world); } void DeserializeFromJson_ser_deser_named_child_to_different_table(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t p = ecs_entity(world, { .name = "p" }); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add_pair(world, e, EcsChildOf, p); ecs_add(world, e, Foo); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_TAG(world, Foo); ecs_entity_t p = ecs_entity(world, { .name = "p" }); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add_pair(world, e, EcsChildOf, p); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); test_assert(ecs_has(world, e, Foo)); test_assert(ecs_has_pair(world, e, EcsChildOf, p)); } ecs_fini(world); } void DeserializeFromJson_ser_deser_with_child_tgt(void) { ecs_world_t *world = ecs_init(); { ECS_TAG(world, Rel); ECS_TAG(world, Foo); ecs_entity_t p = ecs_entity(world, { .name = "p" }); ecs_entity_t e = ecs_entity(world, { .name = "e" }); ecs_add_pair(world, e, EcsChildOf, p); ecs_add(world, e, Foo); ecs_entity_t c = ecs_entity(world, { .name = "c" }); ecs_add_pair(world, c, EcsChildOf, e); ecs_add_pair(world, e, Rel, c); } char *json = ecs_world_to_json(world, NULL); test_assert(json != NULL); ecs_fini(world); world = ecs_init(); { ECS_TAG(world, Rel); ECS_TAG(world, Foo); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_os_free(json); ecs_entity_t p = ecs_lookup(world, "p"); test_assert(p != 0); ecs_entity_t e = ecs_lookup(world, "p.e"); test_assert(e != 0); ecs_entity_t c = ecs_lookup(world, "p.e.c"); test_assert(c != 0); test_assert(ecs_has(world, e, Foo)); test_assert(ecs_has_pair(world, e, EcsChildOf, p)); test_assert(ecs_has_pair(world, e, Rel, c)); test_assert(ecs_has_pair(world, c, EcsChildOf, e)); } ecs_fini(world); } void DeserializeFromJson_ser_deser_with_child_tgt_no_child(void) { ecs_world_t *world = ecs_init(); char *json = "{\"results\": [{\"parent\": \"p\", \"name\": \"e\", \"id\": 1000, \"tags\": [\"Foo\"], \"pairs\": {\"flecs.core.ChildOf\": \"p\", \"Rel\": \"p.e.c\"}, \"components\": {\"(flecs.core.Identifier,flecs.core.Name)\": null } } ] }"; ecs_fini(world); world = ecs_init(); { ECS_TAG(world, Rel); ECS_TAG(world, Foo); const char *r = ecs_world_from_json(world, json, NULL); test_str(r, ""); ecs_entity_t p = ecs_lookup(world, "p"); test_assert(p != 0); ecs_entity_t e = ecs_lookup(world, "p.e"); test_assert(e != 0); ecs_entity_t c = ecs_lookup(world, "p.e.c"); test_assert(c != 0); test_assert(ecs_has(world, e, Foo)); test_assert(ecs_has_pair(world, e, EcsChildOf, p)); test_assert(ecs_has_pair(world, e, Rel, c)); test_assert(ecs_has_pair(world, c, EcsChildOf, e)); } ecs_fini(world); } void DeserializeFromJson_deser_unknown_component_w_spaces(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, "{\"results\":[{\"name\":\"e\", \"components\":{\"Position\": {\"x\": 10, \"y\": 20}, \"DoesntExist\": {\"pos\":{\"x\":20, \"y\":30}}}}]}", NULL); test_assert(r != NULL); test_assert(r[0] == 0); ecs_entity_t e = ecs_lookup(world, "e"); test_assert(e != 0); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_deser_unknown_component_no_spaces(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); const char *r = ecs_world_from_json(world, "{\"results\":[{\"name\":\"e\", \"components\":{\"Position\":{\"x\": 10, \"y\": 20}, \"DoesntExist\":{\"pos\":{\"x\":20, \"y\":30}}}}]}", NULL); test_assert(r != NULL); test_assert(r[0] == 0); ecs_entity_t e = ecs_lookup(world, "e"); test_assert(e != 0); const Position *p = ecs_get(world, e, Position); test_assert(p != NULL); test_int(p->x, 10); test_int(p->y, 20); ecs_fini(world); } void DeserializeFromJson_deser_unknown_component_w_spaces_strict(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_from_json_desc_t desc = { .strict = true }; ecs_log_set_level(-4); const char *r = ecs_world_from_json(world, "{\"results\":[{\"name\":\"e\", \"components\":{\"Position\": {\"x\": 10, \"y\": 20}, \"DoesntExist\": {\"pos\":{\"x\":20, \"y\":30}}}}]}", &desc); test_assert(r == NULL); ecs_fini(world); } void DeserializeFromJson_deser_unknown_component_no_spaces_strict(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)}, } }); ecs_from_json_desc_t desc = { .strict = true }; ecs_log_set_level(-4); const char *r = ecs_world_from_json(world, "{\"results\":[{\"name\":\"e\", \"components\":{\"Position\":{\"x\": 10, \"y\": 20}, \"DoesntExist\":{\"pos\":{\"x\":20, \"y\":30}}}}]}", &desc); test_assert(r == NULL); ecs_fini(world); } void DeserializeFromJson_deser_unknown_member(void) { typedef struct { ecs_i32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10, \"y\": 20}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_deser_valid_after_unknown_member(void) { typedef struct { ecs_i32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i32_t)} } }); test_assert(t != 0); T value = {0}; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"y\": 20, \"v\": 10}", NULL); test_assert(ptr != NULL); test_assert(ptr[0] == '\0'); test_int(value.v, 10); ecs_fini(world); } void DeserializeFromJson_deser_unknown_member_w_strict(void) { typedef struct { ecs_i32_t v; } T; ecs_world_t *world = ecs_init(); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"v", ecs_id(ecs_i32_t)} } }); test_assert(t != 0); T value = {0}; ecs_log_set_level(-4); ecs_from_json_desc_t desc = { .strict = true }; const char *ptr = ecs_ptr_from_json(world, t, &value, "{\"v\": 10, \"y\": 20}", &desc); test_assert(ptr == NULL); ecs_fini(world); } void DeserializeFromJson_deser_pretty_printed_identifier_pair(void) { ecs_world_t *world = ecs_init(); const char *expr = HEAD "" LINE "{" LINE " \"results\":" LINE " [" LINE " {" LINE " \"name\": \"e\"," LINE " \"components\":" LINE " {" LINE " \"(flecs.core.Identifier,flecs.core.Symbol)\":" LINE " {" LINE " \"value\": \"E\"" LINE " }" LINE " }" LINE " }" LINE " ]" LINE "}" LINE ""; test_assert(ecs_world_from_json(world, expr, NULL) != NULL); ecs_entity_t e = ecs_lookup(world, "e"); test_str(ecs_get_name(world, e), "e"); ecs_fini(world); } void DeserializeFromJson_ser_deser_alias(void) { const char *name = "child"; ecs_world_t *world = ecs_init(); ecs_entity_t parent = ecs_new(world); ecs_entity_t child = ecs_new(world); ecs_add_pair(world, child, EcsChildOf, parent); ecs_set_alias(world, child, name); test_assert(ecs_lookup(world, name)); char *json = ecs_world_to_json(world, NULL); ecs_world_t *new_world = ecs_init(); ecs_world_from_json(new_world, json, NULL); test_assert(ecs_lookup(new_world, name)); ecs_os_free(json); ecs_fini(world); }