From 6e74e263e64d88a24136ab0cadf17ebafe95554b 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 8ecbfdac9a1cc21388a73b31b235228d5c2d3ed0 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 17d6439dce..26114f3957 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -1748,9 +1748,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: @@ -1775,9 +1784,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: @@ -1842,9 +1860,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: @@ -1886,9 +1913,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: @@ -1945,7 +1981,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: @@ -1958,30 +1994,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( @@ -1993,21 +2017,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 */ } @@ -2053,9 +2067,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: @@ -2095,9 +2118,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 8f79b2332b..0ea3fca3f4 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -2942,10 +2942,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) { @@ -2957,7 +2955,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 eaae780b02e7950cff2822029049fb633146c30f 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 0ea3fca3f4..7eea7eda89 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -2806,8 +2806,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) @@ -2827,10 +2831,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(); @@ -2839,7 +2851,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 }; @@ -2847,8 +2860,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); } @@ -2861,7 +2876,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 }; @@ -2869,8 +2885,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); } @@ -2883,7 +2901,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 }; @@ -2891,8 +2910,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); } @@ -2905,7 +2926,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 }; @@ -2913,8 +2935,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); } @@ -2927,7 +2951,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 }; @@ -2935,17 +2960,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(); @@ -2978,7 +3000,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 }; @@ -2988,8 +3011,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 65aba35abf9a0443c93d8a094ca3d3746a4e6116 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 b7386f611b..b71889e073 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -49205,9 +49205,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: @@ -49232,9 +49241,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: @@ -49299,9 +49317,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: @@ -49343,9 +49370,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: @@ -49402,7 +49438,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: @@ -49415,30 +49451,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( @@ -49450,21 +49474,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 */ } @@ -49510,9 +49524,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: @@ -49543,7 +49566,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); @@ -49552,9 +49575,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: @@ -49626,10 +49658,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 */ @@ -49671,7 +49701,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 dc7e065211..a7eb318a1c 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -15464,6 +15464,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; @@ -15929,6 +15966,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); @@ -19098,6 +19136,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 26114f3957..2cfc74dbf9 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -2109,7 +2109,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 7eea7eda89..10934217a0 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3027,7 +3027,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 }; @@ -3037,8 +3038,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 23bc1d161b4095907c7a6e47a65c47d882ab509d 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 d736524f27..0a79cdb840 100644 --- a/test/meta/project.json +++ b/test/meta/project.json @@ -432,14 +432,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 10934217a0..03e38c0f25 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -2843,7 +2843,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); @@ -2868,7 +2868,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); @@ -2893,7 +2893,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); @@ -2918,7 +2918,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); @@ -2943,7 +2943,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); @@ -2992,7 +2992,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); @@ -3019,7 +3019,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 4845f069e9..d23169f5f1 100644 --- a/test/meta/src/main.c +++ b/test/meta/src/main.c @@ -407,14 +407,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); @@ -2554,36 +2554,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 74b273f1aa0162d1b2d3e1725c95cd111a49729a 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 b71889e073..66ffdb5b9d 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -49657,6 +49657,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); @@ -49701,7 +49708,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 4cfda95b7982420912babd77239d6ec4c0f872f3 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 2cfc74dbf9..7925b2f0bd 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -123,9 +123,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) { @@ -169,6 +169,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, @@ -220,7 +266,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)); } @@ -396,7 +449,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); @@ -879,7 +932,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); @@ -919,7 +972,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); @@ -976,7 +1029,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); @@ -1029,7 +1082,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); @@ -1081,7 +1134,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: @@ -1182,7 +1235,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); @@ -1297,7 +1350,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: @@ -1485,7 +1538,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); ecs_size_t len = ecs_os_strlen(value); if (value[0] != '\"' || value[len - 1] != '\"') { @@ -1553,7 +1606,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: @@ -1613,7 +1666,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: @@ -1670,7 +1723,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); @@ -1726,7 +1779,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; @@ -1780,7 +1836,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; @@ -1832,7 +1891,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; @@ -1891,7 +1953,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); @@ -1993,7 +2058,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). */ @@ -2013,7 +2081,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: { @@ -2064,7 +2135,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: { @@ -2114,7 +2188,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 03e38c0f25..2392ec230b 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3065,6 +3065,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) { @@ -3087,6 +3095,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 }); @@ -3107,6 +3116,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 7abc4358a406adfbf10f9b20421f9f8a93ee6e55 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 | 207 ++++++++++++------ distr/flecs.h | 43 +++- .../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.c | 14 +- test/meta/src/Cursor.c | 85 +++++-- 8 files changed, 302 insertions(+), 130 deletions(-) diff --git a/distr/flecs.c b/distr/flecs.c index 66ffdb5b9d..a7d7efa275 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -24867,7 +24867,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); @@ -47580,9 +47580,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) { @@ -47626,6 +47626,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, @@ -47674,10 +47720,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)); } @@ -47853,7 +47906,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); @@ -48336,7 +48389,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); @@ -48376,7 +48429,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); @@ -48433,7 +48486,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); @@ -48486,7 +48539,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); @@ -48538,7 +48591,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: @@ -48639,7 +48692,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); @@ -48754,7 +48807,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: @@ -48942,7 +48995,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); ecs_size_t len = ecs_os_strlen(value); if (value[0] != '\"' || value[len - 1] != '\"') { @@ -49010,7 +49063,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: @@ -49070,7 +49123,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: @@ -49127,7 +49180,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); @@ -49183,28 +49236,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). */ @@ -49237,10 +49293,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). */ @@ -49289,7 +49348,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; @@ -49306,7 +49368,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: @@ -49348,24 +49410,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; @@ -49450,7 +49515,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). */ @@ -49470,9 +49538,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). */ @@ -49521,9 +49592,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). */ @@ -49571,10 +49645,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). */ @@ -55050,7 +55127,7 @@ ecs_value_t flecs_dotresolve_var( } return (ecs_value_t){ - .ptr = ecs_meta_get_ptr(&cur), + .ptr = ecs_meta_get_write_ptr(&cur), .type = ecs_meta_get_type(&cur) }; } @@ -55066,7 +55143,7 @@ int flecs_meta_call( const char *function) { ecs_entity_t type = ecs_meta_get_type(cur); - void *value_ptr = ecs_meta_get_ptr(cur); + void *value_ptr = ecs_meta_get_write_ptr(cur); if (!ecs_os_strcmp(function, "parent")) { if (type != ecs_id(ecs_entity_t)) { @@ -55830,7 +55907,7 @@ const char* flecs_funccall_parse( } ecs_entity_t type = ecs_meta_get_type(cur); - value->ptr = ecs_meta_get_ptr(cur); + value->ptr = ecs_meta_get_write_ptr(cur); value->type = type; ptr += 2; @@ -55944,7 +56021,7 @@ const char* flecs_script_expr_run( out = &result; } else { temp_result.type = ecs_meta_get_type(&cur); - temp_result.ptr = ecs_meta_get_ptr(&cur); + temp_result.ptr = ecs_meta_get_write_ptr(&cur); out = &temp_result; } @@ -56200,7 +56277,7 @@ const char* flecs_script_expr_run( } result.type = ecs_meta_get_type(&member_cur); - result.ptr = ecs_meta_get_ptr(&member_cur); + result.ptr = ecs_meta_get_write_ptr(&member_cur); } } } @@ -56223,7 +56300,7 @@ const char* flecs_script_expr_run( out = &result; } else { ecs_entity_t cur_type = ecs_meta_get_type(&cur); - void *cur_ptr = ecs_meta_get_ptr(&cur); + void *cur_ptr = ecs_meta_get_write_ptr(&cur); rvalue.type = cur_type; rvalue.ptr = cur_ptr; temp_out.type = cur_type; @@ -56255,7 +56332,7 @@ const char* flecs_script_expr_run( * temporary storage, and initialize the result value * for the binary operation with the current cursor */ ecs_entity_t cur_type = ecs_meta_get_type(&cur); - void *cur_ptr = ecs_meta_get_ptr(&cur); + void *cur_ptr = ecs_meta_get_write_ptr(&cur); lvalue.type = cur_type; lvalue.ptr = flecs_expr_value_new(stack, cur_type); ecs_value_copy(world, cur_type, lvalue.ptr, cur_ptr); diff --git a/distr/flecs.h b/distr/flecs.h index a7eb318a1c..5f3f2daf1e 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -15501,6 +15501,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; @@ -15655,13 +15665,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. @@ -18874,7 +18893,7 @@ struct cursor { /** Get untyped pointer to value */ void* get_ptr() { - return ecs_meta_get_ptr(&cursor_); + return ecs_meta_get_write_ptr(&cursor_); } /** Set boolean value */ @@ -19202,6 +19221,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 7925b2f0bd..9db30e8cd3 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -263,7 +263,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, @@ -1784,26 +1784,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). */ @@ -1842,7 +1842,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). */ @@ -1911,7 +1911,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: @@ -1958,22 +1958,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; @@ -2086,7 +2086,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). */ @@ -2140,7 +2140,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). */ @@ -2193,8 +2193,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 1e31f55775..219ddf38e7 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.c b/src/addons/script/expr.c index c0cafe8880..1cd8bc96a1 100644 --- a/src/addons/script/expr.c +++ b/src/addons/script/expr.c @@ -464,7 +464,7 @@ ecs_value_t flecs_dotresolve_var( } return (ecs_value_t){ - .ptr = ecs_meta_get_ptr(&cur), + .ptr = ecs_meta_get_write_ptr(&cur), .type = ecs_meta_get_type(&cur) }; } @@ -480,7 +480,7 @@ int flecs_meta_call( const char *function) { ecs_entity_t type = ecs_meta_get_type(cur); - void *value_ptr = ecs_meta_get_ptr(cur); + void *value_ptr = ecs_meta_get_write_ptr(cur); if (!ecs_os_strcmp(function, "parent")) { if (type != ecs_id(ecs_entity_t)) { @@ -1244,7 +1244,7 @@ const char* flecs_funccall_parse( } ecs_entity_t type = ecs_meta_get_type(cur); - value->ptr = ecs_meta_get_ptr(cur); + value->ptr = ecs_meta_get_write_ptr(cur); value->type = type; ptr += 2; @@ -1358,7 +1358,7 @@ const char* flecs_script_expr_run( out = &result; } else { temp_result.type = ecs_meta_get_type(&cur); - temp_result.ptr = ecs_meta_get_ptr(&cur); + temp_result.ptr = ecs_meta_get_write_ptr(&cur); out = &temp_result; } @@ -1614,7 +1614,7 @@ const char* flecs_script_expr_run( } result.type = ecs_meta_get_type(&member_cur); - result.ptr = ecs_meta_get_ptr(&member_cur); + result.ptr = ecs_meta_get_write_ptr(&member_cur); } } } @@ -1637,7 +1637,7 @@ const char* flecs_script_expr_run( out = &result; } else { ecs_entity_t cur_type = ecs_meta_get_type(&cur); - void *cur_ptr = ecs_meta_get_ptr(&cur); + void *cur_ptr = ecs_meta_get_write_ptr(&cur); rvalue.type = cur_type; rvalue.ptr = cur_ptr; temp_out.type = cur_type; @@ -1669,7 +1669,7 @@ const char* flecs_script_expr_run( * temporary storage, and initialize the result value * for the binary operation with the current cursor */ ecs_entity_t cur_type = ecs_meta_get_type(&cur); - void *cur_ptr = ecs_meta_get_ptr(&cur); + void *cur_ptr = ecs_meta_get_write_ptr(&cur); lvalue.type = cur_type; lvalue.ptr = flecs_expr_value_new(stack, cur_type); ecs_value_copy(world, cur_type, lvalue.ptr, cur_ptr); diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index 2392ec230b..cbaa3323bd 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -3123,14 +3123,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); @@ -3385,7 +3381,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; @@ -3396,6 +3392,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(); @@ -3409,7 +3416,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 }; @@ -3417,8 +3425,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); @@ -3427,8 +3437,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); @@ -3443,7 +3455,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; @@ -3454,6 +3466,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(); @@ -3476,7 +3499,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 }; @@ -3486,15 +3510,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)); @@ -3509,15 +3537,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)); @@ -3536,7 +3568,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; @@ -3547,6 +3579,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(); @@ -3561,7 +3604,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, { @@ -3572,7 +3616,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 }; @@ -3582,15 +3627,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)); @@ -3605,15 +3654,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)); @@ -4014,7 +4067,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, { @@ -4195,7 +4249,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 c115666a9ffdeb2f1c84478f082b0442d7db8c1c 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 --- distr/flecs.h | 9 +++++-- test/meta/src/Cursor.c | 57 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/distr/flecs.h b/distr/flecs.h index 5f3f2daf1e..4376e9eefb 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -18891,11 +18891,16 @@ struct cursor { /** Get unit of value */ flecs::entity get_unit() const; - /** Get untyped pointer to value */ - void* get_ptr() { + /** 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 */ int set_bool(bool value) { return ecs_meta_set_bool(&cursor_, value); diff --git a/test/meta/src/Cursor.c b/test/meta/src/Cursor.c index cbaa3323bd..7eb0607348 100644 --- a/test/meta/src/Cursor.c +++ b/test/meta/src/Cursor.c @@ -4451,7 +4451,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; @@ -4462,6 +4462,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(); @@ -4472,6 +4483,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 }); @@ -4486,7 +4498,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}; @@ -4495,19 +4508,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); @@ -4524,7 +4555,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 { @@ -4550,13 +4589,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 }); @@ -4567,19 +4608,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 6f355cb5c6da021361c643006b287c3735042fd2 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 | 74 ++++++++++++++++++++++++++++++++++------ 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/addons/meta/cursor.c b/src/addons/meta/cursor.c index 9db30e8cd3..796ada2641 100644 --- a/src/addons/meta/cursor.c +++ b/src/addons/meta/cursor.c @@ -1842,7 +1842,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 7eb0607348..6c4e0977a4 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); @@ -432,7 +462,8 @@ void Cursor_set_string_to_null_as_signed(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_int(&cur, 0) ); - test_str(value, 0); + test_str(ecs_meta_get_string(&cur), NULL); + test_str(value, NULL); ecs_fini(world); } @@ -445,7 +476,8 @@ void Cursor_set_string_to_null_as_unsigned(void) { ecs_meta_cursor_t cur = ecs_meta_cursor(world, ecs_id(ecs_string_t), &value); test_ok( ecs_meta_set_uint(&cur, 0) ); - test_str(value, 0); + test_str(ecs_meta_get_string(&cur), NULL); + test_str(value, NULL); ecs_fini(world); } @@ -459,6 +491,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); @@ -473,6 +506,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); @@ -487,6 +521,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); @@ -501,6 +536,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); @@ -515,6 +551,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); @@ -529,6 +566,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); @@ -547,6 +585,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); @@ -558,9 +597,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); } @@ -571,7 +610,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'); @@ -586,6 +625,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); @@ -599,6 +639,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); @@ -612,6 +653,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); @@ -624,6 +666,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); } @@ -631,6 +674,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); } @@ -644,6 +688,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); } @@ -651,6 +696,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); } @@ -665,6 +711,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); @@ -678,6 +725,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); @@ -691,6 +739,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); @@ -704,6 +753,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); @@ -719,6 +769,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); @@ -734,6 +785,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); @@ -749,6 +801,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); @@ -776,6 +829,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 6ca3c985467de5997ac68ba2c8b75a63e7b34ae5 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 a7d7efa275..67ce693ba4 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -49299,7 +49299,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). */