#include void Cursor_set_bool(void) { ecs_world_t *world = ecs_init(); ecs_bool_t value = false; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_bool_t), &value); test_ok( ecs_meta_set_bool(&cur, true) ); test_bool(value, true); ecs_fini(world); } void Cursor_set_byte(void) { ecs_world_t *world = ecs_init(); ecs_byte_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_byte_t), &value); test_ok( ecs_meta_set_uint(&cur, 20) ); test_uint(value, 20); ecs_fini(world); } void Cursor_set_char(void) { ecs_world_t *world = ecs_init(); ecs_char_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_char_t), &value); test_ok( ecs_meta_set_int(&cur, 20) ); test_int(value, 20); ecs_fini(world); } void Cursor_set_i8(void) { ecs_world_t *world = ecs_init(); ecs_i8_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i8_t), &value); test_ok( ecs_meta_set_int(&cur, 20) ); test_int(value, 20); ecs_fini(world); } void Cursor_set_i16(void) { ecs_world_t *world = ecs_init(); ecs_i16_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i16_t), &value); test_ok( ecs_meta_set_int(&cur, 20) ); test_int(value, 20); ecs_fini(world); } void Cursor_set_i32(void) { ecs_world_t *world = ecs_init(); ecs_i32_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i32_t), &value); test_ok( ecs_meta_set_int(&cur, 20) ); test_int(value, 20); ecs_fini(world); } void Cursor_set_i64(void) { ecs_world_t *world = ecs_init(); ecs_i64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i64_t), &value); test_ok( ecs_meta_set_int(&cur, 20) ); test_int(value, 20); ecs_fini(world); } void Cursor_set_iptr(void) { ecs_world_t *world = ecs_init(); ecs_iptr_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_iptr_t), &value); test_ok( ecs_meta_set_int(&cur, 20) ); test_int(value, 20); ecs_fini(world); } void Cursor_set_u8(void) { ecs_world_t *world = ecs_init(); ecs_u8_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u8_t), &value); test_ok( ecs_meta_set_uint(&cur, 20) ); test_uint(value, 20); ecs_fini(world); } void Cursor_set_u16(void) { ecs_world_t *world = ecs_init(); ecs_u16_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u8_t), &value); test_ok( ecs_meta_set_uint(&cur, 20) ); test_uint(value, 20); ecs_fini(world); } void Cursor_set_u32(void) { ecs_world_t *world = ecs_init(); ecs_u32_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u32_t), &value); test_ok( ecs_meta_set_uint(&cur, 20) ); test_uint(value, 20); ecs_fini(world); } void Cursor_set_u64(void) { ecs_world_t *world = ecs_init(); { ecs_u64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u64_t), &value); test_ok( ecs_meta_set_uint(&cur, 20) ); test_uint(value, 20); } { ecs_u64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u64_t), &value); test_ok( ecs_meta_set_uint(&cur, 2366700781656087864) ); test_uint(value, 2366700781656087864); } ecs_fini(world); } void Cursor_set_uptr(void) { ecs_world_t *world = ecs_init(); ecs_uptr_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_uptr_t), &value); test_ok( ecs_meta_set_uint(&cur, 20) ); test_uint(value, 20); ecs_fini(world); } void Cursor_set_float(void) { ecs_world_t *world = ecs_init(); ecs_f32_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_f32_t), &value); test_ok( ecs_meta_set_float(&cur, 20.5) ); test_flt(value, 20.5); ecs_fini(world); } void Cursor_set_double(void) { ecs_world_t *world = ecs_init(); ecs_f64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_f64_t), &value); test_ok( ecs_meta_set_float(&cur, 20.5) ); test_flt(value, 20.5); ecs_fini(world); } void Cursor_set_string(void) { ecs_world_t *world = ecs_init(); char *value = NULL; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_string(&cur, "HelloWorld") ); test_str(value, "HelloWorld"); ecs_os_free(value); ecs_fini(world); } void Cursor_set_string_literal(void) { ecs_world_t *world = ecs_init(); char *value = NULL; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_string_literal(&cur, "\"HelloWorld\"") ); test_str(value, "HelloWorld"); ecs_os_free(value); ecs_fini(world); } void Cursor_set_string_to_null(void) { ecs_world_t *world = ecs_init(); char *value = ecs_os_strdup("HelloWorld"); ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_null(&cur) ); test_str(value, NULL); ecs_os_free(value); ecs_fini(world); } void Cursor_set_entity(void) { ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_ok( ecs_meta_set_entity(&cur, EcsFlecs) ); test_uint(value, EcsFlecs); ecs_fini(world); } void Cursor_set_entity_to_number(void) { ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_ok( ecs_meta_set_uint(&cur, 500) ); test_uint(value, 500); ecs_fini(world); } void Cursor_set_entity_to_0(void) { ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_ok( ecs_meta_set_uint(&cur, 0) ); test_uint(value, 0); ecs_fini(world); } void Cursor_set_enum(void) { ecs_world_t *world = ecs_init(); typedef enum { Red, Green, Blue } Color; ecs_entity_t t = ecs_enum(world, { .constants = { { "Red" }, { "Green" }, { "Blue"} } }); test_assert(t != 0); Color value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_set_int(&cur, Green) ); test_int(value, Green); ecs_fini(world); } void Cursor_set_bitmask(void) { ecs_world_t *world = ecs_init(); uint32_t Bacon = 1; uint32_t Lettuce = 2; ecs_entity_t t = ecs_bitmask(world, { .constants = { { "Bacon" }, { "Lettuce" } } }); test_assert(t != 0); uint32_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_set_uint(&cur, Bacon | Lettuce) ); test_uint(value, Bacon | Lettuce); ecs_fini(world); } void Cursor_set_signed_as_unsigned(void) { ecs_world_t *world = ecs_init(); int32_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i32_t), &value); test_ok( ecs_meta_set_uint(&cur, 10) ); test_int(value, 10); ecs_fini(world); } void Cursor_set_unsigned_as_signed(void) { ecs_world_t *world = ecs_init(); uint32_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u32_t), &value); test_ok( ecs_meta_set_int(&cur, 10) ); test_int(value, 10); ecs_fini(world); } void Cursor_set_signed_as_unsigned_out_of_range(void) { ecs_log_set_level(-4); ecs_world_t *world = ecs_init(); int8_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i8_t), &value); test_fail( ecs_meta_set_uint(&cur, 128) ); test_int(value, 0); ecs_fini(world); } void Cursor_set_unsigned_as_signed_out_of_range(void) { ecs_log_set_level(-4); ecs_world_t *world = ecs_init(); uint32_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u32_t), &value); test_fail( ecs_meta_set_int(&cur, -10) ); test_int(value, 0); ecs_fini(world); } void Cursor_set_string_to_null_as_signed(void) { ecs_world_t *world = ecs_init(); char *value = ecs_os_strdup("Hello"); ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_int(&cur, 0) ); test_str(value, 0); ecs_fini(world); } void Cursor_set_string_to_null_as_unsigned(void) { ecs_world_t *world = ecs_init(); char *value = ecs_os_strdup("Hello"); ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_uint(&cur, 0) ); test_str(value, 0); ecs_fini(world); } void Cursor_set_entity_as_signed(void) { ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_entity_t e = ecs_new_id(world); ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_ok( ecs_meta_set_int(&cur, (int64_t)e) ); test_uint(value, e); ecs_fini(world); } void Cursor_set_entity_as_unsigned(void) { ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_entity_t e = ecs_new_id(world); ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_ok( ecs_meta_set_uint(&cur, e) ); test_uint(value, e); ecs_fini(world); } void Cursor_set_entity_as_signed_out_of_range(void) { ecs_log_set_level(-4); ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_fail( ecs_meta_set_int(&cur, -10) ); test_uint(value, 0); ecs_fini(world); } void Cursor_set_str_to_bool(void) { ecs_world_t *world = ecs_init(); ecs_bool_t value = false; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_bool_t), &value); test_ok( ecs_meta_set_string(&cur, "true") ); test_bool(value, true); cur = ecs_meta_cursor(world, ecs_id(ecs_bool_t), &value); test_ok( ecs_meta_set_string(&cur, "false") ); test_bool(value, false); ecs_fini(world); } void Cursor_set_str_to_char(void) { ecs_world_t *world = ecs_init(); ecs_char_t value = false; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_char_t), &value); test_ok( ecs_meta_set_string(&cur, "10") ); test_bool(value, 10); ecs_fini(world); } void Cursor_set_str_literal_to_char(void) { ecs_world_t *world = ecs_init(); ecs_char_t value = false; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_char_t), &value); test_ok( ecs_meta_set_string_literal(&cur, "\"a\"") ); test_int(value, 'a'); ecs_fini(world); } void Cursor_set_str_to_i8(void) { ecs_world_t *world = ecs_init(); ecs_i8_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i8_t), &value); test_ok( ecs_meta_set_string(&cur, "20") ); test_int(value, 20); ecs_fini(world); } void Cursor_set_str_to_i16(void) { ecs_world_t *world = ecs_init(); ecs_i16_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i16_t), &value); test_ok( ecs_meta_set_string(&cur, "20") ); test_int(value, 20); ecs_fini(world); } void Cursor_set_str_to_i32(void) { ecs_world_t *world = ecs_init(); ecs_i32_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i32_t), &value); test_ok( ecs_meta_set_string(&cur, "20") ); test_int(value, 20); ecs_fini(world); } void Cursor_set_str_to_i64(void) { ecs_world_t *world = ecs_init(); { ecs_i64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i64_t), &value); test_ok( ecs_meta_set_string(&cur, "20") ); test_int(value, 20); } { ecs_i64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_i64_t), &value); test_ok( ecs_meta_set_string(&cur, "2366700781656087864") ); test_int(value, 2366700781656087864); } ecs_fini(world); } void Cursor_set_str_to_u64(void) { ecs_world_t *world = ecs_init(); { ecs_u64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u64_t), &value); test_ok( ecs_meta_set_string(&cur, "20") ); test_uint(value, 20); } { ecs_u64_t value = 10; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_u64_t), &value); test_ok( ecs_meta_set_string(&cur, "2366700781656087864") ); test_uint(value, 2366700781656087864); } ecs_fini(world); } void Cursor_set_str_to_f32(void) { ecs_world_t *world = ecs_init(); ecs_f32_t value = 10.5; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_f32_t), &value); test_ok( ecs_meta_set_string(&cur, "20.5") ); test_flt(value, 20.5); ecs_fini(world); } void Cursor_set_str_to_f64(void) { ecs_world_t *world = ecs_init(); ecs_f64_t value = 10.5; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_f64_t), &value); test_ok( ecs_meta_set_string(&cur, "20.5") ); test_flt(value, 20.5); ecs_fini(world); } void Cursor_set_str_to_entity(void) { ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_ok( ecs_meta_set_string(&cur, "flecs.core") ); test_uint(value, EcsFlecsCore); ecs_fini(world); } void Cursor_set_str_to_invalid_bool(void) { ecs_log_set_level(-4); ecs_world_t *world = ecs_init(); ecs_bool_t value = false; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_bool_t), &value); test_fail( ecs_meta_set_string(&cur, "foo") ); test_bool(value, false); ecs_fini(world); } void Cursor_set_str_to_invalid_entity(void) { ecs_log_set_level(-4); ecs_world_t *world = ecs_init(); ecs_entity_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_fail( ecs_meta_set_string(&cur, "flops.core") ); test_uint(value, 0); ecs_fini(world); } void Cursor_struct_set_i32(void) { typedef struct { ecs_i32_t x; } 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)} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_int(value.x, 10); ecs_fini(world); } void Cursor_struct_set_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; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.x, 10); test_int(value.y, 20); ecs_fini(world); } void Cursor_struct_set_i32_i32_i32(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; ecs_i32_t z; } 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)}, {"z", ecs_id(ecs_i32_t)}, } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.x, 10); test_int(value.y, 20); test_int(value.z, 30); ecs_fini(world); } void Cursor_struct_set_bool(void) { typedef struct { ecs_bool_t x; } 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_bool_t)} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_bool(value.x, true); ecs_fini(world); } void Cursor_struct_set_bool_bool(void) { typedef struct { ecs_bool_t x; ecs_bool_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_bool_t)}, {"y", ecs_id(ecs_bool_t)} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, false) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.x, true); test_bool(value.y, false); cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, false) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.x, false); test_bool(value.y, true); ecs_fini(world); } void Cursor_struct_set_bool_bool_bool(void) { typedef struct { ecs_bool_t x; ecs_bool_t y; ecs_bool_t z; } 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_bool_t)}, {"y", ecs_id(ecs_bool_t)}, {"z", ecs_id(ecs_bool_t)} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, false) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.x, true); test_bool(value.y, false); test_bool(value.z, true); ecs_fini(world); } void Cursor_struct_set_bool_bool_i32_bool(void) { typedef struct { ecs_bool_t x; ecs_bool_t y; ecs_i32_t z; ecs_bool_t w; } 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_bool_t)}, {"y", ecs_id(ecs_bool_t)}, {"z", ecs_id(ecs_i32_t)}, {"w", ecs_id(ecs_bool_t)}, } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, false) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.x, true); test_bool(value.y, false); test_int(value.z, 10); test_bool(value.w, true); ecs_fini(world); } void Cursor_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)} } }); test_assert(n1 != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.n_1.x, 10); ecs_fini(world); } void Cursor_struct_2_nested_1_i32_2_i32(void) { typedef struct { ecs_i32_t x; } 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)} } }); test_assert(n1 != 0); 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} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.n_1.x, 10); test_int(value.n_2.x, 20); ecs_fini(world); } void Cursor_struct_2_nested_1_i32_i32_2_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)} } }); test_assert(n1 != 0); 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} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); 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 Cursor_struct_2_nested_1_i32_i32_2_i32_i32_w_padding_members(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N1; typedef struct { bool p1; N1 n_1; bool p2; N1 n_2; bool p3; } 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)} } }); test_assert(n1 != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"p1", ecs_id(ecs_bool_t)}, {"n_1", n1}, {"p2", ecs_id(ecs_bool_t)}, {"n_2", n1}, {"p3", ecs_id(ecs_bool_t)}, } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.p1, true); test_bool(value.p2, true); test_bool(value.p3, true); 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 Cursor_struct_set_array_i32_3(void) { typedef struct { ecs_i32_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_i32_t), 3} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.x[0], 10); test_int(value.x[1], 20); test_int(value.x[2], 30); ecs_fini(world); } void Cursor_struct_set_2_array_i32_3(void) { typedef struct { ecs_i32_t x[3]; ecs_i32_t y[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_i32_t), 3}, {"y", ecs_id(ecs_i32_t), 3} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 50) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 60) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.x[0], 10); test_int(value.x[1], 20); test_int(value.x[2], 30); test_int(value.y[0], 40); test_int(value.y[1], 50); test_int(value.y[2], 60); ecs_fini(world); } void Cursor_struct_set_2_array_i32_3_w_padding_members(void) { typedef struct { ecs_bool_t p1; ecs_i32_t x[3]; ecs_bool_t p2; ecs_i32_t y[3]; ecs_bool_t p3; } 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 = { {"p1", ecs_id(ecs_bool_t)}, {"x", ecs_id(ecs_i32_t), 3}, {"p2", ecs_id(ecs_bool_t)}, {"y", ecs_id(ecs_i32_t), 3}, {"p3", ecs_id(ecs_bool_t)} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 50) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 60) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_bool(&cur, true) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.p1, true); test_bool(value.p2, true); test_bool(value.p3, true); test_int(value.x[0], 10); test_int(value.x[1], 20); test_int(value.x[2], 30); test_int(value.y[0], 40); test_int(value.y[1], 50); test_int(value.y[2], 60); ecs_fini(world); } void Cursor_struct_set_array_w_struct_i32(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} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); 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 Cursor_struct_set_2_array_w_struct_i32(void) { typedef struct { ecs_i32_t x; } N1; typedef struct { N1 n_1[3]; N1 n_2[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}, {"n_2", n1, 3} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 50) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 60) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.n_1[0].x, 10); test_int(value.n_1[1].x, 20); test_int(value.n_1[2].x, 30); test_int(value.n_2[0].x, 40); test_int(value.n_2[1].x, 50); test_int(value.n_2[2].x, 60); ecs_fini(world); } void Cursor_struct_set_array_w_struct_w_array_i32(void) { typedef struct { ecs_i32_t x[3]; } 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), 3} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1, 3} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 11) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 12) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 21) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 22) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 31) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 32) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.n_1[0].x[0], 10); test_int(value.n_1[0].x[1], 11); test_int(value.n_1[0].x[2], 12); test_int(value.n_1[1].x[0], 20); test_int(value.n_1[1].x[1], 21); test_int(value.n_1[1].x[2], 22); test_int(value.n_1[2].x[0], 30); test_int(value.n_1[2].x[1], 31); test_int(value.n_1[2].x[2], 32); ecs_fini(world); } void Cursor_struct_set_2_array_w_struct_w_array_i32(void) { typedef struct { ecs_i32_t x[3]; } N1; typedef struct { N1 n_1[3]; N1 n_2[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), 3} } }); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", n1, 3}, {"n_2", n1, 3} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 11) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 12) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 21) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 22) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 31) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 32) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 41) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 42) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 50) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 51) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 52) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 60) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 61) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 62) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.n_1[0].x[0], 10); test_int(value.n_1[0].x[1], 11); test_int(value.n_1[0].x[2], 12); test_int(value.n_1[1].x[0], 20); test_int(value.n_1[1].x[1], 21); test_int(value.n_1[1].x[2], 22); test_int(value.n_1[2].x[0], 30); test_int(value.n_1[2].x[1], 31); test_int(value.n_1[2].x[2], 32); test_int(value.n_2[0].x[0], 40); test_int(value.n_2[0].x[1], 41); test_int(value.n_2[0].x[2], 42); test_int(value.n_2[1].x[0], 50); test_int(value.n_2[1].x[1], 51); test_int(value.n_2[1].x[2], 52); test_int(value.n_2[2].x[0], 60); test_int(value.n_2[2].x[1], 61); test_int(value.n_2[2].x[2], 62); ecs_fini(world); } void Cursor_struct_member_i32(void) { typedef struct { ecs_i32_t x; } 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)} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_bool(value.x, 10); ecs_fini(world); } void Cursor_struct_member_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; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_bool(value.x, 10); test_bool(value.y, 20); ecs_fini(world); } void Cursor_struct_member_i32_i32_reverse(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; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_bool(value.x, 10); test_bool(value.y, 20); ecs_fini(world); } void Cursor_struct_member_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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "n_1")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 10); test_bool(value.n_1.y, 20); ecs_fini(world); } void Cursor_struct_member_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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "n_1")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_member(&cur, "n_2")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 10); test_bool(value.n_1.y, 20); test_bool(value.n_2.x, 30); test_bool(value.n_2.y, 40); ecs_fini(world); } void Cursor_struct_member_2_nested_i32_i32_reverse(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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "n_2")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_member(&cur, "n_1")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 10); test_bool(value.n_1.y, 20); test_bool(value.n_2.x, 30); test_bool(value.n_2.y, 40); ecs_fini(world); } void Cursor_struct_dotmember(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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_dotmember(&cur, "n_1.y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_dotmember(&cur, "n_1.x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_dotmember(&cur, "n_2.y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_dotmember(&cur, "n_2.x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 10); test_bool(value.n_1.y, 20); test_bool(value.n_2.x, 30); test_bool(value.n_2.y, 40); ecs_fini(world); } void Cursor_struct_dotmember_assign_twice(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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_dotmember(&cur, "n_1.y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_set_int(&cur, 25) ); test_ok( ecs_meta_dotmember(&cur, "n_1.x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_set_int(&cur, 15) ); test_ok( ecs_meta_dotmember(&cur, "n_2.y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_set_int(&cur, 45) ); test_ok( ecs_meta_dotmember(&cur, "n_2.x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_set_int(&cur, 35) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 15); test_bool(value.n_1.y, 25); test_bool(value.n_2.x, 35); test_bool(value.n_2.y, 45); ecs_fini(world); } void Cursor_struct_member_after_dotmember(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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_dotmember(&cur, "n_2.y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_dotmember(&cur, "n_2.x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_member(&cur, "n_1")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 10); test_bool(value.n_1.y, 20); test_bool(value.n_2.x, 30); test_bool(value.n_2.y, 40); ecs_fini(world); } void Cursor_struct_next_after_dotmember(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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_dotmember(&cur, "n_2.y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_dotmember(&cur, "n_2.x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_member(&cur, "n_1")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_member(&cur, "x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.x, 10); test_bool(value.n_1.y, 20); test_bool(value.n_2.x, 30); test_bool(value.n_2.y, 40); ecs_fini(world); } void Cursor_struct_pop_after_dotmember(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N2; typedef struct { N2 n_1; N2 n_2; } N1; typedef struct { N1 n_1; N1 n_2; } T; ecs_world_t *world = ecs_init(); ecs_entity_t n2 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N2"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); ecs_entity_t n1 = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N1"}), .members = { {"n_1", n2}, {"n_2", n2} } }); 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}}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_member(&cur, "n_2")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_dotmember(&cur, "n_2.y")); test_ok( ecs_meta_set_int(&cur, 80) ); test_ok( ecs_meta_dotmember(&cur, "n_2.x")); test_ok( ecs_meta_set_int(&cur, 70) ); test_ok( ecs_meta_dotmember(&cur, "n_1.y")); test_ok( ecs_meta_set_int(&cur, 60) ); test_ok( ecs_meta_dotmember(&cur, "n_1.x")); test_ok( ecs_meta_set_int(&cur, 50) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_member(&cur, "n_1")); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_dotmember(&cur, "n_2.y")); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_dotmember(&cur, "n_2.x")); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_dotmember(&cur, "n_1.y")); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_dotmember(&cur, "n_1.x")); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_bool(value.n_1.n_1.x, 10); test_bool(value.n_1.n_1.y, 20); test_bool(value.n_1.n_2.x, 30); test_bool(value.n_1.n_2.y, 40); test_bool(value.n_2.n_1.x, 50); test_bool(value.n_2.n_1.y, 60); test_bool(value.n_2.n_2.x, 70); test_bool(value.n_2.n_2.y, 80); ecs_fini(world); } void Cursor_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 }}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_int(value.n_1[0], 10); test_int(value.n_1[1], 20); ecs_fini(world); } void Cursor_struct_w_array_type_struct(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N1; typedef N1 A1[2]; typedef struct { A1 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)} } }); test_assert(n1 != 0); ecs_entity_t a1 = ecs_array_init(world, &(ecs_array_desc_t){ .entity = ecs_entity(world, {.name = "A1"}), .type = n1, .count = 2 }); test_assert(a1 != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", a1} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); 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); ecs_fini(world); } void Cursor_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 }}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); 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 Cursor_struct_w_2_array_type_struct(void) { typedef struct { ecs_i32_t x; ecs_i32_t y; } N1; typedef N1 A1[2]; typedef struct { A1 n_1; A1 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)} } }); test_assert(n1 != 0); ecs_entity_t a1 = ecs_array_init(world, &(ecs_array_desc_t){ .entity = ecs_entity(world, {.name = "A1"}), .type = n1, .count = 2 }); test_assert(a1 != 0); ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"n_1", a1}, {"n_2", a1} } }); test_assert(t != 0); T value; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 20) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 30) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 40) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 50) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 60) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 70) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_set_int(&cur, 80) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); test_ok( ecs_meta_pop(&cur) ); 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_2[0].x, 50); test_int(value.n_2[0].y, 60); test_int(value.n_2[1].x, 70); test_int(value.n_2[1].y, 80); ecs_fini(world); } void Cursor_array_i32_3(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t a[3]; } T; ecs_entity_t t = ecs_array_init(world, &(ecs_array_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .type = ecs_id(ecs_i32_t), .count = 3 }); T value = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(value.a[0], 10); test_int(value.a[1], 20); test_int(value.a[2], 30); test_int(0, ecs_meta_pop(&cur)); ecs_fini(world); } void Cursor_array_struct_3(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t x, y; } N; typedef struct { N a[2]; } T; ecs_entity_t n = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N"}), .members = { {"x", ecs_id(ecs_i32_t)}, {"y", ecs_id(ecs_i32_t)} } }); ecs_entity_t t = ecs_array_init(world, &(ecs_array_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .type = n, .count = 2 }); T value = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(value.a[0].x, 10); test_int(value.a[0].y, 20); test_int(value.a[1].x, 30); test_int(value.a[1].y, 40); ecs_fini(world); } void Cursor_array_move_primitive(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t a[3]; } T; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"a", ecs_id(ecs_i32_t), 3} } }); T value = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_elem(&cur, 2)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(value.a[0], 0); test_int(value.a[1], 0); test_int(value.a[2], 10); test_int(0, ecs_meta_elem(&cur, 0)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(value.a[0], 20); test_int(value.a[1], 0); test_int(value.a[2], 10); test_int(0, ecs_meta_elem(&cur, 1)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(value.a[0], 20); test_int(value.a[1], 30); test_int(value.a[2], 10); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); ecs_fini(world); } void Cursor_array_move_struct(void) { ecs_world_t *world = ecs_init(); typedef struct { ecs_i32_t x; ecs_i32_t y; } N; typedef struct { N a[3]; } T; ecs_entity_t n = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "N"}), .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 = { {"a", n, 3} } }); T value = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_elem(&cur, 2)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(value.a[0].x, 0); test_int(value.a[0].y, 0); test_int(value.a[1].x, 0); test_int(value.a[1].y, 0); test_int(value.a[2].x, 10); test_int(value.a[2].y, 20); test_int(0, ecs_meta_elem(&cur, 0)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(value.a[0].x, 30); test_int(value.a[0].y, 40); test_int(value.a[1].x, 0); test_int(value.a[1].y, 0); test_int(value.a[2].x, 10); test_int(value.a[2].y, 20); test_int(0, ecs_meta_elem(&cur, 1)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(value.a[0].x, 30); test_int(value.a[0].y, 40); test_int(value.a[1].x, 50); test_int(value.a[1].y, 60); test_int(value.a[2].x, 10); test_int(value.a[2].y, 20); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); ecs_fini(world); } void Cursor_array_move_out_of_range(void) { ecs_world_t *world = ecs_init(); typedef struct { int32_t a[3]; } T; ecs_entity_t t = ecs_struct_init(world, &(ecs_struct_desc_t){ .entity = ecs_entity(world, {.name = "T"}), .members = { {"a", ecs_id(ecs_i32_t), 3} } }); T value = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_push(&cur)); test_assert(0 == ecs_meta_elem(&cur, 0)); /* Sanity check */ test_assert(0 == ecs_meta_elem(&cur, 2)); /* Sanity check */ ecs_log_set_level(-4); test_assert(0 != ecs_meta_elem(&cur, -1)); test_assert(0 != ecs_meta_elem(&cur, 3)); ecs_log_set_level(-1); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); ecs_fini(world); } typedef const char* const_string_t; #define OpaqueType(t)\ typedef struct { \ t value; \ } Opaque_##t; \ \ static void t##_set(void *ptr, t value) { \ ((Opaque_##t*)ptr)->value = value; \ } OpaqueType(bool) OpaqueType(char) OpaqueType(int64_t) OpaqueType(uint64_t) OpaqueType(double) OpaqueType(const_string_t) typedef struct { ecs_entity_t value; } Opaque_entity; static void Opaque_entity_set(void *ptr, ecs_world_t *world, ecs_entity_t value) { ((Opaque_entity*)ptr)->value = value; } void Cursor_opaque_set_bool(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_bool); ecs_opaque(world, { .entity = ecs_id(Opaque_bool), .type.as_type = ecs_id(ecs_bool_t), .type.assign_bool = bool_set }); Opaque_bool v = { false }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_bool), &v); test_int(0, ecs_meta_set_bool(&cur, true)); test_bool(v.value, true); test_int(0, ecs_meta_set_bool(&cur, false)); test_bool(v.value, false); ecs_fini(world); } void Cursor_opaque_set_char(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_char); ecs_opaque(world, { .entity = ecs_id(Opaque_char), .type.as_type = ecs_id(ecs_char_t), .type.assign_char = char_set }); Opaque_char v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_char), &v); test_int(0, ecs_meta_set_char(&cur, 'a')); test_int(v.value, 'a'); test_int(0, ecs_meta_set_char(&cur, 'A')); test_int(v.value, 'A'); ecs_fini(world); } void Cursor_opaque_set_int(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_int64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_int64_t), .type.as_type = ecs_id(ecs_i64_t), .type.assign_int = int64_t_set }); Opaque_int64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_int64_t), &v); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_int(&cur, -10)); test_int(v.value, -10); ecs_fini(world); } void Cursor_opaque_set_uint(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_uint64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_uint64_t), .type.as_type = ecs_id(ecs_i64_t), .type.assign_uint = uint64_t_set }); Opaque_uint64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_uint64_t), &v); test_int(0, ecs_meta_set_uint(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_uint(&cur, 20)); test_int(v.value, 20); ecs_fini(world); } void Cursor_opaque_set_float(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_double); ecs_opaque(world, { .entity = ecs_id(Opaque_double), .type.as_type = ecs_id(ecs_f64_t), .type.assign_float = double_set }); Opaque_double v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_double), &v); test_int(0, ecs_meta_set_float(&cur, 10.5)); test_flt(v.value, 10.5); test_int(0, ecs_meta_set_float(&cur, 20.5)); test_flt(v.value, 20.5); ecs_fini(world); } void Cursor_opaque_set_string(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_const_string_t); ecs_opaque(world, { .entity = ecs_id(Opaque_const_string_t), .type.as_type = ecs_id(ecs_string_t), .type.assign_string = const_string_t_set }); Opaque_const_string_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_const_string_t), &v); test_int(0, ecs_meta_set_string(&cur, "Hello World")); test_str(v.value, "Hello World"); ecs_fini(world); } void Cursor_opaque_set_entity(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_entity); ecs_opaque(world, { .entity = ecs_id(Opaque_entity), .type.as_type = ecs_id(ecs_entity_t), .type.assign_entity = Opaque_entity_set }); Opaque_entity v = { 0 }; ecs_entity_t e1 = ecs_new_id(world); ecs_entity_t e2 = ecs_new_id(world); ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_entity), &v); test_int(0, ecs_meta_set_entity(&cur, e1)); test_uint(v.value, e1); test_int(0, ecs_meta_set_entity(&cur, e2)); test_uint(v.value, e2); ecs_fini(world); } typedef struct { size_t count; int32_t *array; } IntVec; static size_t IntVec_count(const void *ptr) { const IntVec *data = ptr; return data->count; } static void* IntVec_ensure(void *ptr, size_t index) { IntVec *data = ptr; if (data->count <= index) { data->count = index + 1; data->array = ecs_os_realloc_n(data->array, int32_t, data->count); } return &data->array[index]; } static void IntVec_resize(void *ptr, size_t size) { IntVec *data = ptr; if (data->count != size) { data->count = size; if (!data->count) { ecs_os_free(data->array); data->array = NULL; } else { data->array = ecs_os_realloc_n(data->array, int32_t, size); } } } void Cursor_opaque_set_int_vec(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t) }), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); IntVec v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 3); test_int(v.array[0], 10); test_int(v.array[1], 20); test_int(v.array[2], 30); ecs_os_free(v.array); ecs_fini(world); } void Cursor_opaque_set_int_vec_empty(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t)} ), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); IntVec v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 0); test_assert(v.array == NULL); ecs_fini(world); } void Cursor_opaque_set_int_vec_resize_smaller(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t)} ), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); IntVec v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 3); test_int(v.array[0], 10); test_int(v.array[1], 20); test_int(v.array[2], 30); cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 2); test_int(v.array[0], 40); test_int(v.array[1], 50); ecs_os_free(v.array); ecs_fini(world); } void Cursor_opaque_set_int_vec_resize_larger(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t)} ), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); IntVec v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 3); test_int(v.array[0], 10); test_int(v.array[1], 20); test_int(v.array[2], 30); cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 70)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 4); test_int(v.array[0], 40); test_int(v.array[1], 50); test_int(v.array[2], 60); test_int(v.array[3], 70); ecs_os_free(v.array); ecs_fini(world); } void Cursor_opaque_set_int_vec_resize_empty(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t)} ), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); IntVec v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 3); test_int(v.array[0], 10); test_int(v.array[1], 20); test_int(v.array[2], 30); cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 0); test_assert(v.array == NULL); ecs_fini(world); } typedef struct { int32_t value; } Int; typedef struct { size_t count; Int *array; } BoxedIntVec; static void Int_assign_int(void *ptr, int64_t value) { Int *data = ptr; data->value = value; } static size_t BoxedIntVec_count(const void *ptr) { const BoxedIntVec *data = ptr; return data->count; } static void* BoxedIntVec_ensure(void *ptr, size_t index) { BoxedIntVec *data = ptr; if (data->count <= index) { data->count = index + 1; data->array = ecs_os_realloc_n(data->array, Int, data->count); } return &data->array[index]; } static void BoxedIntVec_resize(void *ptr, size_t size) { BoxedIntVec *data = ptr; if (data->count != size) { data->count = size; if (!data->count) { ecs_os_free(data->array); data->array = NULL; } else { data->array = ecs_os_realloc_n(data->array, Int, size); } } } void Cursor_opaque_set_opaque_int_vec(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, BoxedIntVec); ECS_COMPONENT(world, Int); ecs_opaque(world, { .entity = ecs_id(Int), .type.as_type = ecs_id(ecs_i32_t), .type.assign_int = Int_assign_int }); ecs_opaque(world, { .entity = ecs_id(BoxedIntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(Int)} ), .type.ensure_element = BoxedIntVec_ensure, .type.count = BoxedIntVec_count, .type.resize = BoxedIntVec_resize }); BoxedIntVec v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(BoxedIntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 3); test_int(v.array[0].value, 10); test_int(v.array[1].value, 20); test_int(v.array[2].value, 30); ecs_os_free(v.array); ecs_fini(world); } typedef struct { int32_t _dummy_1; int32_t x; int32_t _dummy_2; int32_t y; } OpaqueStruct; static void* OpaqueStruct_member(void *ptr, const char *member) { OpaqueStruct *data = ptr; if (!strcmp(member, "x")) { return &data->x; } else if (!strcmp(member, "y")) { return &data->y; } else { return NULL; } } void Cursor_opaque_set_struct(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueStruct); ecs_opaque(world, { .entity = ecs_id(OpaqueStruct), .type.as_type = ecs_struct(world, { .members = { {"x", .type = ecs_id(ecs_i32_t)}, {"y", .type = ecs_id(ecs_i32_t)} } }), .type.ensure_member = OpaqueStruct_member }); OpaqueStruct v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(OpaqueStruct), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(v.x, 10); test_int(v.y, 20); cur = ecs_meta_cursor(world, ecs_id(OpaqueStruct), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(v.x, 40); test_int(v.y, 30); ecs_fini(world); } typedef struct { int32_t _dummy_1; Position start; int32_t _dummy_2; Position stop; } OpaqueNested; static void* OpaqueNested_member(void *ptr, const char *member) { OpaqueNested *data = ptr; if (!strcmp(member, "start")) { return &data->start; } else if (!strcmp(member, "stop")) { return &data->stop; } else { return NULL; } } void Cursor_opaque_set_nested_struct(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Position); ECS_COMPONENT(world, OpaqueNested); ecs_struct(world, { .entity = ecs_id(Position), .members = { {"x", .type = ecs_id(ecs_i32_t)}, {"y", .type = ecs_id(ecs_i32_t)} } }); ecs_opaque(world, { .entity = ecs_id(OpaqueNested), .type.as_type = ecs_struct(world, { .members = { {"start", .type = ecs_id(Position)}, {"stop", .type = ecs_id(Position)} } }), .type.ensure_member = OpaqueNested_member }); OpaqueNested v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(OpaqueNested), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "start")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "stop")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.start.x, 10); test_int(v.start.y, 20); test_int(v.stop.x, 30); test_int(v.stop.y, 40); cur = ecs_meta_cursor(world, ecs_id(OpaqueNested), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "stop")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "start")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 70)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 80)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.start.x, 80); test_int(v.start.y, 70); test_int(v.stop.x, 60); test_int(v.stop.y, 50); ecs_fini(world); } typedef struct { int32_t _dummy_1; OpaqueStruct start; int32_t _dummy_2; OpaqueStruct stop; } OpaqueNestedOpaque; static void* OpaqueNestedOpaque_member(void *ptr, const char *member) { OpaqueNestedOpaque *data = ptr; if (!strcmp(member, "start")) { return &data->start; } else if (!strcmp(member, "stop")) { return &data->stop; } else { return NULL; } } void Cursor_opaque_set_nested_opaque_struct(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueStruct); ECS_COMPONENT(world, OpaqueNestedOpaque); ecs_opaque(world, { .entity = ecs_id(OpaqueStruct), .type.as_type = ecs_struct(world, { .members = { {"x", .type = ecs_id(ecs_i32_t)}, {"y", .type = ecs_id(ecs_i32_t)} } }), .type.ensure_member = OpaqueStruct_member }); ecs_opaque(world, { .entity = ecs_id(OpaqueNestedOpaque), .type.as_type = ecs_struct(world, { .members = { {"start", .type = ecs_id(OpaqueStruct)}, {"stop", .type = ecs_id(OpaqueStruct)} } }), .type.ensure_member = OpaqueNestedOpaque_member }); OpaqueNestedOpaque v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(OpaqueNestedOpaque), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "start")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "stop")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.start.x, 10); test_int(v.start.y, 20); test_int(v.stop.x, 30); test_int(v.stop.y, 40); cur = ecs_meta_cursor(world, ecs_id(OpaqueNestedOpaque), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "stop")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "start")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 70)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 80)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.start.x, 80); test_int(v.start.y, 70); test_int(v.stop.x, 60); test_int(v.stop.y, 50); ecs_fini(world); } typedef struct { int32_t el_1; int32_t _dummy_1; int32_t el_2; int32_t _dummy_2; int32_t el_3; int32_t _dummy_3; } OpaqueArray; static void* OpaqueArray_ensure(void *ptr, size_t index) { OpaqueArray *data = ptr; switch(index) { case 0: return &data->el_1; case 1: return &data->el_2; case 2: return &data->el_3; default: break; } return NULL; } void Cursor_opaque_set_array(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueArray); ecs_opaque(world, { .entity = ecs_id(OpaqueArray), .type.as_type = ecs_array(world, { .type = ecs_id(ecs_i32_t), .count = 3 }), .type.ensure_element = OpaqueArray_ensure }); OpaqueArray v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(OpaqueArray), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(v.el_1, 10); test_int(v.el_2, 20); test_int(v.el_3, 30); ecs_fini(world); } void Cursor_opaque_set_array_2_of_3_elems(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueArray); ecs_opaque(world, { .entity = ecs_id(OpaqueArray), .type.as_type = ecs_array(world, { .type = ecs_id(ecs_i32_t), .count = 3 }), .type.ensure_element = OpaqueArray_ensure }); OpaqueArray v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(OpaqueArray), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(v.el_1, 10); test_int(v.el_2, 20); test_int(v.el_3, 0); ecs_fini(world); } void Cursor_opaque_set_array_empty(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueArray); ecs_opaque(world, { .entity = ecs_id(OpaqueArray), .type.as_type = ecs_array(world, { .type = ecs_id(ecs_i32_t), .count = 3 }), .type.ensure_element = OpaqueArray_ensure }); OpaqueArray v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(OpaqueArray), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.el_1, 0); test_int(v.el_2, 0); test_int(v.el_3, 0); ecs_fini(world); } void Cursor_opaque_set_uint_to_int(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_int64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_int64_t), .type.as_type = ecs_id(ecs_i64_t), .type.assign_int = int64_t_set }); Opaque_int64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_int64_t), &v); test_int(0, ecs_meta_set_uint(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_uint(&cur, 100)); test_int(v.value, 100); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_uint(&cur, (uint64_t)INT64_MAX + 1)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_float_to_int(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_int64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_int64_t), .type.as_type = ecs_id(ecs_i64_t), .type.assign_int = int64_t_set }); Opaque_int64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_int64_t), &v); test_int(0, ecs_meta_set_float(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_float(&cur, 100)); test_int(v.value, 100); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_float(&cur, (double)INT64_MAX + 10000)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_int_to_uint(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_uint64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_uint64_t), .type.as_type = ecs_id(ecs_u64_t), .type.assign_uint = uint64_t_set }); Opaque_uint64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_uint64_t), &v); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_int(&cur, 100)); test_int(v.value, 100); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_int(&cur, -1)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_float_to_uint(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_uint64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_uint64_t), .type.as_type = ecs_id(ecs_u64_t), .type.assign_uint = uint64_t_set }); Opaque_uint64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_uint64_t), &v); test_int(0, ecs_meta_set_float(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_float(&cur, 100)); test_int(v.value, 100); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_float(&cur, -1)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_int_to_float(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_double); ecs_opaque(world, { .entity = ecs_id(Opaque_double), .type.as_type = ecs_id(ecs_f64_t), .type.assign_float = double_set }); Opaque_double v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_double), &v); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_int(&cur, 100)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_uint_to_float(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_double); ecs_opaque(world, { .entity = ecs_id(Opaque_double), .type.as_type = ecs_id(ecs_f64_t), .type.assign_float = double_set }); Opaque_double v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_double), &v); test_int(0, ecs_meta_set_uint(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_uint(&cur, 100)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_string_to_char(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_char); ecs_opaque(world, { .entity = ecs_id(Opaque_char), .type.as_type = ecs_id(ecs_char_t), .type.assign_char = char_set }); Opaque_char v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_char), &v); test_int(0, ecs_meta_set_string(&cur, "a")); test_int(v.value, 'a'); test_int(0, ecs_meta_set_string(&cur, "b")); test_int(v.value, 'b'); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_string(&cur, "ab")); test_int(v.value, 'b'); ecs_fini(world); } void Cursor_opaque_set_int_to_char(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_char); ecs_opaque(world, { .entity = ecs_id(Opaque_char), .type.as_type = ecs_id(ecs_char_t), .type.assign_char = char_set }); Opaque_char v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_char), &v); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_int(&cur, 100)); test_int(v.value, 100); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_int(&cur, 1000)); test_int(v.value, 100); test_int(-1, ecs_meta_set_int(&cur, -10)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_uint_to_char(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_char); ecs_opaque(world, { .entity = ecs_id(Opaque_char), .type.as_type = ecs_id(ecs_char_t), .type.assign_char = char_set }); Opaque_char v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_char), &v); test_int(0, ecs_meta_set_uint(&cur, 10)); test_int(v.value, 10); test_int(0, ecs_meta_set_uint(&cur, 100)); test_int(v.value, 100); ecs_log_set_level(-4); test_int(-1, ecs_meta_set_uint(&cur, 1000)); test_int(v.value, 100); ecs_fini(world); } void Cursor_opaque_set_char_to_int(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_int64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_int64_t), .type.as_type = ecs_id(ecs_i64_t), .type.assign_int = int64_t_set }); Opaque_int64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_int64_t), &v); test_int(0, ecs_meta_set_char(&cur, 'a')); test_int(v.value, 'a'); test_int(0, ecs_meta_set_char(&cur, 'b')); test_int(v.value, 'b'); ecs_fini(world); } void Cursor_opaque_set_char_to_uint(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_uint64_t); ecs_opaque(world, { .entity = ecs_id(Opaque_uint64_t), .type.as_type = ecs_id(ecs_u64_t), .type.assign_uint = uint64_t_set }); Opaque_uint64_t v = { 0 }; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_uint64_t), &v); test_int(0, ecs_meta_set_char(&cur, 'a')); test_int(v.value, 'a'); test_int(0, ecs_meta_set_char(&cur, 'b')); test_int(v.value, 'b'); ecs_fini(world); } typedef struct { OpaqueStruct foo; OpaqueStruct bar; } Struct_w_OpaqueStruct; void Cursor_struct_w_2_opaque_structs(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueStruct); ECS_COMPONENT(world, Struct_w_OpaqueStruct); ecs_opaque(world, { .entity = ecs_id(OpaqueStruct), .type.as_type = ecs_struct(world, { .members = { {"x", .type = ecs_id(ecs_i32_t)}, {"y", .type = ecs_id(ecs_i32_t)} } }), .type.ensure_member = OpaqueStruct_member }); ecs_struct(world, { .entity = ecs_id(Struct_w_OpaqueStruct), .members = { {"foo", ecs_id(OpaqueStruct)}, {"bar", ecs_id(OpaqueStruct)}, } }); Struct_w_OpaqueStruct v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_OpaqueStruct), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.x, 10); test_int(v.foo.y, 20); test_int(v.bar.x, 30); test_int(v.bar.y, 40); ecs_fini(world); } typedef struct { IntVec foo; IntVec bar; } Struct_w_IntVec; void Cursor_struct_w_2_opaque_vectors(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ECS_COMPONENT(world, Struct_w_IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t) }), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); ecs_struct(world, { .entity = ecs_id(Struct_w_IntVec), .members = { {"foo", ecs_id(IntVec)}, {"bar", ecs_id(IntVec)}, } }); Struct_w_IntVec v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.count, 3); test_int(v.foo.array[0], 10); test_int(v.foo.array[1], 20); test_int(v.foo.array[2], 30); test_int(v.bar.count, 3); test_int(v.bar.array[0], 40); test_int(v.bar.array[1], 50); test_int(v.bar.array[2], 60); ecs_os_free(v.foo.array); ecs_os_free(v.bar.array); ecs_fini(world); } typedef struct { OpaqueArray foo; OpaqueArray bar; } Struct_w_OpaqueArray; void Cursor_struct_w_2_opaque_arrays(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueArray); ECS_COMPONENT(world, Struct_w_OpaqueArray); ecs_opaque(world, { .entity = ecs_id(OpaqueArray), .type.as_type = ecs_array(world, { .type = ecs_id(ecs_i32_t), .count = 3 }), .type.ensure_element = OpaqueArray_ensure }); ecs_struct(world, { .entity = ecs_id(Struct_w_OpaqueArray), .members = { {"foo", ecs_id(OpaqueArray)}, {"bar", ecs_id(OpaqueArray)}, } }); Struct_w_OpaqueArray v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_OpaqueArray), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.el_1, 10); test_int(v.foo.el_2, 20); test_int(v.foo.el_3, 30); test_int(v.bar.el_1, 40); test_int(v.bar.el_2, 50); test_int(v.bar.el_3, 60); ecs_fini(world); } typedef struct { OpaqueStruct foo; OpaqueStruct bar; OpaqueStruct zoo; } Struct_w_3_OpaqueStructs; void Cursor_struct_w_3_opaque_structs(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueStruct); ECS_COMPONENT(world, Struct_w_3_OpaqueStructs); ecs_opaque(world, { .entity = ecs_id(OpaqueStruct), .type.as_type = ecs_struct(world, { .members = { {"x", .type = ecs_id(ecs_i32_t)}, {"y", .type = ecs_id(ecs_i32_t)} } }), .type.ensure_member = OpaqueStruct_member }); ecs_struct(world, { .entity = ecs_id(Struct_w_3_OpaqueStructs), .members = { {"foo", ecs_id(OpaqueStruct)}, {"bar", ecs_id(OpaqueStruct)}, {"zoo", ecs_id(OpaqueStruct)}, } }); Struct_w_3_OpaqueStructs v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_3_OpaqueStructs), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "zoo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.x, 10); test_int(v.foo.y, 20); test_int(v.bar.x, 30); test_int(v.bar.y, 40); test_int(v.zoo.x, 50); test_int(v.zoo.y, 60); ecs_fini(world); } typedef struct { IntVec foo; IntVec bar; IntVec zoo; } Struct_w_3_IntVecs; void Cursor_struct_w_3_opaque_vectors(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ECS_COMPONENT(world, Struct_w_3_IntVecs); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t) }), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); ecs_struct(world, { .entity = ecs_id(Struct_w_3_IntVecs), .members = { {"foo", ecs_id(IntVec)}, {"bar", ecs_id(IntVec)}, {"zoo", ecs_id(IntVec)}, } }); Struct_w_3_IntVecs v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_3_IntVecs), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "zoo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 70)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 80)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 90)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.count, 3); test_int(v.foo.array[0], 10); test_int(v.foo.array[1], 20); test_int(v.foo.array[2], 30); test_int(v.bar.count, 3); test_int(v.bar.array[0], 40); test_int(v.bar.array[1], 50); test_int(v.bar.array[2], 60); test_int(v.zoo.count, 3); test_int(v.zoo.array[0], 70); test_int(v.zoo.array[1], 80); test_int(v.zoo.array[2], 90); ecs_os_free(v.foo.array); ecs_os_free(v.bar.array); ecs_os_free(v.zoo.array); ecs_fini(world); } typedef struct { OpaqueArray foo; OpaqueArray bar; OpaqueArray zoo; } Struct_w_3_OpaqueArrays; void Cursor_struct_w_3_opaque_arrays(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, OpaqueArray); ECS_COMPONENT(world, Struct_w_3_OpaqueArrays); ecs_opaque(world, { .entity = ecs_id(OpaqueArray), .type.as_type = ecs_array(world, { .type = ecs_id(ecs_i32_t), .count = 3 }), .type.ensure_element = OpaqueArray_ensure }); ecs_struct(world, { .entity = ecs_id(Struct_w_3_OpaqueArrays), .members = { {"foo", ecs_id(OpaqueArray)}, {"bar", ecs_id(OpaqueArray)}, {"zoo", ecs_id(OpaqueArray)}, } }); Struct_w_3_OpaqueArrays v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_3_OpaqueArrays), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "zoo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 70)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 80)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 90)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.el_1, 10); test_int(v.foo.el_2, 20); test_int(v.foo.el_3, 30); test_int(v.bar.el_1, 40); test_int(v.bar.el_2, 50); test_int(v.bar.el_3, 60); test_int(v.zoo.el_1, 70); test_int(v.zoo.el_2, 80); test_int(v.zoo.el_3, 90); ecs_fini(world); } static void* OpaqueStructIntVec_member(void *ptr, const char *member) { Struct_w_IntVec *data = ptr; if (!strcmp(member, "foo")) { return &data->foo; } else if (!strcmp(member, "bar")) { return &data->bar; } else { return NULL; } } void Cursor_opaque_struct_w_opaque_vec(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ECS_COMPONENT(world, Struct_w_IntVec); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t) }), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); ecs_entity_t os = ecs_struct(world, { .members = { {"foo", ecs_id(IntVec)}, {"bar", ecs_id(IntVec)}, } }); ecs_opaque(world, { .entity = ecs_id(Struct_w_IntVec), .type.as_type = os, .type.ensure_member = OpaqueStructIntVec_member, }); Struct_w_IntVec v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Struct_w_IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "foo")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_member(&cur, "bar")); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_set_int(&cur, 40)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.count, 3); test_int(v.foo.array[0], 10); test_int(v.foo.array[1], 20); test_int(v.foo.array[2], 30); test_int(v.bar.array[0], 40); test_int(v.bar.array[1], 50); test_int(v.bar.array[2], 60); ecs_os_free(v.foo.array); ecs_os_free(v.bar.array); ecs_fini(world); } static void* OpaqueStructElem_member(void *ptr, const char *member) { if (!strcmp(member, "i")) { return ptr; } else { return NULL; } } void Cursor_opaque_vec_w_opaque_elem(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, IntVec); ECS_COMPONENT(world, Struct_w_IntVec); ecs_entity_t os = ecs_struct(world, { .members = { {"i", ecs_id(ecs_i32_t)} } }); ecs_entity_t oelem = ecs_opaque(world, { .entity = ecs_component(world, { .type.size = ECS_SIZEOF(ecs_i32_t), .type.alignment = ECS_ALIGNOF(ecs_i32_t) }), .type.as_type = os, .type.ensure_member = OpaqueStructElem_member, }); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = oelem }), .type.ensure_element = IntVec_ensure, .type.count = IntVec_count, .type.resize = IntVec_resize }); IntVec v = {0}; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(IntVec), &v); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "i")); test_int(0, ecs_meta_set_int(&cur, 10)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "i")); test_int(0, ecs_meta_set_int(&cur, 20)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_push(&cur)); test_int(0, ecs_meta_member(&cur, "i")); test_int(0, ecs_meta_set_int(&cur, 30)); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); test_int(v.count, 3); test_int(v.array[0], 10); test_int(v.array[1], 20); test_int(v.array[2], 30); ecs_os_free(v.array); ecs_fini(world); } void Cursor_next_out_of_bounds(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; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_next(&cur) ); ecs_log_set_level(-4); test_fail( ecs_meta_next(&cur) ); ecs_fini(world); } void Cursor_set_out_of_bounds(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; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_next(&cur) ); test_ok( ecs_meta_next(&cur) ); ecs_log_set_level(-4); test_fail(ecs_meta_set_int(&cur, 10)); ecs_fini(world); } void Cursor_get_member_id(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; ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_push(&cur) ); test_assert(ecs_meta_get_member_id(&cur) != 0); test_assert(ecs_meta_get_member_id(&cur) == ecs_lookup_fullpath(world, "T.x")); test_ok( ecs_meta_next(&cur) ); test_assert(ecs_meta_get_member_id(&cur) != 0); test_assert(ecs_meta_get_member_id(&cur) == ecs_lookup_fullpath(world, "T.y")); test_ok( ecs_meta_pop(&cur) ); ecs_fini(world); }