From 8f5d227a505e6ea709fbb630dcd73afe6c6b738c Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Wed, 16 Oct 2024 15:41:10 +0200 Subject: [PATCH 01/11] add primitive callbacks and cpp methods --- .../flecs/addons/cpp/mixins/meta/opaque.hpp | 50 +++++++++++++++++++ include/flecs/addons/meta.h | 27 ++++++++++ 2 files changed, 77 insertions(+) diff --git a/include/flecs/addons/cpp/mixins/meta/opaque.hpp b/include/flecs/addons/cpp/mixins/meta/opaque.hpp index d1f23803cf..c62c736eb8 100644 --- a/include/flecs/addons/cpp/mixins/meta/opaque.hpp +++ b/include/flecs/addons/cpp/mixins/meta/opaque.hpp @@ -166,6 +166,56 @@ struct opaque { return *this; } + /* Getter interface */ + + /** Get bool value */ + opaque& get_bool(bool (*func)(const T *src)) { + this->desc.type.get_bool = + reinterpret_castdesc.type.get_bool)>(func); + return *this; + } + + /** Get char value */ + opaque& get_char(char (*func)(const T *src)) { + this->desc.type.get_char = + reinterpret_castdesc.type.get_char)>(func); + return *this; + } + + /** Get int value */ + opaque& get_int(int64_t (*func)(const T *src)) { + this->desc.type.get_int = + reinterpret_castdesc.type.get_int)>(func); + return *this; + } + + /** Get unsigned int value */ + opaque& get_uint(uint64_t (*func)(const T *src)) { + this->desc.type.get_uint = + reinterpret_castdesc.type.get_uint)>(func); + return *this; + } + + /** Get float value */ + opaque& get_float(double (*func)(const T *src)) { + this->desc.type.get_float = + reinterpret_castdesc.type.get_float)>(func); + return *this; + } + + /** Get string value */ + opaque& get_string(const char* (*func)(const T *src)) { + this->desc.type.get_string = + reinterpret_castdesc.type.get_string)>(func); + return *this; + } + ~opaque() { if (world) { ecs_opaque_init(world, &desc); diff --git a/include/flecs/addons/meta.h b/include/flecs/addons/meta.h index 4981269215..ebea53f03e 100644 --- a/include/flecs/addons/meta.h +++ b/include/flecs/addons/meta.h @@ -457,6 +457,33 @@ typedef struct EcsOpaque { void (*resize)( void *dst, size_t count); + + /* Getter interface */ + + /** Get bool value */ + bool (*get_bool)( + const void *src); + + /** Get char value */ + char (*get_char)( + const void *src); + + /** Get int value */ + int64_t (*get_int)( + const void *src); + + /** Get unsigned int value */ + uint64_t (*get_uint)( + const void *src); + + /** Get float value */ + double (*get_float)( + const void *src); + + /** Get string value */ + const char* (*get_string)( + const void *src); + } EcsOpaque; From 39c96a72548cb2967de7ffb8bc3b88a667740f4b Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Wed, 16 Oct 2024 19:02:49 +0200 Subject: [PATCH 02/11] added entity/id and modified ecs_get_* --- .../flecs/addons/cpp/mixins/meta/opaque.hpp | 24 ++++ include/flecs/addons/meta.h | 14 +++ src/addons/meta/cursor.c | 118 +++++++++++------- src/addons/meta/definitions.c | 9 +- test/meta/src/Cursor.c | 8 +- 5 files changed, 120 insertions(+), 53 deletions(-) diff --git a/include/flecs/addons/cpp/mixins/meta/opaque.hpp b/include/flecs/addons/cpp/mixins/meta/opaque.hpp index c62c736eb8..f8a4ec3f56 100644 --- a/include/flecs/addons/cpp/mixins/meta/opaque.hpp +++ b/include/flecs/addons/cpp/mixins/meta/opaque.hpp @@ -216,6 +216,30 @@ struct opaque { return *this; } + /** Get entity value */ + opaque& get_entity(ecs_entity_t (*func)(const T *src, const flecs::world_t *world)) { + this->desc.type.get_entity = + reinterpret_castdesc.type.get_entity)>(func); + return *this; + } + + /** Get (component) id value */ + opaque& get_id(ecs_id_t (*func)(const T *src, const flecs::world_t *world)) { + this->desc.type.get_id = + reinterpret_castdesc.type.get_id)>(func); + return *this; + } + + /** Check if value is null */ + opaque& is_null(bool (*func)(const T *src)) { + this->desc.type.is_null = + reinterpret_castdesc.type.is_null)>(func); + return *this; + } + ~opaque() { if (world) { ecs_opaque_init(world, &desc); diff --git a/include/flecs/addons/meta.h b/include/flecs/addons/meta.h index ebea53f03e..4f81aed550 100644 --- a/include/flecs/addons/meta.h +++ b/include/flecs/addons/meta.h @@ -484,6 +484,20 @@ typedef struct EcsOpaque { const char* (*get_string)( const void *src); + /** Get entity value */ + ecs_entity_t (*get_entity)( + const void *src, + const ecs_world_t *world); + + /** Get (component) id value */ + ecs_id_t (*get_id)( + const void *src, + const ecs_world_t *world); + + /** Check if value is null */ + bool (*is_null)( + const void *src); + } EcsOpaque; diff --git a/src/addons/meta/cursor.c b/src/addons/meta/cursor.c index 069300f51e..5bfaaae255 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -1798,9 +1798,18 @@ bool ecs_meta_get_bool( case EcsOpBitmask: return *(ecs_u32_t*)ptr != 0; case EcsOpEntity: return *(ecs_entity_t*)ptr != 0; case EcsOpId: return *(ecs_id_t*)ptr != 0; + case EcsOpOpaque: { + /* If opaque type knows how to convert to bool, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_bool) { + return opaque->get_bool(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -1825,9 +1834,18 @@ char ecs_meta_get_char( switch(op->kind) { case EcsOpChar: return *(ecs_char_t*)ptr != 0; + case EcsOpOpaque: { + /* If opaque type knows how to convert to char, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_char) { + return opaque->get_char(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -1892,9 +1910,18 @@ int64_t ecs_meta_get_int( ecs_throw(ECS_INVALID_PARAMETER, "invalid conversion from id to int"); break; + case EcsOpOpaque: { + /* If opaque type knows how to convert to int, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_int) { + return opaque->get_int(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -1936,9 +1963,18 @@ uint64_t ecs_meta_get_uint( case EcsOpBitmask: return *(const ecs_u32_t*)ptr; case EcsOpEntity: return *(const ecs_entity_t*)ptr; case EcsOpId: return *(const ecs_id_t*)ptr; + case EcsOpOpaque: { + /* If opaque type knows how to convert to uint, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_uint) { + return opaque->get_uint(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -1995,7 +2031,7 @@ double flecs_meta_to_float( ecs_throw(ECS_INVALID_PARAMETER, "invalid element for float"); break; default: - ecs_throw(ECS_INVALID_PARAMETER, "invalid operation"); + break; } error: @@ -2008,30 +2044,18 @@ double ecs_meta_get_float( ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); - return flecs_meta_to_float(op->kind, ptr); -} - -/* Handler to get string from opaque (see ecs_meta_get_string below) */ -static int ecs_meta_get_string_value_from_opaque( - const struct ecs_serializer_t *ser, ecs_entity_t type, const void *value) -{ - if(type != ecs_id(ecs_string_t)) { - ecs_err("Expected value call for opaque type to be a string"); - return -1; + if(op->kind == EcsOpOpaque){ + /* If opaque type knows how to convert to float, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_float) { + return opaque->get_float(ptr); + } + ecs_throw(ECS_INVALID_PARAMETER, "invalid operation"); + error: + return 0; } - char*** ctx = (char ***) ser->ctx; - *ctx = ECS_CONST_CAST(char**, value); - return 0; -} - -/* Handler to get string from opaque (see ecs_meta_get_string below) */ -static int ecs_meta_get_string_member_from_opaque( - const struct ecs_serializer_t* ser, const char* name) -{ - (void)ser; // silence unused warning - (void)name; // silence unused warning - ecs_err("Unexpected member call when serializing string from opaque"); - return -1; + return flecs_meta_to_float(op->kind, ptr); } const char* ecs_meta_get_string( @@ -2043,21 +2067,11 @@ const char* ecs_meta_get_string( switch(op->kind) { case EcsOpString: return *(const char**)ptr; case EcsOpOpaque: { - /* If opaque type happens to map to a string, retrieve it. + /* If opaque type knows how to convert to string, retrieve it. Otherwise, fallback to default case (error). */ const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); - if(opaque && opaque->as_type == ecs_id(ecs_string_t) && opaque->serialize) { - char** str = NULL; - ecs_serializer_t ser = { - .world = cursor->world, - .value = ecs_meta_get_string_value_from_opaque, - .member = ecs_meta_get_string_member_from_opaque, - .ctx = &str - }; - opaque->serialize(&ser, ptr); - if(str && *str) - return *str; - /* invalid string, so fall through */ + if(opaque && opaque->get_string) { + return opaque->get_string(ptr); } /* Not a compatible opaque type, so fall through */ } @@ -2103,9 +2117,18 @@ ecs_entity_t ecs_meta_get_entity( void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); switch(op->kind) { case EcsOpEntity: return *(ecs_entity_t*)ptr; + case EcsOpOpaque: { + /* If opaque type knows how to convert to entity, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_entity) { + return opaque->get_entity(ptr, cursor->world); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -2145,9 +2168,18 @@ ecs_entity_t ecs_meta_get_id( switch(op->kind) { case EcsOpEntity: return *(ecs_id_t*)ptr; /* Entities are valid ids */ case EcsOpId: return *(ecs_id_t*)ptr; + case EcsOpOpaque: { + /* If opaque type knows how to convert to id, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_id) { + return opaque->get_id(ptr, cursor->world); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: diff --git a/src/addons/meta/definitions.c b/src/addons/meta/definitions.c index f22a7ef98f..7cccfc8e32 100644 --- a/src/addons/meta/definitions.c +++ b/src/addons/meta/definitions.c @@ -31,10 +31,9 @@ size_t flecs_addon_vec_count(const void *ptr) { } static -int flecs_const_str_serialize(const ecs_serializer_t *ser, const void *ptr) { - char **data = ECS_CONST_CAST(char**, ptr); - ser->value(ser, ecs_id(ecs_string_t), data); - return 0; +const char* flecs_const_get_string(const void *ptr) { + const char **data = (const char**) ptr; + return *data; } /* Initialize reflection data for core components */ @@ -76,7 +75,7 @@ void flecs_meta_import_core_definitions( }), .type = { .as_type = ecs_id(ecs_string_t), - .serialize = flecs_const_str_serialize, + .get_string = flecs_const_get_string, } }); diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index 629efc3414..df096b6c5d 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3124,10 +3124,8 @@ void Cursor_opaque_set_float(void) { } static -int const_string_t_serialize(const ecs_serializer_t *ser, const void *ptr) { - char **data = ECS_CONST_CAST(char**, ptr); - ser->value(ser, ecs_id(ecs_string_t), data); - return 0; +const char* const_string_t_get( const void *ptr) { + return *((const char**) ptr); } void Cursor_opaque_get_set_string(void) { @@ -3139,7 +3137,7 @@ void Cursor_opaque_get_set_string(void) { .entity = ecs_id(Opaque_const_string_t), .type.as_type = ecs_id(ecs_string_t), .type.assign_string = const_string_t_set, - .type.serialize = const_string_t_serialize + .type.get_string = const_string_t_get }); Opaque_const_string_t v = { 0 }; From e602c82e10b7cdb7e794f8b436cc652d08469716 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Wed, 16 Oct 2024 19:48:25 +0200 Subject: [PATCH 03/11] tests wip --- test/meta/src/Cursor.c | 47 ++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index df096b6c5d..29546cf154 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -2988,8 +2988,12 @@ typedef const char* const_string_t; \ static void t##_set(void *ptr, t value) { \ ((Opaque_##t*)ptr)->value = value; \ + } \ + static t t##_get(const void *ptr) { \ + return ((Opaque_##t*)ptr)->value; \ } + OpaqueType(bool) OpaqueType(char) OpaqueType(int64_t) @@ -3009,10 +3013,18 @@ static void Opaque_entity_set(void *ptr, ecs_world_t *world, ecs_entity_t value) ((Opaque_entity*)ptr)->value = value; } +static ecs_entity_t Opaque_entity_get(const void *ptr, const ecs_world_t *world) { + return ((Opaque_entity*)ptr)->value; +} + static void Opaque_id_set(void *ptr, ecs_world_t *world, ecs_id_t value) { ((Opaque_id*)ptr)->value = value; } +static ecs_entity_t Opaque_id_get(const void *ptr, const ecs_world_t *world) { + return ((Opaque_id*)ptr)->value; +} + void Cursor_opaque_set_bool(void) { ecs_world_t *world = ecs_init(); @@ -3021,7 +3033,8 @@ void Cursor_opaque_set_bool(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_bool), .type.as_type = ecs_id(ecs_bool_t), - .type.assign_bool = bool_set + .type.assign_bool = bool_set, + .type.get_bool = bool_get }); Opaque_bool v = { false }; @@ -3029,8 +3042,10 @@ void Cursor_opaque_set_bool(void) { 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_bool(ecs_meta_get_bool(&cur), true); test_int(0, ecs_meta_set_bool(&cur, false)); test_bool(v.value, false); + test_bool(ecs_meta_get_bool(&cur), false); ecs_fini(world); } @@ -3043,7 +3058,8 @@ void Cursor_opaque_set_char(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_char), .type.as_type = ecs_id(ecs_char_t), - .type.assign_char = char_set + .type.assign_char = char_set, + .type.get_char = char_get }); Opaque_char v = { 0 }; @@ -3051,8 +3067,10 @@ void Cursor_opaque_set_char(void) { 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(ecs_meta_get_char(&cur), 'a'); test_int(0, ecs_meta_set_char(&cur, 'A')); test_int(v.value, 'A'); + test_int(ecs_meta_get_char(&cur), 'A'); ecs_fini(world); } @@ -3065,7 +3083,8 @@ void Cursor_opaque_set_int(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_int64_t), .type.as_type = ecs_id(ecs_i64_t), - .type.assign_int = int64_t_set + .type.assign_int = int64_t_set, + .type.get_int = int64_t_get }); Opaque_int64_t v = { 0 }; @@ -3073,8 +3092,10 @@ void Cursor_opaque_set_int(void) { 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(ecs_meta_get_int(&cur), 10); test_int(0, ecs_meta_set_int(&cur, -10)); test_int(v.value, -10); + test_int(ecs_meta_get_int(&cur), -10); ecs_fini(world); } @@ -3087,7 +3108,8 @@ void Cursor_opaque_set_uint(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_uint64_t), .type.as_type = ecs_id(ecs_i64_t), - .type.assign_uint = uint64_t_set + .type.assign_uint = uint64_t_set, + .type.get_uint = uint64_t_get }); Opaque_uint64_t v = { 0 }; @@ -3095,8 +3117,10 @@ void Cursor_opaque_set_uint(void) { 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(ecs_meta_get_uint(&cur), 10); test_int(0, ecs_meta_set_uint(&cur, 20)); test_int(v.value, 20); + test_int(ecs_meta_get_uint(&cur), 20); ecs_fini(world); } @@ -3109,7 +3133,8 @@ void Cursor_opaque_set_float(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_double), .type.as_type = ecs_id(ecs_f64_t), - .type.assign_float = double_set + .type.assign_float = double_set, + .type.get_float = double_get }); Opaque_double v = { 0 }; @@ -3117,17 +3142,14 @@ void Cursor_opaque_set_float(void) { 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_flt(ecs_meta_get_float(&cur), 10.5); test_int(0, ecs_meta_set_float(&cur, 20.5)); test_flt(v.value, 20.5); + test_flt(ecs_meta_get_float(&cur), 20.5); ecs_fini(world); } -static -const char* const_string_t_get( const void *ptr) { - return *((const char**) ptr); -} - void Cursor_opaque_get_set_string(void) { ecs_world_t *world = ecs_init(); @@ -3160,7 +3182,8 @@ void Cursor_opaque_set_entity(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_entity), .type.as_type = ecs_id(ecs_entity_t), - .type.assign_entity = Opaque_entity_set + .type.assign_entity = Opaque_entity_set, + .type.get_entity = Opaque_entity_get }); Opaque_entity v = { 0 }; @@ -3170,8 +3193,10 @@ void Cursor_opaque_set_entity(void) { 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_uint(ecs_meta_get_entity(&cur), e1); test_int(0, ecs_meta_set_entity(&cur, e2)); test_uint(v.value, e2); + test_uint(ecs_meta_get_entity(&cur), e2); ecs_fini(world); } From 42c01f636a7cd78321838d2d96f401ca8922d120 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Wed, 16 Oct 2024 21:45:20 +0200 Subject: [PATCH 04/11] id tests --- distr/flecs.c | 128 +++++++++++------- distr/flecs.h | 104 ++++++++++++++ .../flecs/addons/cpp/mixins/meta/opaque.hpp | 8 -- include/flecs/addons/meta.h | 5 +- src/addons/meta/cursor.c | 2 +- src/addons/meta/definitions.c | 3 +- test/meta/src/Cursor.c | 5 +- 7 files changed, 190 insertions(+), 65 deletions(-) diff --git a/distr/flecs.c b/distr/flecs.c index 8e2b3fffbc..df019cb91d 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -50028,9 +50028,18 @@ bool ecs_meta_get_bool( case EcsOpBitmask: return *(ecs_u32_t*)ptr != 0; case EcsOpEntity: return *(ecs_entity_t*)ptr != 0; case EcsOpId: return *(ecs_id_t*)ptr != 0; + case EcsOpOpaque: { + /* If opaque type knows how to convert to bool, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_bool) { + return opaque->get_bool(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -50055,9 +50064,18 @@ char ecs_meta_get_char( switch(op->kind) { case EcsOpChar: return *(ecs_char_t*)ptr != 0; + case EcsOpOpaque: { + /* If opaque type knows how to convert to char, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_char) { + return opaque->get_char(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -50122,9 +50140,18 @@ int64_t ecs_meta_get_int( ecs_throw(ECS_INVALID_PARAMETER, "invalid conversion from id to int"); break; + case EcsOpOpaque: { + /* If opaque type knows how to convert to int, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_int) { + return opaque->get_int(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -50166,9 +50193,18 @@ uint64_t ecs_meta_get_uint( case EcsOpBitmask: return *(const ecs_u32_t*)ptr; case EcsOpEntity: return *(const ecs_entity_t*)ptr; case EcsOpId: return *(const ecs_id_t*)ptr; + case EcsOpOpaque: { + /* If opaque type knows how to convert to uint, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_uint) { + return opaque->get_uint(ptr); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -50225,7 +50261,7 @@ double flecs_meta_to_float( ecs_throw(ECS_INVALID_PARAMETER, "invalid element for float"); break; default: - ecs_throw(ECS_INVALID_PARAMETER, "invalid operation"); + break; } error: @@ -50238,30 +50274,18 @@ double ecs_meta_get_float( ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); - return flecs_meta_to_float(op->kind, ptr); -} - -/* Handler to get string from opaque (see ecs_meta_get_string below) */ -static int ecs_meta_get_string_value_from_opaque( - const struct ecs_serializer_t *ser, ecs_entity_t type, const void *value) -{ - if(type != ecs_id(ecs_string_t)) { - ecs_err("Expected value call for opaque type to be a string"); - return -1; + if(op->kind == EcsOpOpaque){ + /* If opaque type knows how to convert to float, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_float) { + return opaque->get_float(ptr); + } + ecs_throw(ECS_INVALID_PARAMETER, "invalid operation"); + error: + return 0; } - char*** ctx = (char ***) ser->ctx; - *ctx = ECS_CONST_CAST(char**, value); - return 0; -} - -/* Handler to get string from opaque (see ecs_meta_get_string below) */ -static int ecs_meta_get_string_member_from_opaque( - const struct ecs_serializer_t* ser, const char* name) -{ - (void)ser; // silence unused warning - (void)name; // silence unused warning - ecs_err("Unexpected member call when serializing string from opaque"); - return -1; + return flecs_meta_to_float(op->kind, ptr); } const char* ecs_meta_get_string( @@ -50273,21 +50297,11 @@ const char* ecs_meta_get_string( switch(op->kind) { case EcsOpString: return *(const char**)ptr; case EcsOpOpaque: { - /* If opaque type happens to map to a string, retrieve it. + /* If opaque type knows how to convert to string, retrieve it. Otherwise, fallback to default case (error). */ const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); - if(opaque && opaque->as_type == ecs_id(ecs_string_t) && opaque->serialize) { - char** str = NULL; - ecs_serializer_t ser = { - .world = cursor->world, - .value = ecs_meta_get_string_value_from_opaque, - .member = ecs_meta_get_string_member_from_opaque, - .ctx = &str - }; - opaque->serialize(&ser, ptr); - if(str && *str) - return *str; - /* invalid string, so fall through */ + if(opaque && opaque->get_string) { + return opaque->get_string(ptr); } /* Not a compatible opaque type, so fall through */ } @@ -50333,9 +50347,18 @@ ecs_entity_t ecs_meta_get_entity( void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); switch(op->kind) { case EcsOpEntity: return *(ecs_entity_t*)ptr; + case EcsOpOpaque: { + /* If opaque type knows how to convert to entity, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_entity) { + return opaque->get_entity(ptr, cursor->world); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -50366,7 +50389,7 @@ ecs_entity_t ecs_meta_get_entity( return 0; } -ecs_entity_t ecs_meta_get_id( +ecs_id_t ecs_meta_get_id( const ecs_meta_cursor_t *cursor) { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); @@ -50375,9 +50398,18 @@ ecs_entity_t ecs_meta_get_id( switch(op->kind) { case EcsOpEntity: return *(ecs_id_t*)ptr; /* Entities are valid ids */ case EcsOpId: return *(ecs_id_t*)ptr; + case EcsOpOpaque: { + /* If opaque type knows how to convert to id, retrieve it. + Otherwise, fallback to default case (error). */ + const EcsOpaque *opaque = ecs_get(cursor->world, op->type, EcsOpaque); + if(opaque && opaque->get_id) { + return opaque->get_id(ptr, cursor->world); + } + /* Not a compatible opaque type, so fall through */ + } + /* fall through */ case EcsOpArray: case EcsOpVector: - case EcsOpOpaque: case EcsOpPush: case EcsOpPop: case EcsOpScope: @@ -50449,10 +50481,8 @@ size_t flecs_addon_vec_count(const void *ptr) { } static -int flecs_const_str_serialize(const ecs_serializer_t *ser, const void *ptr) { - char **data = ECS_CONST_CAST(char**, ptr); - ser->value(ser, ecs_id(ecs_string_t), data); - return 0; +const char* flecs_const_get_string(const void *ptr) { + return *((const char *const *) ptr); } /* Initialize reflection data for core components */ @@ -50494,7 +50524,7 @@ void flecs_meta_import_core_definitions( }), .type = { .as_type = ecs_id(ecs_string_t), - .serialize = flecs_const_str_serialize, + .get_string = flecs_const_get_string, } }); diff --git a/distr/flecs.h b/distr/flecs.h index 572c77d3a8..821f466a5f 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -15843,6 +15843,43 @@ typedef struct EcsOpaque { void (*resize)( void *dst, size_t count); + + /* Getter interface */ + + /** Get bool value */ + bool (*get_bool)( + const void *src); + + /** Get char value */ + char (*get_char)( + const void *src); + + /** Get int value */ + int64_t (*get_int)( + const void *src); + + /** Get unsigned int value */ + uint64_t (*get_uint)( + const void *src); + + /** Get float value */ + double (*get_float)( + const void *src); + + /** Get string value */ + const char* (*get_string)( + const void *src); + + /** Get entity value */ + ecs_entity_t (*get_entity)( + const void *src, + const ecs_world_t *world); + + /** Get (component) id value */ + ecs_id_t (*get_id)( + const void *src, + const ecs_world_t *world); + } EcsOpaque; @@ -16308,6 +16345,7 @@ ecs_entity_t ecs_meta_get_entity( * @param cursor The cursor. * @return The value of the current field. */ +FLECS_API ecs_id_t ecs_meta_get_id( const ecs_meta_cursor_t *cursor); @@ -19469,6 +19507,72 @@ struct opaque { return *this; } + /* Getter interface */ + + /** Get bool value */ + opaque& get_bool(bool (*func)(const T *src)) { + this->desc.type.get_bool = + reinterpret_castdesc.type.get_bool)>(func); + return *this; + } + + /** Get char value */ + opaque& get_char(char (*func)(const T *src)) { + this->desc.type.get_char = + reinterpret_castdesc.type.get_char)>(func); + return *this; + } + + /** Get int value */ + opaque& get_int(int64_t (*func)(const T *src)) { + this->desc.type.get_int = + reinterpret_castdesc.type.get_int)>(func); + return *this; + } + + /** Get unsigned int value */ + opaque& get_uint(uint64_t (*func)(const T *src)) { + this->desc.type.get_uint = + reinterpret_castdesc.type.get_uint)>(func); + return *this; + } + + /** Get float value */ + opaque& get_float(double (*func)(const T *src)) { + this->desc.type.get_float = + reinterpret_castdesc.type.get_float)>(func); + return *this; + } + + /** Get string value */ + opaque& get_string(const char* (*func)(const T *src)) { + this->desc.type.get_string = + reinterpret_castdesc.type.get_string)>(func); + return *this; + } + + /** Get entity value */ + opaque& get_entity(ecs_entity_t (*func)(const T *src, const flecs::world_t *world)) { + this->desc.type.get_entity = + reinterpret_castdesc.type.get_entity)>(func); + return *this; + } + + /** Get (component) id value */ + opaque& get_id(ecs_id_t (*func)(const T *src, const flecs::world_t *world)) { + this->desc.type.get_id = + reinterpret_castdesc.type.get_id)>(func); + return *this; + } + ~opaque() { if (world) { ecs_opaque_init(world, &desc); diff --git a/include/flecs/addons/cpp/mixins/meta/opaque.hpp b/include/flecs/addons/cpp/mixins/meta/opaque.hpp index f8a4ec3f56..af6a37ae8e 100644 --- a/include/flecs/addons/cpp/mixins/meta/opaque.hpp +++ b/include/flecs/addons/cpp/mixins/meta/opaque.hpp @@ -232,14 +232,6 @@ struct opaque { return *this; } - /** Check if value is null */ - opaque& is_null(bool (*func)(const T *src)) { - this->desc.type.is_null = - reinterpret_castdesc.type.is_null)>(func); - return *this; - } - ~opaque() { if (world) { ecs_opaque_init(world, &desc); diff --git a/include/flecs/addons/meta.h b/include/flecs/addons/meta.h index 4f81aed550..16a9897324 100644 --- a/include/flecs/addons/meta.h +++ b/include/flecs/addons/meta.h @@ -494,10 +494,6 @@ typedef struct EcsOpaque { const void *src, const ecs_world_t *world); - /** Check if value is null */ - bool (*is_null)( - const void *src); - } EcsOpaque; @@ -963,6 +959,7 @@ ecs_entity_t ecs_meta_get_entity( * @param cursor The cursor. * @return The value of the current field. */ +FLECS_API ecs_id_t ecs_meta_get_id( const ecs_meta_cursor_t *cursor); diff --git a/src/addons/meta/cursor.c b/src/addons/meta/cursor.c index 5bfaaae255..dca2218d27 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -2159,7 +2159,7 @@ ecs_entity_t ecs_meta_get_entity( return 0; } -ecs_entity_t ecs_meta_get_id( +ecs_id_t ecs_meta_get_id( const ecs_meta_cursor_t *cursor) { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); diff --git a/src/addons/meta/definitions.c b/src/addons/meta/definitions.c index 7cccfc8e32..2769ea1946 100644 --- a/src/addons/meta/definitions.c +++ b/src/addons/meta/definitions.c @@ -32,8 +32,7 @@ size_t flecs_addon_vec_count(const void *ptr) { static const char* flecs_const_get_string(const void *ptr) { - const char **data = (const char**) ptr; - return *data; + return *((const char *const *) ptr); } /* Initialize reflection data for core components */ diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index 29546cf154..3a246de640 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3209,7 +3209,8 @@ void Cursor_opaque_set_id(void) { ecs_opaque(world, { .entity = ecs_id(Opaque_id), .type.as_type = ecs_id(ecs_id_t), - .type.assign_id = Opaque_id_set + .type.assign_id = Opaque_id_set, + .type.get_id = Opaque_id_get }); Opaque_id v = { 0 }; @@ -3219,8 +3220,10 @@ void Cursor_opaque_set_id(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(Opaque_id), &v); test_int(0, ecs_meta_set_id(&cur, e1)); test_uint(v.value, e1); + test_uint(ecs_meta_get_id(&cur), e1); test_int(0, ecs_meta_set_id(&cur, e2)); test_uint(v.value, e2); + test_uint(ecs_meta_get_id(&cur), e2); ecs_fini(world); } From a2965859f3655ef9faabd51f75980afe1b54c536 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Wed, 16 Oct 2024 21:51:40 +0200 Subject: [PATCH 05/11] rename tests --- test/meta/project.json | 14 +++++++------- test/meta/src/Cursor.c | 14 +++++++------- test/meta/src/main.c | 42 +++++++++++++++++++++--------------------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/test/meta/project.json b/test/meta/project.json index e9147dab11..b1575475d5 100644 --- a/test/meta/project.json +++ b/test/meta/project.json @@ -441,14 +441,14 @@ "array_move_primitive", "array_move_struct", "array_move_out_of_range", - "opaque_set_bool", - "opaque_set_char", - "opaque_set_int", - "opaque_set_uint", - "opaque_set_float", + "opaque_get_set_bool", + "opaque_get_set_char", + "opaque_get_set_int", + "opaque_get_set_uint", + "opaque_get_set_float", "opaque_get_set_string", - "opaque_set_entity", - "opaque_set_id", + "opaque_get_set_entity", + "opaque_get_set_id", "opaque_set_int_vec", "opaque_set_int_vec_empty", "opaque_set_int_vec_resize_smaller", diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index 3a246de640..35ad5ffda9 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3025,7 +3025,7 @@ static ecs_entity_t Opaque_id_get(const void *ptr, const ecs_world_t *world) { return ((Opaque_id*)ptr)->value; } -void Cursor_opaque_set_bool(void) { +void Cursor_opaque_get_set_bool(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_bool); @@ -3050,7 +3050,7 @@ void Cursor_opaque_set_bool(void) { ecs_fini(world); } -void Cursor_opaque_set_char(void) { +void Cursor_opaque_get_set_char(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_char); @@ -3075,7 +3075,7 @@ void Cursor_opaque_set_char(void) { ecs_fini(world); } -void Cursor_opaque_set_int(void) { +void Cursor_opaque_get_set_int(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_int64_t); @@ -3100,7 +3100,7 @@ void Cursor_opaque_set_int(void) { ecs_fini(world); } -void Cursor_opaque_set_uint(void) { +void Cursor_opaque_get_set_uint(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_uint64_t); @@ -3125,7 +3125,7 @@ void Cursor_opaque_set_uint(void) { ecs_fini(world); } -void Cursor_opaque_set_float(void) { +void Cursor_opaque_get_set_float(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_double); @@ -3174,7 +3174,7 @@ void Cursor_opaque_get_set_string(void) { ecs_fini(world); } -void Cursor_opaque_set_entity(void) { +void Cursor_opaque_get_set_entity(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_entity); @@ -3201,7 +3201,7 @@ void Cursor_opaque_set_entity(void) { ecs_fini(world); } -void Cursor_opaque_set_id(void) { +void Cursor_opaque_get_set_id(void) { ecs_world_t *world = ecs_init(); ECS_COMPONENT(world, Opaque_id); diff --git a/test/meta/src/main.c b/test/meta/src/main.c index a5d9f23c81..9bfae356f0 100644 --- a/test/meta/src/main.c +++ b/test/meta/src/main.c @@ -416,14 +416,14 @@ void Cursor_array_struct_3(void); void Cursor_array_move_primitive(void); void Cursor_array_move_struct(void); void Cursor_array_move_out_of_range(void); -void Cursor_opaque_set_bool(void); -void Cursor_opaque_set_char(void); -void Cursor_opaque_set_int(void); -void Cursor_opaque_set_uint(void); -void Cursor_opaque_set_float(void); +void Cursor_opaque_get_set_bool(void); +void Cursor_opaque_get_set_char(void); +void Cursor_opaque_get_set_int(void); +void Cursor_opaque_get_set_uint(void); +void Cursor_opaque_get_set_float(void); void Cursor_opaque_get_set_string(void); -void Cursor_opaque_set_entity(void); -void Cursor_opaque_set_id(void); +void Cursor_opaque_get_set_entity(void); +void Cursor_opaque_get_set_id(void); void Cursor_opaque_set_int_vec(void); void Cursor_opaque_set_int_vec_empty(void); void Cursor_opaque_set_int_vec_resize_smaller(void); @@ -2601,36 +2601,36 @@ bake_test_case Cursor_testcases[] = { Cursor_array_move_out_of_range }, { - "opaque_set_bool", - Cursor_opaque_set_bool + "opaque_get_set_bool", + Cursor_opaque_get_set_bool }, { - "opaque_set_char", - Cursor_opaque_set_char + "opaque_get_set_char", + Cursor_opaque_get_set_char }, { - "opaque_set_int", - Cursor_opaque_set_int + "opaque_get_set_int", + Cursor_opaque_get_set_int }, { - "opaque_set_uint", - Cursor_opaque_set_uint + "opaque_get_set_uint", + Cursor_opaque_get_set_uint }, { - "opaque_set_float", - Cursor_opaque_set_float + "opaque_get_set_float", + Cursor_opaque_get_set_float }, { "opaque_get_set_string", Cursor_opaque_get_set_string }, { - "opaque_set_entity", - Cursor_opaque_set_entity + "opaque_get_set_entity", + Cursor_opaque_get_set_entity }, { - "opaque_set_id", - Cursor_opaque_set_id + "opaque_get_set_id", + Cursor_opaque_get_set_id }, { "opaque_set_int_vec", From d24ae39e2daa55561894a4831ea691bb1117b9dc Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Wed, 16 Oct 2024 22:02:50 +0200 Subject: [PATCH 06/11] --getter interface fix const string serializer --- distr/flecs.c | 10 +++++++++- src/addons/meta/definitions.c | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/distr/flecs.c b/distr/flecs.c index df019cb91d..eb28b1e53e 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -50480,6 +50480,13 @@ size_t flecs_addon_vec_count(const void *ptr) { return flecs_ito(size_t, count); } +static +int flecs_const_str_serialize(const ecs_serializer_t *ser, const void *ptr) { + char **data = ECS_CONST_CAST(char**, ptr); + ser->value(ser, ecs_id(ecs_string_t), data); + return 0; +} + static const char* flecs_const_get_string(const void *ptr) { return *((const char *const *) ptr); @@ -50524,7 +50531,8 @@ void flecs_meta_import_core_definitions( }), .type = { .as_type = ecs_id(ecs_string_t), - .get_string = flecs_const_get_string, + .serialize = flecs_const_str_serialize, + .get_string = flecs_const_get_string, } }); diff --git a/src/addons/meta/definitions.c b/src/addons/meta/definitions.c index 2769ea1946..5556896481 100644 --- a/src/addons/meta/definitions.c +++ b/src/addons/meta/definitions.c @@ -30,6 +30,13 @@ size_t flecs_addon_vec_count(const void *ptr) { return flecs_ito(size_t, count); } +static +int flecs_const_str_serialize(const ecs_serializer_t *ser, const void *ptr) { + char **data = ECS_CONST_CAST(char**, ptr); + ser->value(ser, ecs_id(ecs_string_t), data); + return 0; +} + static const char* flecs_const_get_string(const void *ptr) { return *((const char *const *) ptr); @@ -74,7 +81,8 @@ void flecs_meta_import_core_definitions( }), .type = { .as_type = ecs_id(ecs_string_t), - .get_string = flecs_const_get_string, + .serialize = flecs_const_str_serialize, + .get_string = flecs_const_get_string, } }); From 330625090527321fab3aaae41da544f72c81d4a5 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Thu, 17 Oct 2024 10:58:21 +0200 Subject: [PATCH 07/11] before big rename --- .../flecs/addons/cpp/mixins/meta/opaque.hpp | 16 +++ include/flecs/addons/meta.h | 23 +++- src/addons/meta/cursor.c | 123 ++++++++++++++---- test/meta/src/Cursor.c | 25 ++++ 4 files changed, 162 insertions(+), 25 deletions(-) diff --git a/include/flecs/addons/cpp/mixins/meta/opaque.hpp b/include/flecs/addons/cpp/mixins/meta/opaque.hpp index af6a37ae8e..81955597d4 100644 --- a/include/flecs/addons/cpp/mixins/meta/opaque.hpp +++ b/include/flecs/addons/cpp/mixins/meta/opaque.hpp @@ -232,6 +232,22 @@ struct opaque { return *this; } + /** Get collection element */ + opaque& get_element(const void* (*func)(const T *src, size_t elem)) { + this->desc.type.get_element = + reinterpret_castdesc.type.get_element)>(func); + return *this; + } + + /** get element */ + opaque& get_member(const void* (*func)(const T *src, const char *member)) { + this->desc.type.get_member = + reinterpret_castdesc.type.get_member)>(func); + return *this; + } + ~opaque() { if (world) { ecs_opaque_init(world, &desc); diff --git a/include/flecs/addons/meta.h b/include/flecs/addons/meta.h index 16a9897324..bc259c0e4b 100644 --- a/include/flecs/addons/meta.h +++ b/include/flecs/addons/meta.h @@ -494,6 +494,16 @@ typedef struct EcsOpaque { const void *src, const ecs_world_t *world); + /** get collection element */ + const void* (*get_element)( + const void *src, + size_t elem); + + /** get element */ + const void* (*get_member)( + const void *src, + const char *member); + } EcsOpaque; @@ -648,15 +658,24 @@ ecs_meta_cursor_t ecs_meta_cursor( ecs_entity_t type, void *ptr); -/** Get pointer to current field. +/** Get pointer to current field for writing. * * @param cursor The cursor. - * @return A pointer to the current field. + * @return A pointer to the current field for writing. */ FLECS_API void* ecs_meta_get_ptr( ecs_meta_cursor_t *cursor); +/** Get pointer to current field for reading. + * + * @param cursor The cursor. + * @return A pointer to the current field. NULL if element does not exist. + */ +FLECS_API +const void* ecs_meta_get_read_ptr( + ecs_meta_cursor_t *cursor); + /** Move cursor to next field. * * @param cursor The cursor. diff --git a/src/addons/meta/cursor.c b/src/addons/meta/cursor.c index dca2218d27..61ba1730fe 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -124,9 +124,9 @@ int32_t get_elem_count( return op->count; } -/* Get pointer to current field/element */ +/* Get pointer to current field/element for writing */ static -ecs_meta_type_op_t* flecs_meta_cursor_get_ptr( +void* flecs_meta_cursor_get_write_ptr( const ecs_world_t *world, ecs_meta_scope_t *scope) { @@ -170,6 +170,52 @@ ecs_meta_type_op_t* flecs_meta_cursor_get_ptr( return ECS_OFFSET(scope->ptr, size * scope->elem_cur + op->offset); } +/* Get pointer to current field/element for reading */ +static +const void* flecs_meta_cursor_get_read_ptr( + const ecs_world_t *world, + ecs_meta_scope_t *scope) +{ + ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); + ecs_size_t size = get_size(world, scope); + const EcsOpaque *opaque = scope->opaque; + + if (scope->vector) { + if(ecs_vec_count(scope->vector) <= scope->elem_cur){ + return NULL; + } + scope->ptr = ecs_vec_first(scope->vector); + } else if (opaque) { + if (scope->is_collection) { + if (!opaque->get_element) { + char *str = ecs_get_path(world, scope->type); + ecs_err("missing get_element for opaque type %s", str); + ecs_os_free(str); + return NULL; + } + scope->is_empty_scope = false; + + const void *opaque_ptr = opaque->get_element( + scope->ptr, flecs_ito(size_t, scope->elem_cur)); + return opaque_ptr; + } else if (op->name) { + if (!opaque->get_member) { + char *str = ecs_get_path(world, scope->type); + ecs_err("missing get_member for opaque type %s", str); + ecs_os_free(str); + return NULL; + } + ecs_assert(scope->ptr != NULL, ECS_INTERNAL_ERROR, NULL); + return opaque->get_member(scope->ptr, op->name); + } else { + ecs_err("invalid operation for opaque type"); + return NULL; + } + } + + return ECS_OFFSET(scope->ptr, size * scope->elem_cur + op->offset); +} + static int flecs_meta_cursor_push_type( const ecs_world_t *world, @@ -221,7 +267,14 @@ ecs_meta_cursor_t ecs_meta_cursor( void* ecs_meta_get_ptr( ecs_meta_cursor_t *cursor) { - return flecs_meta_cursor_get_ptr(cursor->world, + return flecs_meta_cursor_get_write_ptr(cursor->world, + flecs_meta_cursor_get_scope(cursor)); +} + +const void* ecs_meta_get_read_ptr( + ecs_meta_cursor_t *cursor) +{ + return flecs_meta_cursor_get_read_ptr(cursor->world, flecs_meta_cursor_get_scope(cursor)); } @@ -398,7 +451,7 @@ int ecs_meta_push( } } - void *ptr = flecs_meta_cursor_get_ptr(world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(world, scope); cursor->depth ++; ecs_check(cursor->depth < ECS_META_MAX_SCOPE_DEPTH, ECS_INVALID_PARAMETER, NULL); @@ -885,7 +938,7 @@ int ecs_meta_set_bool( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -935,7 +988,7 @@ int ecs_meta_set_char( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -997,7 +1050,7 @@ int ecs_meta_set_int( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -1055,7 +1108,7 @@ int ecs_meta_set_uint( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -1112,7 +1165,7 @@ int ecs_meta_set_float( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpBool: @@ -1218,7 +1271,7 @@ int ecs_meta_set_value( } else { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); if (op->type != value->type) { char *type_str = ecs_get_path(cursor->world, value->type); flecs_meta_conversion_error(cursor, op, type_str); @@ -1333,7 +1386,7 @@ int ecs_meta_set_string( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpI8: @@ -1521,7 +1574,7 @@ int ecs_meta_set_string_literal( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); if (!value) { return -1; @@ -1593,7 +1646,7 @@ int ecs_meta_set_entity( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpEntity: @@ -1658,7 +1711,7 @@ int ecs_meta_set_id( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpId: @@ -1720,7 +1773,7 @@ int ecs_meta_set_null( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch (op->kind) { case EcsOpString: ecs_os_free(*(char**)ptr); @@ -1776,7 +1829,10 @@ bool ecs_meta_get_bool( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpBool: return *(ecs_bool_t*)ptr; case EcsOpI8: return *(ecs_i8_t*)ptr != 0; @@ -1830,7 +1886,10 @@ char ecs_meta_get_char( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpChar: return *(ecs_char_t*)ptr != 0; @@ -1882,7 +1941,10 @@ int64_t ecs_meta_get_int( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpBool: return *(const ecs_bool_t*)ptr; case EcsOpI8: return *(const ecs_i8_t*)ptr; @@ -1941,7 +2003,10 @@ uint64_t ecs_meta_get_uint( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpBool: return *(ecs_bool_t*)ptr; case EcsOpI8: return flecs_ito(uint64_t, *(const ecs_i8_t*)ptr); @@ -2043,7 +2108,10 @@ double ecs_meta_get_float( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } if(op->kind == EcsOpOpaque){ /* If opaque type knows how to convert to float, retrieve it. Otherwise, fallback to default case (error). */ @@ -2063,7 +2131,10 @@ const char* ecs_meta_get_string( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpString: return *(const char**)ptr; case EcsOpOpaque: { @@ -2114,7 +2185,10 @@ ecs_entity_t ecs_meta_get_entity( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpEntity: return *(ecs_entity_t*)ptr; case EcsOpOpaque: { @@ -2164,7 +2238,10 @@ ecs_id_t ecs_meta_get_id( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpEntity: return *(ecs_id_t*)ptr; /* Entities are valid ids */ case EcsOpId: return *(ecs_id_t*)ptr; diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index 35ad5ffda9..c7236a50ff 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3247,6 +3247,14 @@ static void* IntVec_ensure(void *ptr, size_t index) { return &data->array[index]; } +static const void* IntVec_get(const void *ptr, size_t index) { + const IntVec *data = ptr; + if (index >= data->count) { + return NULL; + } + return &data->array[index]; +} + static void IntVec_resize(void *ptr, size_t size) { IntVec *data = ptr; if (data->count != size) { @@ -3269,6 +3277,7 @@ void Cursor_opaque_set_int_vec(void) { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t) }), .type.ensure_element = IntVec_ensure, + .type.get_element = IntVec_get, .type.count = IntVec_count, .type.resize = IntVec_resize }); @@ -3289,6 +3298,22 @@ void Cursor_opaque_set_int_vec(void) { 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(ecs_meta_get_int(&cur), 10); + test_int(0, ecs_meta_next(&cur)); + test_int(ecs_meta_get_int(&cur), 20); + test_int(0, ecs_meta_next(&cur)); + test_int(ecs_meta_get_int(&cur), 30); + + /* set up an abort handler for the following operations */ + install_test_abort(); + test_expect_abort(); + + test_int(0, ecs_meta_next(&cur)); + /* Expect the next read to fail since we are trying to read a non-existing element */ + ecs_meta_get_int(&cur); + ecs_os_free(v.array); ecs_fini(world); From 65af3e89a4b2b2c23aec9b91c01a0adf36c7224b Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Thu, 17 Oct 2024 12:40:01 +0200 Subject: [PATCH 08/11] wip --- distr/flecs.c | 197 ++++++++++++------ distr/flecs.h | 52 ++++- .../flecs/addons/cpp/mixins/meta/cursor.hpp | 11 +- include/flecs/addons/meta.h | 2 +- src/addons/meta/cursor.c | 68 +++--- src/addons/metrics.c | 2 +- src/addons/script/expr/visit_type.c | 4 +- test/meta/src/Cursor.c | 85 ++++++-- 8 files changed, 299 insertions(+), 122 deletions(-) diff --git a/distr/flecs.c b/distr/flecs.c index eb28b1e53e..cb7ef777d8 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -25524,7 +25524,7 @@ int flecs_member_metric_init( id = desc->id; member_type = ecs_meta_get_type(&cur); - offset = (uintptr_t)ecs_meta_get_ptr(&cur); + offset = (uintptr_t)ecs_meta_get_write_ptr(&cur); member = ecs_meta_get_member_id(&cur); } else { const EcsMember *m = ecs_get(world, desc->member, EcsMember); @@ -48354,9 +48354,9 @@ int32_t get_elem_count( return op->count; } -/* Get pointer to current field/element */ +/* Get pointer to current field/element for writing */ static -ecs_meta_type_op_t* flecs_meta_cursor_get_ptr( +void* flecs_meta_cursor_get_write_ptr( const ecs_world_t *world, ecs_meta_scope_t *scope) { @@ -48400,6 +48400,52 @@ ecs_meta_type_op_t* flecs_meta_cursor_get_ptr( return ECS_OFFSET(scope->ptr, size * scope->elem_cur + op->offset); } +/* Get pointer to current field/element for reading */ +static +const void* flecs_meta_cursor_get_read_ptr( + const ecs_world_t *world, + ecs_meta_scope_t *scope) +{ + ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); + ecs_size_t size = get_size(world, scope); + const EcsOpaque *opaque = scope->opaque; + + if (scope->vector) { + if(ecs_vec_count(scope->vector) <= scope->elem_cur){ + return NULL; + } + scope->ptr = ecs_vec_first(scope->vector); + } else if (opaque) { + if (scope->is_collection) { + if (!opaque->get_element) { + char *str = ecs_get_path(world, scope->type); + ecs_err("missing get_element for opaque type %s", str); + ecs_os_free(str); + return NULL; + } + scope->is_empty_scope = false; + + const void *opaque_ptr = opaque->get_element( + scope->ptr, flecs_ito(size_t, scope->elem_cur)); + return opaque_ptr; + } else if (op->name) { + if (!opaque->get_member) { + char *str = ecs_get_path(world, scope->type); + ecs_err("missing get_member for opaque type %s", str); + ecs_os_free(str); + return NULL; + } + ecs_assert(scope->ptr != NULL, ECS_INTERNAL_ERROR, NULL); + return opaque->get_member(scope->ptr, op->name); + } else { + ecs_err("invalid operation for opaque type"); + return NULL; + } + } + + return ECS_OFFSET(scope->ptr, size * scope->elem_cur + op->offset); +} + static int flecs_meta_cursor_push_type( const ecs_world_t *world, @@ -48448,10 +48494,17 @@ ecs_meta_cursor_t ecs_meta_cursor( return (ecs_meta_cursor_t){ 0 }; } -void* ecs_meta_get_ptr( +void* ecs_meta_get_write_ptr( ecs_meta_cursor_t *cursor) { - return flecs_meta_cursor_get_ptr(cursor->world, + return flecs_meta_cursor_get_write_ptr(cursor->world, + flecs_meta_cursor_get_scope(cursor)); +} + +const void* ecs_meta_get_read_ptr( + ecs_meta_cursor_t *cursor) +{ + return flecs_meta_cursor_get_read_ptr(cursor->world, flecs_meta_cursor_get_scope(cursor)); } @@ -48628,7 +48681,7 @@ int ecs_meta_push( } } - void *ptr = flecs_meta_cursor_get_ptr(world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(world, scope); cursor->depth ++; ecs_check(cursor->depth < ECS_META_MAX_SCOPE_DEPTH, ECS_INVALID_PARAMETER, NULL); @@ -49115,7 +49168,7 @@ int ecs_meta_set_bool( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -49165,7 +49218,7 @@ int ecs_meta_set_char( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -49227,7 +49280,7 @@ int ecs_meta_set_int( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -49285,7 +49338,7 @@ int ecs_meta_set_uint( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { cases_T_bool(ptr, value); @@ -49342,7 +49395,7 @@ int ecs_meta_set_float( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpBool: @@ -49448,7 +49501,7 @@ int ecs_meta_set_value( } else { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); if (op->type != value->type) { char *type_str = ecs_get_path(cursor->world, value->type); flecs_meta_conversion_error(cursor, op, type_str); @@ -49563,7 +49616,7 @@ int ecs_meta_set_string( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpI8: @@ -49751,7 +49804,7 @@ int ecs_meta_set_string_literal( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); if (!value) { return -1; @@ -49823,7 +49876,7 @@ int ecs_meta_set_entity( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpEntity: @@ -49888,7 +49941,7 @@ int ecs_meta_set_id( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch(op->kind) { case EcsOpId: @@ -49950,7 +50003,7 @@ int ecs_meta_set_null( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + void *ptr = flecs_meta_cursor_get_write_ptr(cursor->world, scope); switch (op->kind) { case EcsOpString: ecs_os_free(*(char**)ptr); @@ -50006,28 +50059,31 @@ bool ecs_meta_get_bool( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { - case EcsOpBool: return *(ecs_bool_t*)ptr; - case EcsOpI8: return *(ecs_i8_t*)ptr != 0; - case EcsOpU8: return *(ecs_u8_t*)ptr != 0; - case EcsOpChar: return *(ecs_char_t*)ptr != 0; - case EcsOpByte: return *(ecs_u8_t*)ptr != 0; - case EcsOpI16: return *(ecs_i16_t*)ptr != 0; - case EcsOpU16: return *(ecs_u16_t*)ptr != 0; - case EcsOpI32: return *(ecs_i32_t*)ptr != 0; - case EcsOpU32: return *(ecs_u32_t*)ptr != 0; - case EcsOpI64: return *(ecs_i64_t*)ptr != 0; - case EcsOpU64: return *(ecs_u64_t*)ptr != 0; - case EcsOpIPtr: return *(ecs_iptr_t*)ptr != 0; - case EcsOpUPtr: return *(ecs_uptr_t*)ptr != 0; - case EcsOpF32: return ECS_NEQZERO(*(ecs_f32_t*)ptr); - case EcsOpF64: return ECS_NEQZERO(*(ecs_f64_t*)ptr); - case EcsOpString: return *(const char**)ptr != NULL; - case EcsOpEnum: return *(ecs_i32_t*)ptr != 0; - case EcsOpBitmask: return *(ecs_u32_t*)ptr != 0; - case EcsOpEntity: return *(ecs_entity_t*)ptr != 0; - case EcsOpId: return *(ecs_id_t*)ptr != 0; + case EcsOpBool: return *(const ecs_bool_t*)ptr; + case EcsOpI8: return *(const ecs_i8_t*)ptr != 0; + case EcsOpU8: return *(const ecs_u8_t*)ptr != 0; + case EcsOpChar: return *(const ecs_char_t*)ptr != 0; + case EcsOpByte: return *(const ecs_u8_t*)ptr != 0; + case EcsOpI16: return *(const ecs_i16_t*)ptr != 0; + case EcsOpU16: return *(const ecs_u16_t*)ptr != 0; + case EcsOpI32: return *(const ecs_i32_t*)ptr != 0; + case EcsOpU32: return *(const ecs_u32_t*)ptr != 0; + case EcsOpI64: return *(const ecs_i64_t*)ptr != 0; + case EcsOpU64: return *(const ecs_u64_t*)ptr != 0; + case EcsOpIPtr: return *(const ecs_iptr_t*)ptr != 0; + case EcsOpUPtr: return *(const ecs_uptr_t*)ptr != 0; + case EcsOpF32: return ECS_NEQZERO(*(const ecs_f32_t*)ptr); + case EcsOpF64: return ECS_NEQZERO(*(const ecs_f64_t*)ptr); + case EcsOpString: return *(const char* const *)ptr != NULL; + case EcsOpEnum: return *(const ecs_i32_t*)ptr != 0; + case EcsOpBitmask: return *(const ecs_u32_t*)ptr != 0; + case EcsOpEntity: return *(const ecs_entity_t*)ptr != 0; + case EcsOpId: return *(const ecs_id_t*)ptr != 0; case EcsOpOpaque: { /* If opaque type knows how to convert to bool, retrieve it. Otherwise, fallback to default case (error). */ @@ -50060,10 +50116,13 @@ char ecs_meta_get_char( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpChar: - return *(ecs_char_t*)ptr != 0; + return *(const ecs_char_t*)ptr != 0; case EcsOpOpaque: { /* If opaque type knows how to convert to char, retrieve it. Otherwise, fallback to default case (error). */ @@ -50112,7 +50171,10 @@ int64_t ecs_meta_get_int( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { case EcsOpBool: return *(const ecs_bool_t*)ptr; case EcsOpI8: return *(const ecs_i8_t*)ptr; @@ -50129,7 +50191,7 @@ int64_t ecs_meta_get_int( case EcsOpUPtr: return flecs_uto(int64_t, *(const ecs_uptr_t*)ptr); case EcsOpF32: return (int64_t)*(const ecs_f32_t*)ptr; case EcsOpF64: return (int64_t)*(const ecs_f64_t*)ptr; - case EcsOpString: return atoi(*(const char**)ptr); + case EcsOpString: return atoi(*(const char* const *)ptr); case EcsOpEnum: return *(const ecs_i32_t*)ptr; case EcsOpBitmask: return *(const ecs_u32_t*)ptr; case EcsOpEntity: @@ -50171,24 +50233,27 @@ uint64_t ecs_meta_get_uint( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { - case EcsOpBool: return *(ecs_bool_t*)ptr; + case EcsOpBool: return *(const ecs_bool_t*)ptr; case EcsOpI8: return flecs_ito(uint64_t, *(const ecs_i8_t*)ptr); - case EcsOpU8: return *(ecs_u8_t*)ptr; + case EcsOpU8: return *(const ecs_u8_t*)ptr; case EcsOpChar: return flecs_ito(uint64_t, *(const ecs_char_t*)ptr); case EcsOpByte: return flecs_ito(uint64_t, *(const ecs_u8_t*)ptr); case EcsOpI16: return flecs_ito(uint64_t, *(const ecs_i16_t*)ptr); - case EcsOpU16: return *(ecs_u16_t*)ptr; + case EcsOpU16: return *(const ecs_u16_t*)ptr; case EcsOpI32: return flecs_ito(uint64_t, *(const ecs_i32_t*)ptr); - case EcsOpU32: return *(ecs_u32_t*)ptr; + case EcsOpU32: return *(const ecs_u32_t*)ptr; case EcsOpI64: return flecs_ito(uint64_t, *(const ecs_i64_t*)ptr); - case EcsOpU64: return *(ecs_u64_t*)ptr; + case EcsOpU64: return *(const ecs_u64_t*)ptr; case EcsOpIPtr: return flecs_ito(uint64_t, *(const ecs_i64_t*)ptr); - case EcsOpUPtr: return *(ecs_uptr_t*)ptr; + case EcsOpUPtr: return *(const ecs_uptr_t*)ptr; case EcsOpF32: return flecs_ito(uint64_t, *(const ecs_f32_t*)ptr); case EcsOpF64: return flecs_ito(uint64_t, *(const ecs_f64_t*)ptr); - case EcsOpString: return flecs_ito(uint64_t, atoi(*(const char**)ptr)); + case EcsOpString: return flecs_ito(uint64_t, atoi(*(const char* const *)ptr)); case EcsOpEnum: return flecs_ito(uint64_t, *(const ecs_i32_t*)ptr); case EcsOpBitmask: return *(const ecs_u32_t*)ptr; case EcsOpEntity: return *(const ecs_entity_t*)ptr; @@ -50273,7 +50338,10 @@ double ecs_meta_get_float( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } if(op->kind == EcsOpOpaque){ /* If opaque type knows how to convert to float, retrieve it. Otherwise, fallback to default case (error). */ @@ -50293,9 +50361,12 @@ const char* ecs_meta_get_string( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { - case EcsOpString: return *(const char**)ptr; + case EcsOpString: return *(const char* const*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to string, retrieve it. Otherwise, fallback to default case (error). */ @@ -50344,9 +50415,12 @@ ecs_entity_t ecs_meta_get_entity( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { - case EcsOpEntity: return *(ecs_entity_t*)ptr; + case EcsOpEntity: return *(const ecs_entity_t*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to entity, retrieve it. Otherwise, fallback to default case (error). */ @@ -50394,10 +50468,13 @@ ecs_id_t ecs_meta_get_id( { ecs_meta_scope_t *scope = flecs_meta_cursor_get_scope(cursor); ecs_meta_type_op_t *op = flecs_meta_cursor_get_op(scope); - void *ptr = flecs_meta_cursor_get_ptr(cursor->world, scope); + const void *ptr = flecs_meta_cursor_get_read_ptr(cursor->world, scope); + if(!ptr) { + ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); + } switch(op->kind) { - case EcsOpEntity: return *(ecs_id_t*)ptr; /* Entities are valid ids */ - case EcsOpId: return *(ecs_id_t*)ptr; + case EcsOpEntity: return *(const ecs_id_t*)ptr; /* Entities are valid ids */ + case EcsOpId: return *(const ecs_id_t*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to id, retrieve it. Otherwise, fallback to default case (error). */ @@ -79287,7 +79364,7 @@ int flecs_expr_initializer_visit_type( } if (!is_opaque) { - elem->offset = (uintptr_t)ecs_meta_get_ptr(cur); + elem->offset = (uintptr_t)ecs_meta_get_write_ptr(cur); } } @@ -79749,7 +79826,7 @@ int flecs_expr_member_visit_type( const EcsMember *m = ecs_get(world, ecs_meta_get_member_id(cur), EcsMember); ecs_assert(m != NULL, ECS_INTERNAL_ERROR, NULL); #endif - node->offset = (uintptr_t)ecs_meta_get_ptr(cur); + node->offset = (uintptr_t)ecs_meta_get_write_ptr(cur); return 0; error: diff --git a/distr/flecs.h b/distr/flecs.h index 821f466a5f..9fe5cd410e 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -15880,6 +15880,16 @@ typedef struct EcsOpaque { const void *src, const ecs_world_t *world); + /** get collection element */ + const void* (*get_element)( + const void *src, + size_t elem); + + /** get element */ + const void* (*get_member)( + const void *src, + const char *member); + } EcsOpaque; @@ -16034,13 +16044,22 @@ ecs_meta_cursor_t ecs_meta_cursor( ecs_entity_t type, void *ptr); -/** Get pointer to current field. +/** Get pointer to current field for writing. + * + * @param cursor The cursor. + * @return A pointer to the current field for writing. + */ +FLECS_API +void* ecs_meta_get_write_ptr( + ecs_meta_cursor_t *cursor); + +/** Get pointer to current field for reading. * * @param cursor The cursor. - * @return A pointer to the current field. + * @return A pointer to the current field. NULL if element does not exist. */ FLECS_API -void* ecs_meta_get_ptr( +const void* ecs_meta_get_read_ptr( ecs_meta_cursor_t *cursor); /** Move cursor to next field. @@ -19243,9 +19262,14 @@ struct cursor { /** Get unit of value */ flecs::entity get_unit() const; - /** Get untyped pointer to value */ - void* get_ptr() { - return ecs_meta_get_ptr(&cursor_); + /** Get untyped pointer to value for writing */ + void* get_write_ptr() { + return ecs_meta_get_write_ptr(&cursor_); + } + + /** Get untyped pointer to value for reading */ + const void* get_read_ptr() { + return ecs_meta_get_read_ptr(&cursor_); } /** Set boolean value */ @@ -19573,6 +19597,22 @@ struct opaque { return *this; } + /** Get collection element */ + opaque& get_element(const void* (*func)(const T *src, size_t elem)) { + this->desc.type.get_element = + reinterpret_castdesc.type.get_element)>(func); + return *this; + } + + /** get element */ + opaque& get_member(const void* (*func)(const T *src, const char *member)) { + this->desc.type.get_member = + reinterpret_castdesc.type.get_member)>(func); + return *this; + } + ~opaque() { if (world) { ecs_opaque_init(world, &desc); diff --git a/include/flecs/addons/cpp/mixins/meta/cursor.hpp b/include/flecs/addons/cpp/mixins/meta/cursor.hpp index 868621c2db..3bceb90628 100644 --- a/include/flecs/addons/cpp/mixins/meta/cursor.hpp +++ b/include/flecs/addons/cpp/mixins/meta/cursor.hpp @@ -65,9 +65,14 @@ struct cursor { /** Get unit of value */ flecs::entity get_unit() const; - /** Get untyped pointer to value */ - void* get_ptr() { - return ecs_meta_get_ptr(&cursor_); + /** Get untyped pointer to value for writing */ + void* get_write_ptr() { + return ecs_meta_get_write_ptr(&cursor_); + } + + /** Get untyped pointer to value for reading */ + const void* get_read_ptr() { + return ecs_meta_get_read_ptr(&cursor_); } /** Set boolean value */ diff --git a/include/flecs/addons/meta.h b/include/flecs/addons/meta.h index bc259c0e4b..f64bbc2b62 100644 --- a/include/flecs/addons/meta.h +++ b/include/flecs/addons/meta.h @@ -664,7 +664,7 @@ ecs_meta_cursor_t ecs_meta_cursor( * @return A pointer to the current field for writing. */ FLECS_API -void* ecs_meta_get_ptr( +void* ecs_meta_get_write_ptr( ecs_meta_cursor_t *cursor); /** Get pointer to current field for reading. diff --git a/src/addons/meta/cursor.c b/src/addons/meta/cursor.c index 61ba1730fe..f4bd58a061 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -264,7 +264,7 @@ ecs_meta_cursor_t ecs_meta_cursor( return (ecs_meta_cursor_t){ 0 }; } -void* ecs_meta_get_ptr( +void* ecs_meta_get_write_ptr( ecs_meta_cursor_t *cursor) { return flecs_meta_cursor_get_write_ptr(cursor->world, @@ -1834,26 +1834,26 @@ bool ecs_meta_get_bool( ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); } switch(op->kind) { - case EcsOpBool: return *(ecs_bool_t*)ptr; - case EcsOpI8: return *(ecs_i8_t*)ptr != 0; - case EcsOpU8: return *(ecs_u8_t*)ptr != 0; - case EcsOpChar: return *(ecs_char_t*)ptr != 0; - case EcsOpByte: return *(ecs_u8_t*)ptr != 0; - case EcsOpI16: return *(ecs_i16_t*)ptr != 0; - case EcsOpU16: return *(ecs_u16_t*)ptr != 0; - case EcsOpI32: return *(ecs_i32_t*)ptr != 0; - case EcsOpU32: return *(ecs_u32_t*)ptr != 0; - case EcsOpI64: return *(ecs_i64_t*)ptr != 0; - case EcsOpU64: return *(ecs_u64_t*)ptr != 0; - case EcsOpIPtr: return *(ecs_iptr_t*)ptr != 0; - case EcsOpUPtr: return *(ecs_uptr_t*)ptr != 0; - case EcsOpF32: return ECS_NEQZERO(*(ecs_f32_t*)ptr); - case EcsOpF64: return ECS_NEQZERO(*(ecs_f64_t*)ptr); - case EcsOpString: return *(const char**)ptr != NULL; - case EcsOpEnum: return *(ecs_i32_t*)ptr != 0; - case EcsOpBitmask: return *(ecs_u32_t*)ptr != 0; - case EcsOpEntity: return *(ecs_entity_t*)ptr != 0; - case EcsOpId: return *(ecs_id_t*)ptr != 0; + case EcsOpBool: return *(const ecs_bool_t*)ptr; + case EcsOpI8: return *(const ecs_i8_t*)ptr != 0; + case EcsOpU8: return *(const ecs_u8_t*)ptr != 0; + case EcsOpChar: return *(const ecs_char_t*)ptr != 0; + case EcsOpByte: return *(const ecs_u8_t*)ptr != 0; + case EcsOpI16: return *(const ecs_i16_t*)ptr != 0; + case EcsOpU16: return *(const ecs_u16_t*)ptr != 0; + case EcsOpI32: return *(const ecs_i32_t*)ptr != 0; + case EcsOpU32: return *(const ecs_u32_t*)ptr != 0; + case EcsOpI64: return *(const ecs_i64_t*)ptr != 0; + case EcsOpU64: return *(const ecs_u64_t*)ptr != 0; + case EcsOpIPtr: return *(const ecs_iptr_t*)ptr != 0; + case EcsOpUPtr: return *(const ecs_uptr_t*)ptr != 0; + case EcsOpF32: return ECS_NEQZERO(*(const ecs_f32_t*)ptr); + case EcsOpF64: return ECS_NEQZERO(*(const ecs_f64_t*)ptr); + case EcsOpString: return *(const char* const *)ptr != NULL; + case EcsOpEnum: return *(const ecs_i32_t*)ptr != 0; + case EcsOpBitmask: return *(const ecs_u32_t*)ptr != 0; + case EcsOpEntity: return *(const ecs_entity_t*)ptr != 0; + case EcsOpId: return *(const ecs_id_t*)ptr != 0; case EcsOpOpaque: { /* If opaque type knows how to convert to bool, retrieve it. Otherwise, fallback to default case (error). */ @@ -1892,7 +1892,7 @@ char ecs_meta_get_char( } switch(op->kind) { case EcsOpChar: - return *(ecs_char_t*)ptr != 0; + return *(const ecs_char_t*)ptr != 0; case EcsOpOpaque: { /* If opaque type knows how to convert to char, retrieve it. Otherwise, fallback to default case (error). */ @@ -1961,7 +1961,7 @@ int64_t ecs_meta_get_int( case EcsOpUPtr: return flecs_uto(int64_t, *(const ecs_uptr_t*)ptr); case EcsOpF32: return (int64_t)*(const ecs_f32_t*)ptr; case EcsOpF64: return (int64_t)*(const ecs_f64_t*)ptr; - case EcsOpString: return atoi(*(const char**)ptr); + case EcsOpString: return atoi(*(const char* const *)ptr); case EcsOpEnum: return *(const ecs_i32_t*)ptr; case EcsOpBitmask: return *(const ecs_u32_t*)ptr; case EcsOpEntity: @@ -2008,22 +2008,22 @@ uint64_t ecs_meta_get_uint( ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); } switch(op->kind) { - case EcsOpBool: return *(ecs_bool_t*)ptr; + case EcsOpBool: return *(const ecs_bool_t*)ptr; case EcsOpI8: return flecs_ito(uint64_t, *(const ecs_i8_t*)ptr); - case EcsOpU8: return *(ecs_u8_t*)ptr; + case EcsOpU8: return *(const ecs_u8_t*)ptr; case EcsOpChar: return flecs_ito(uint64_t, *(const ecs_char_t*)ptr); case EcsOpByte: return flecs_ito(uint64_t, *(const ecs_u8_t*)ptr); case EcsOpI16: return flecs_ito(uint64_t, *(const ecs_i16_t*)ptr); - case EcsOpU16: return *(ecs_u16_t*)ptr; + case EcsOpU16: return *(const ecs_u16_t*)ptr; case EcsOpI32: return flecs_ito(uint64_t, *(const ecs_i32_t*)ptr); - case EcsOpU32: return *(ecs_u32_t*)ptr; + case EcsOpU32: return *(const ecs_u32_t*)ptr; case EcsOpI64: return flecs_ito(uint64_t, *(const ecs_i64_t*)ptr); - case EcsOpU64: return *(ecs_u64_t*)ptr; + case EcsOpU64: return *(const ecs_u64_t*)ptr; case EcsOpIPtr: return flecs_ito(uint64_t, *(const ecs_i64_t*)ptr); - case EcsOpUPtr: return *(ecs_uptr_t*)ptr; + case EcsOpUPtr: return *(const ecs_uptr_t*)ptr; case EcsOpF32: return flecs_ito(uint64_t, *(const ecs_f32_t*)ptr); case EcsOpF64: return flecs_ito(uint64_t, *(const ecs_f64_t*)ptr); - case EcsOpString: return flecs_ito(uint64_t, atoi(*(const char**)ptr)); + case EcsOpString: return flecs_ito(uint64_t, atoi(*(const char* const *)ptr)); case EcsOpEnum: return flecs_ito(uint64_t, *(const ecs_i32_t*)ptr); case EcsOpBitmask: return *(const ecs_u32_t*)ptr; case EcsOpEntity: return *(const ecs_entity_t*)ptr; @@ -2136,7 +2136,7 @@ const char* ecs_meta_get_string( ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); } switch(op->kind) { - case EcsOpString: return *(const char**)ptr; + case EcsOpString: return *(const char* const*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to string, retrieve it. Otherwise, fallback to default case (error). */ @@ -2190,7 +2190,7 @@ ecs_entity_t ecs_meta_get_entity( ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); } switch(op->kind) { - case EcsOpEntity: return *(ecs_entity_t*)ptr; + case EcsOpEntity: return *(const ecs_entity_t*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to entity, retrieve it. Otherwise, fallback to default case (error). */ @@ -2243,8 +2243,8 @@ ecs_id_t ecs_meta_get_id( ecs_throw(ECS_OUT_OF_RANGE, "cannot find element"); } switch(op->kind) { - case EcsOpEntity: return *(ecs_id_t*)ptr; /* Entities are valid ids */ - case EcsOpId: return *(ecs_id_t*)ptr; + case EcsOpEntity: return *(const ecs_id_t*)ptr; /* Entities are valid ids */ + case EcsOpId: return *(const ecs_id_t*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to id, retrieve it. Otherwise, fallback to default case (error). */ diff --git a/src/addons/metrics.c b/src/addons/metrics.c index ec66b59e7a..599e1f9886 100644 --- a/src/addons/metrics.c +++ b/src/addons/metrics.c @@ -484,7 +484,7 @@ int flecs_member_metric_init( id = desc->id; member_type = ecs_meta_get_type(&cur); - offset = (uintptr_t)ecs_meta_get_ptr(&cur); + offset = (uintptr_t)ecs_meta_get_write_ptr(&cur); member = ecs_meta_get_member_id(&cur); } else { const EcsMember *m = ecs_get(world, desc->member, EcsMember); diff --git a/src/addons/script/expr/visit_type.c b/src/addons/script/expr/visit_type.c index dfed363071..0884db9f4c 100644 --- a/src/addons/script/expr/visit_type.c +++ b/src/addons/script/expr/visit_type.c @@ -744,7 +744,7 @@ int flecs_expr_initializer_visit_type( } if (!is_opaque) { - elem->offset = (uintptr_t)ecs_meta_get_ptr(cur); + elem->offset = (uintptr_t)ecs_meta_get_write_ptr(cur); } } @@ -1206,7 +1206,7 @@ int flecs_expr_member_visit_type( const EcsMember *m = ecs_get(world, ecs_meta_get_member_id(cur), EcsMember); ecs_assert(m != NULL, ECS_INTERNAL_ERROR, NULL); #endif - node->offset = (uintptr_t)ecs_meta_get_ptr(cur); + node->offset = (uintptr_t)ecs_meta_get_write_ptr(cur); return 0; error: diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index c7236a50ff..d2fe66ffa4 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3305,14 +3305,10 @@ void Cursor_opaque_set_int_vec(void) { test_int(ecs_meta_get_int(&cur), 20); test_int(0, ecs_meta_next(&cur)); test_int(ecs_meta_get_int(&cur), 30); - - /* set up an abort handler for the following operations */ - install_test_abort(); - test_expect_abort(); + test_assert(ecs_meta_get_read_ptr(&cur) != NULL); /* still points to a valid item */ test_int(0, ecs_meta_next(&cur)); - /* Expect the next read to fail since we are trying to read a non-existing element */ - ecs_meta_get_int(&cur); + test_assert(ecs_meta_get_read_ptr(&cur) == NULL); /* now we are out of bounds */ ecs_os_free(v.array); @@ -3567,7 +3563,7 @@ typedef struct { int32_t y; } OpaqueStruct; -static void* OpaqueStruct_member(void *ptr, const char *member) { +static void* OpaqueStruct_ensure_member(void *ptr, const char *member) { OpaqueStruct *data = ptr; if (!strcmp(member, "x")) { return &data->x; @@ -3578,6 +3574,17 @@ static void* OpaqueStruct_member(void *ptr, const char *member) { } } +static const void* OpaqueStruct_get_member(const void *ptr, const char *member) { + const 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(); @@ -3591,7 +3598,8 @@ void Cursor_opaque_set_struct(void) { {"y", .type = ecs_id(ecs_i32_t)} } }), - .type.ensure_member = OpaqueStruct_member + .type.ensure_member = OpaqueStruct_ensure_member, + .type.get_member = OpaqueStruct_get_member }); OpaqueStruct v = { 0 }; @@ -3599,8 +3607,10 @@ void Cursor_opaque_set_struct(void) { 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(ecs_meta_get_int(&cur), 10); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); + test_int(ecs_meta_get_int(&cur), 20); test_int(0, ecs_meta_pop(&cur)); test_int(v.x, 10); test_int(v.y, 20); @@ -3609,8 +3619,10 @@ void Cursor_opaque_set_struct(void) { 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(ecs_meta_get_int(&cur), 30); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 40)); + test_int(ecs_meta_get_int(&cur), 40); test_int(0, ecs_meta_pop(&cur)); test_int(v.x, 40); test_int(v.y, 30); @@ -3625,7 +3637,7 @@ typedef struct { Position stop; } OpaqueNested; -static void* OpaqueNested_member(void *ptr, const char *member) { +static void* OpaqueNested_ensure_member(void *ptr, const char *member) { OpaqueNested *data = ptr; if (!strcmp(member, "start")) { return &data->start; @@ -3636,6 +3648,17 @@ static void* OpaqueNested_member(void *ptr, const char *member) { } } +static const void* OpaqueNested_get_member(const void *ptr, const char *member) { + const 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(); @@ -3658,7 +3681,8 @@ void Cursor_opaque_set_nested_struct(void) { {"stop", .type = ecs_id(Position)} } }), - .type.ensure_member = OpaqueNested_member + .type.ensure_member = OpaqueNested_ensure_member, + .type.get_member = OpaqueNested_get_member, }); OpaqueNested v = { 0 }; @@ -3668,15 +3692,19 @@ void Cursor_opaque_set_nested_struct(void) { 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(ecs_meta_get_int(&cur), 10); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); + test_int(ecs_meta_get_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(ecs_meta_get_int(&cur), 30); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 40)); + test_int(ecs_meta_get_int(&cur), 40); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); @@ -3691,15 +3719,19 @@ void Cursor_opaque_set_nested_struct(void) { 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(ecs_meta_get_int(&cur), 50); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 60)); + test_int(ecs_meta_get_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(ecs_meta_get_int(&cur), 70); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 80)); + test_int(ecs_meta_get_int(&cur), 80); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); @@ -3718,7 +3750,7 @@ typedef struct { OpaqueStruct stop; } OpaqueNestedOpaque; -static void* OpaqueNestedOpaque_member(void *ptr, const char *member) { +static void* OpaqueNestedOpaque_ensure_member(void *ptr, const char *member) { OpaqueNestedOpaque *data = ptr; if (!strcmp(member, "start")) { return &data->start; @@ -3729,6 +3761,17 @@ static void* OpaqueNestedOpaque_member(void *ptr, const char *member) { } } +static const void* OpaqueNestedOpaque_get_member(const void *ptr, const char *member) { + const 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(); @@ -3743,7 +3786,8 @@ void Cursor_opaque_set_nested_opaque_struct(void) { {"y", .type = ecs_id(ecs_i32_t)} } }), - .type.ensure_member = OpaqueStruct_member + .type.ensure_member = OpaqueStruct_ensure_member, + .type.get_member = OpaqueStruct_get_member, }); ecs_opaque(world, { @@ -3754,7 +3798,8 @@ void Cursor_opaque_set_nested_opaque_struct(void) { {"stop", .type = ecs_id(OpaqueStruct)} } }), - .type.ensure_member = OpaqueNestedOpaque_member + .type.ensure_member = OpaqueNestedOpaque_ensure_member, + .type.get_member = OpaqueNestedOpaque_get_member }); OpaqueNestedOpaque v = { 0 }; @@ -3764,15 +3809,19 @@ void Cursor_opaque_set_nested_opaque_struct(void) { 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(ecs_meta_get_int(&cur), 10); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 20)); + test_int(ecs_meta_get_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(ecs_meta_get_int(&cur), 30); test_int(0, ecs_meta_member(&cur, "y")); test_int(0, ecs_meta_set_int(&cur, 40)); + test_int(ecs_meta_get_int(&cur), 40); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); @@ -3787,15 +3836,19 @@ void Cursor_opaque_set_nested_opaque_struct(void) { 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(ecs_meta_get_int(&cur), 50); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 60)); + test_int(ecs_meta_get_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(ecs_meta_get_int(&cur), 70); test_int(0, ecs_meta_member(&cur, "x")); test_int(0, ecs_meta_set_int(&cur, 80)); + test_int(ecs_meta_get_int(&cur), 80); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); @@ -4196,7 +4249,8 @@ void Cursor_struct_w_2_opaque_structs(void) { {"y", .type = ecs_id(ecs_i32_t)} } }), - .type.ensure_member = OpaqueStruct_member + .type.ensure_member = OpaqueStruct_ensure_member, + .type.get_member = OpaqueStruct_get_member }); ecs_struct(world, { @@ -4377,7 +4431,8 @@ void Cursor_struct_w_3_opaque_structs(void) { {"y", .type = ecs_id(ecs_i32_t)} } }), - .type.ensure_member = OpaqueStruct_member + .type.ensure_member = OpaqueStruct_ensure_member, + .type.get_member = OpaqueStruct_get_member }); ecs_struct(world, { From b0f21964f9a3187bf8f4a1dc7054a4c8afa03d14 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Thu, 17 Oct 2024 14:36:36 +0200 Subject: [PATCH 09/11] finish tests --- test/meta/src/Cursor.c | 57 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index d2fe66ffa4..811d614594 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -4633,7 +4633,7 @@ void Cursor_struct_w_3_opaque_arrays(void) { ecs_fini(world); } -static void* OpaqueStructIntVec_member(void *ptr, const char *member) { +static void* OpaqueStructIntVec_ensure_member(void *ptr, const char *member) { Struct_w_IntVec *data = ptr; if (!strcmp(member, "foo")) { return &data->foo; @@ -4644,6 +4644,17 @@ static void* OpaqueStructIntVec_member(void *ptr, const char *member) { } } +static const void* OpaqueStructIntVec_get_member(const void *ptr, const char *member) { + const 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(); @@ -4654,6 +4665,7 @@ void Cursor_opaque_struct_w_opaque_vec(void) { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = ecs_id(ecs_i32_t) }), .type.ensure_element = IntVec_ensure, + .type.get_element = IntVec_get, .type.count = IntVec_count, .type.resize = IntVec_resize }); @@ -4668,7 +4680,8 @@ void Cursor_opaque_struct_w_opaque_vec(void) { ecs_opaque(world, { .entity = ecs_id(Struct_w_IntVec), .type.as_type = os, - .type.ensure_member = OpaqueStructIntVec_member, + .type.ensure_member = OpaqueStructIntVec_ensure_member, + .type.get_member = OpaqueStructIntVec_get_member }); Struct_w_IntVec v = {0}; @@ -4677,19 +4690,37 @@ void Cursor_opaque_struct_w_opaque_vec(void) { 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(ecs_meta_get_int(&cur), 10); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 20)); + test_int(ecs_meta_get_int(&cur), 20); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 30)); + test_int(ecs_meta_get_int(&cur), 30); test_int(0, ecs_meta_pop(&cur)); + + const IntVec *vec = ecs_meta_get_read_ptr(&cur); + test_int(vec->array[0], 10); + test_int(vec->array[1], 20); + test_int(vec->array[2], 30); + 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(ecs_meta_get_int(&cur), 40); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 50)); + test_int(ecs_meta_get_int(&cur), 50); test_int(0, ecs_meta_next(&cur)); test_int(0, ecs_meta_set_int(&cur, 60)); + test_int(ecs_meta_get_int(&cur), 60); test_int(0, ecs_meta_pop(&cur)); + + vec = ecs_meta_get_read_ptr(&cur); + test_int(vec->array[0], 40); + test_int(vec->array[1], 50); + test_int(vec->array[2], 60); + test_int(0, ecs_meta_pop(&cur)); test_int(v.foo.count, 3); @@ -4706,7 +4737,15 @@ void Cursor_opaque_struct_w_opaque_vec(void) { ecs_fini(world); } -static void* OpaqueStructElem_member(void *ptr, const char *member) { +static void* OpaqueStructElem_ensure_member(void *ptr, const char *member) { + if (!strcmp(member, "i")) { + return ptr; + } else { + return NULL; + } +} + +static const void* OpaqueStructElem_get_member(const void *ptr, const char *member) { if (!strcmp(member, "i")) { return ptr; } else { @@ -4732,13 +4771,15 @@ void Cursor_opaque_vec_w_opaque_elem(void) { .type.alignment = ECS_ALIGNOF(ecs_i32_t) }), .type.as_type = os, - .type.ensure_member = OpaqueStructElem_member, + .type.ensure_member = OpaqueStructElem_ensure_member, + .type.get_member = OpaqueStructElem_get_member, }); ecs_opaque(world, { .entity = ecs_id(IntVec), .type.as_type = ecs_vector(world, { .type = oelem }), .type.ensure_element = IntVec_ensure, + .type.get_element = IntVec_get, .type.count = IntVec_count, .type.resize = IntVec_resize }); @@ -4749,19 +4790,27 @@ void Cursor_opaque_vec_w_opaque_elem(void) { 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(ecs_meta_get_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(ecs_meta_get_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(ecs_meta_get_int(&cur), 30); test_int(0, ecs_meta_pop(&cur)); test_int(0, ecs_meta_pop(&cur)); + const IntVec *vec = ecs_meta_get_read_ptr(&cur); + test_int(vec->array[0], 10); + test_int(vec->array[1], 20); + test_int(vec->array[2], 30); + test_int(v.count, 3); test_int(v.array[0], 10); test_int(v.array[1], 20); From 293f42e1c69881d8ce162f3fda9ed29ce48b6fc5 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Thu, 17 Oct 2024 19:55:15 +0200 Subject: [PATCH 10/11] test ecs_meta_get_* --- src/addons/meta/cursor.c | 2 +- test/meta/src/Cursor.c | 70 +++++++++++++++++++++++++++++++++++----- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/addons/meta/cursor.c b/src/addons/meta/cursor.c index f4bd58a061..534ad1b31a 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -1892,7 +1892,7 @@ char ecs_meta_get_char( } switch(op->kind) { case EcsOpChar: - return *(const ecs_char_t*)ptr != 0; + return *(const ecs_char_t*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to char, retrieve it. Otherwise, fallback to default case (error). */ diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index 811d614594..5a3e6b39f8 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -8,7 +8,9 @@ void Cursor_set_bool(void) { 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(ecs_meta_get_bool(&cur), true); test_bool(value, true); + ecs_fini(world); } @@ -32,9 +34,10 @@ void Cursor_set_char(void) { 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_ok( ecs_meta_set_char(&cur, 'a') ); - test_int(value, 20); + test_int(ecs_meta_get_char(&cur), 'a'); + test_int(value, 'a'); ecs_fini(world); } @@ -47,6 +50,7 @@ void Cursor_set_i8(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -60,6 +64,7 @@ void Cursor_set_i16(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -73,6 +78,7 @@ void Cursor_set_i32(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -86,6 +92,7 @@ void Cursor_set_i64(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -99,6 +106,7 @@ void Cursor_set_iptr(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -112,6 +120,7 @@ void Cursor_set_u8(void) { 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(ecs_meta_get_uint(&cur), 20); test_uint(value, 20); ecs_fini(world); @@ -125,6 +134,7 @@ void Cursor_set_u16(void) { 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(ecs_meta_get_uint(&cur), 20); test_uint(value, 20); ecs_fini(world); @@ -138,6 +148,7 @@ void Cursor_set_u32(void) { 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(ecs_meta_get_uint(&cur), 20); test_uint(value, 20); ecs_fini(world); @@ -150,6 +161,7 @@ void Cursor_set_u64(void) { 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(ecs_meta_get_uint(&cur), 20); test_uint(value, 20); } @@ -157,6 +169,7 @@ void Cursor_set_u64(void) { 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(ecs_meta_get_uint(&cur), 2366700781656087864); test_uint(value, 2366700781656087864); } @@ -170,7 +183,8 @@ void Cursor_set_uptr(void) { 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(ecs_meta_get_uint(&cur), 20); test_uint(value, 20); ecs_fini(world); @@ -184,6 +198,7 @@ void Cursor_set_float(void) { 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(ecs_meta_get_float(&cur), 20.5); test_flt(value, 20.5); ecs_fini(world); @@ -197,6 +212,7 @@ void Cursor_set_double(void) { 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(ecs_meta_get_float(&cur), 20.5); test_flt(value, 20.5); ecs_fini(world); @@ -210,6 +226,7 @@ void Cursor_set_string(void) { 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(ecs_meta_get_string(&cur), "HelloWorld"); test_str(value, "HelloWorld"); ecs_os_free(value); @@ -238,6 +255,7 @@ void Cursor_set_string_to_null(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_null(&cur) ); + test_str(ecs_meta_get_string(&cur), NULL); test_str(value, NULL); ecs_os_free(value); @@ -252,6 +270,7 @@ void Cursor_set_entity(void) { 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(ecs_meta_get_entity(&cur), EcsFlecs); test_uint(value, EcsFlecs); ecs_fini(world); @@ -265,6 +284,7 @@ void Cursor_set_entity_to_number(void) { 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(ecs_meta_get_entity(&cur), 500); test_uint(value, 500); ecs_fini(world); @@ -278,6 +298,7 @@ void Cursor_set_entity_to_0(void) { 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(ecs_meta_get_entity(&cur), 0); test_uint(value, 0); ecs_fini(world); @@ -289,8 +310,9 @@ void Cursor_set_id(void) { ecs_id_t value = 0; ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); - test_ok( ecs_meta_set_uint(&cur, 500) ); + test_ok( ecs_meta_set_id(&cur, 500) ); + test_uint(ecs_meta_get_id(&cur), 500); test_uint(value, 500); ecs_fini(world); @@ -304,6 +326,7 @@ void Cursor_set_id_to_number(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_ok( ecs_meta_set_uint(&cur, 500) ); + test_uint(ecs_meta_get_id(&cur), 500); test_uint(value, 500); ecs_fini(world); @@ -317,6 +340,7 @@ void Cursor_set_id_to_0(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_ok( ecs_meta_set_uint(&cur, 0) ); + test_uint(ecs_meta_get_id(&cur), 0); test_uint(value, 0); ecs_fini(world); @@ -342,6 +366,7 @@ void Cursor_set_enum(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_set_int(&cur, Green) ); + test_uint(ecs_meta_get_int(&cur), Green); test_int(value, Green); ecs_fini(world); @@ -365,6 +390,7 @@ void Cursor_set_bitmask(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, t, &value); test_ok( ecs_meta_set_uint(&cur, Bacon | Lettuce) ); + test_int(ecs_meta_get_uint(&cur), Bacon | Lettuce); test_uint(value, Bacon | Lettuce); ecs_fini(world); @@ -378,6 +404,7 @@ void Cursor_set_signed_as_unsigned(void) { 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(ecs_meta_get_int(&cur), 10); test_int(value, 10); ecs_fini(world); @@ -391,7 +418,8 @@ void Cursor_set_unsigned_as_signed(void) { 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); + test_uint(ecs_meta_get_uint(&cur), 10); + test_uint(value, 10); ecs_fini(world); } @@ -405,6 +433,7 @@ void Cursor_set_signed_as_unsigned_out_of_range(void) { 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(ecs_meta_get_int(&cur), 0); test_int(value, 0); ecs_fini(world); @@ -419,6 +448,7 @@ void Cursor_set_unsigned_as_signed_out_of_range(void) { 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(ecs_meta_get_int(&cur), 0); test_int(value, 0); ecs_fini(world); @@ -433,6 +463,7 @@ void Cursor_set_string_to_null_as_signed(void) { test_ok( ecs_meta_set_int(&cur, 0) ); test_str(value, "0"); + test_str(ecs_meta_get_string(&cur), "0"); ecs_os_free(value); ecs_fini(world); @@ -447,6 +478,7 @@ void Cursor_set_string_to_null_as_unsigned(void) { test_ok( ecs_meta_set_uint(&cur, 0) ); test_str(value, "0"); + test_str(ecs_meta_get_string(&cur), "0"); ecs_os_free(value); ecs_fini(world); @@ -641,6 +673,7 @@ void Cursor_set_entity_as_signed(void) { 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(ecs_meta_get_uint(&cur), e); test_uint(value, e); ecs_fini(world); @@ -655,6 +688,7 @@ void Cursor_set_entity_as_unsigned(void) { 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(ecs_meta_get_uint(&cur), e); test_uint(value, e); ecs_fini(world); @@ -669,6 +703,7 @@ void Cursor_set_entity_as_signed_out_of_range(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_entity_t), &value); test_fail( ecs_meta_set_int(&cur, -10) ); + test_int(ecs_meta_get_uint(&cur), 0); test_uint(value, 0); ecs_fini(world); @@ -683,6 +718,7 @@ void Cursor_set_id_as_signed(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_ok( ecs_meta_set_int(&cur, (int64_t)e) ); + test_uint(ecs_meta_get_id(&cur), e); test_uint(value, e); ecs_fini(world); @@ -697,6 +733,7 @@ void Cursor_set_id_as_unsigned(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_ok( ecs_meta_set_uint(&cur, e) ); + test_uint(ecs_meta_get_id(&cur), e); test_uint(value, e); ecs_fini(world); @@ -711,6 +748,7 @@ void Cursor_set_id_as_signed_out_of_range(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_fail( ecs_meta_set_int(&cur, -10) ); + test_uint(ecs_meta_get_id(&cur), 0); test_uint(value, 0); ecs_fini(world); @@ -729,6 +767,7 @@ void Cursor_set_str_to_bool(void) { cur = ecs_meta_cursor(world, ecs_id(ecs_bool_t), &value); test_ok( ecs_meta_set_string(&cur, "false") ); + test_bool(ecs_meta_get_bool(&cur), false); test_bool(value, false); ecs_fini(world); @@ -740,9 +779,9 @@ void Cursor_set_str_to_char(void) { 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_ok( ecs_meta_set_string(&cur, "abc") ); - test_bool(value, 10); + test_int(value, 'a'); ecs_fini(world); } @@ -753,7 +792,7 @@ void Cursor_set_str_literal_to_char(void) { 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_ok( ecs_meta_set_string_literal(&cur, "\"abc\"") ); test_int(value, 'a'); @@ -768,6 +807,7 @@ void Cursor_set_str_to_i8(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -781,6 +821,7 @@ void Cursor_set_str_to_i16(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -794,6 +835,7 @@ void Cursor_set_str_to_i32(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); ecs_fini(world); @@ -806,6 +848,7 @@ void Cursor_set_str_to_i64(void) { 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(ecs_meta_get_int(&cur), 20); test_int(value, 20); } @@ -813,6 +856,7 @@ void Cursor_set_str_to_i64(void) { 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(ecs_meta_get_int(&cur), 2366700781656087864); test_int(value, 2366700781656087864); } @@ -826,6 +870,7 @@ void Cursor_set_str_to_u64(void) { 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(ecs_meta_get_uint(&cur), 20); test_uint(value, 20); } @@ -833,6 +878,7 @@ void Cursor_set_str_to_u64(void) { 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(ecs_meta_get_uint(&cur), 2366700781656087864); test_uint(value, 2366700781656087864); } @@ -847,6 +893,7 @@ void Cursor_set_str_to_f32(void) { 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(ecs_meta_get_float(&cur), 20.5); test_flt(value, 20.5); ecs_fini(world); @@ -860,6 +907,7 @@ void Cursor_set_str_to_f64(void) { 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(ecs_meta_get_float(&cur), 20.5); test_flt(value, 20.5); ecs_fini(world); @@ -873,6 +921,7 @@ void Cursor_set_str_to_entity(void) { 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(ecs_meta_get_entity(&cur), EcsFlecsCore); test_uint(value, EcsFlecsCore); ecs_fini(world); @@ -886,6 +935,7 @@ void Cursor_set_str_to_id(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_ok( ecs_meta_set_string(&cur, "flecs.core") ); + test_uint(ecs_meta_get_id(&cur), EcsFlecsCore); test_uint(value, EcsFlecsCore); ecs_fini(world); @@ -901,6 +951,7 @@ void Cursor_set_str_to_invalid_bool(void) { 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(ecs_meta_get_bool(&cur), false); test_bool(value, false); ecs_fini(world); @@ -916,6 +967,7 @@ void Cursor_set_str_to_invalid_entity(void) { 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(ecs_meta_get_entity(&cur), 0); test_uint(value, 0); ecs_fini(world); @@ -931,6 +983,7 @@ void Cursor_set_str_to_invalid_id(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_id_t), &value); test_fail( ecs_meta_set_string(&cur, "flops.core") ); + test_uint(ecs_meta_get_id(&cur), 0); test_uint(value, 0); ecs_fini(world); @@ -958,6 +1011,7 @@ void Cursor_struct_set_i32(void) { test_ok( ecs_meta_push(&cur) ); test_ok( ecs_meta_set_int(&cur, 10) ); + test_int(ecs_meta_get_int(&cur), 10); test_int(value.x, 10); ecs_fini(world); From d7ade02e62dd808e5e548bc3225c71f8287abe57 Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Thu, 17 Oct 2024 20:08:15 +0200 Subject: [PATCH 11/11] -- getter interface for collections bake --strict --- distr/flecs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distr/flecs.c b/distr/flecs.c index cb7ef777d8..36cbdff42a 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -50122,7 +50122,7 @@ char ecs_meta_get_char( } switch(op->kind) { case EcsOpChar: - return *(const ecs_char_t*)ptr != 0; + return *(const ecs_char_t*)ptr; case EcsOpOpaque: { /* If opaque type knows how to convert to char, retrieve it. Otherwise, fallback to default case (error). */