Skip to content

Commit 43b2fd8

Browse files
committed
Allow for modifying reflection of native types after they have been used
1 parent 124dd92 commit 43b2fd8

File tree

6 files changed

+121
-50
lines changed

6 files changed

+121
-50
lines changed

distr/flecs.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -58584,16 +58584,6 @@ void flecs_meta_import_definitions(
5858458584

5858558585
#ifdef FLECS_META
5858658586

58587-
#ifdef FLECS_DEBUG
58588-
static
58589-
bool flecs_meta_is_builtin_type(
58590-
ecs_entity_t type)
58591-
{
58592-
return type < EcsFirstUserComponentId ||
58593-
(type > FLECS_HI_COMPONENT_ID && type < EcsFirstUserEntityId);
58594-
}
58595-
#endif
58596-
5859758587
void flecs_type_serializer_dtor(
5859858588
EcsTypeSerializer *ptr)
5859958589
{
@@ -58768,13 +58758,14 @@ int flecs_init_type(
5876858758
ecs_assert(type != 0, ECS_INTERNAL_ERROR, NULL);
5876958759

5877058760
#ifdef FLECS_DEBUG
58771-
if (!flecs_meta_is_builtin_type(type)) {
58761+
{
5877258762
const ecs_type_info_t *ti = ecs_get_type_info(world, type);
58773-
if (ti) {
58774-
ecs_assert(!(ti->hooks.flags & ECS_TYPE_HOOK_IN_USE),
58763+
if (ti && (ti->hooks.flags & ECS_TYPE_HOOK_IN_USE)) {
58764+
const EcsType *t = ecs_get(world, type, EcsType);
58765+
ecs_assert(!t || t->existing,
5877558766
ECS_INVALID_OPERATION,
58776-
"cannot modify type '%s' after it is in use",
58777-
ecs_get_name(world, type));
58767+
"cannot modify runtime type '%s' after it is in use",
58768+
flecs_errstr_1(ecs_get_path(world, type)));
5877858769
}
5877958770
}
5878058771
#endif
@@ -90237,17 +90228,22 @@ void flecs_meta_primitives_init(
9023790228
});
9023890229

9023990230
/* Initialize primitive types */
90240-
#define ECS_PRIMITIVE(world, type, primitive_kind)\
90241-
ecs_entity_init(world, &(ecs_entity_desc_t){\
90242-
.id = ecs_id(ecs_##type##_t),\
90243-
.name = #type,\
90244-
.symbol = #type });\
90245-
ecs_set(world, ecs_id(ecs_##type##_t), EcsPrimitive, {\
90231+
#define ECS_PRIMITIVE(world, T, primitive_kind)\
90232+
ecs_component_init(world, &(ecs_component_desc_t){\
90233+
.entity = ecs_entity(world, {\
90234+
.id = ecs_id(ecs_##T##_t),\
90235+
.name = #T,\
90236+
.symbol = #T \
90237+
}),\
90238+
.type.size = ECS_SIZEOF(ecs_##T##_t),\
90239+
.type.alignment = ECS_ALIGNOF(ecs_##T##_t),\
90240+
});\
90241+
ecs_set(world, ecs_id(ecs_##T##_t), EcsPrimitive, {\
9024690242
.kind = primitive_kind\
9024790243
});\
90248-
ecs_set_hooks(world, ecs_##type##_t, { \
90249-
.cmp = flecs_compare_##type, \
90250-
.equals = flecs_equals_##type \
90244+
ecs_set_hooks(world, ecs_##T##_t, { \
90245+
.cmp = flecs_compare_##T, \
90246+
.equals = flecs_equals_##T \
9025190247
})
9025290248

9025390249
ECS_PRIMITIVE(world, bool, EcsBool);

src/addons/meta/meta.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,6 @@
88

99
#ifdef FLECS_META
1010

11-
#ifdef FLECS_DEBUG
12-
static
13-
bool flecs_meta_is_builtin_type(
14-
ecs_entity_t type)
15-
{
16-
return type < EcsFirstUserComponentId ||
17-
(type > FLECS_HI_COMPONENT_ID && type < EcsFirstUserEntityId);
18-
}
19-
#endif
20-
2111
void flecs_type_serializer_dtor(
2212
EcsTypeSerializer *ptr)
2313
{
@@ -192,13 +182,14 @@ int flecs_init_type(
192182
ecs_assert(type != 0, ECS_INTERNAL_ERROR, NULL);
193183

194184
#ifdef FLECS_DEBUG
195-
if (!flecs_meta_is_builtin_type(type)) {
185+
{
196186
const ecs_type_info_t *ti = ecs_get_type_info(world, type);
197-
if (ti) {
198-
ecs_assert(!(ti->hooks.flags & ECS_TYPE_HOOK_IN_USE),
187+
if (ti && (ti->hooks.flags & ECS_TYPE_HOOK_IN_USE)) {
188+
const EcsType *t = ecs_get(world, type, EcsType);
189+
ecs_assert(!t || t->existing,
199190
ECS_INVALID_OPERATION,
200-
"cannot modify type '%s' after it is in use",
201-
ecs_get_name(world, type));
191+
"cannot modify runtime type '%s' after it is in use",
192+
flecs_errstr_1(ecs_get_path(world, type)));
202193
}
203194
}
204195
#endif

src/addons/meta/type_support/primitive_ts.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -513,17 +513,22 @@ void flecs_meta_primitives_init(
513513
});
514514

515515
/* Initialize primitive types */
516-
#define ECS_PRIMITIVE(world, type, primitive_kind)\
517-
ecs_entity_init(world, &(ecs_entity_desc_t){\
518-
.id = ecs_id(ecs_##type##_t),\
519-
.name = #type,\
520-
.symbol = #type });\
521-
ecs_set(world, ecs_id(ecs_##type##_t), EcsPrimitive, {\
516+
#define ECS_PRIMITIVE(world, T, primitive_kind)\
517+
ecs_component_init(world, &(ecs_component_desc_t){\
518+
.entity = ecs_entity(world, {\
519+
.id = ecs_id(ecs_##T##_t),\
520+
.name = #T,\
521+
.symbol = #T \
522+
}),\
523+
.type.size = ECS_SIZEOF(ecs_##T##_t),\
524+
.type.alignment = ECS_ALIGNOF(ecs_##T##_t),\
525+
});\
526+
ecs_set(world, ecs_id(ecs_##T##_t), EcsPrimitive, {\
522527
.kind = primitive_kind\
523528
});\
524-
ecs_set_hooks(world, ecs_##type##_t, { \
525-
.cmp = flecs_compare_##type, \
526-
.equals = flecs_equals_##type \
529+
ecs_set_hooks(world, ecs_##T##_t, { \
530+
.cmp = flecs_compare_##T, \
531+
.equals = flecs_equals_##T \
527532
})
528533

529534
ECS_PRIMITIVE(world, bool, EcsBool);

test/meta/project.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@
196196
"struct_w_16_alignment",
197197
"struct_w_use_offset",
198198
"direct_cycle",
199-
"indirect_cycle"
199+
"indirect_cycle",
200+
"use_before_registering_reflection",
201+
"use_before_registering_reflection_w_hooks"
200202
]
201203
}, {
202204
"id": "NestedStructTypes",

test/meta/src/StructTypes.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,3 +1040,69 @@ void StructTypes_indirect_cycle(void) {
10401040
}
10411041
});
10421042
}
1043+
1044+
void StructTypes_use_before_registering_reflection(void) {
1045+
ecs_world_t *world = ecs_init();
1046+
1047+
ECS_COMPONENT(world, Position);
1048+
1049+
ecs_entity_t e = ecs_new(world);
1050+
ecs_set(world, e, Position, {10, 20});
1051+
1052+
ecs_entity_t s = ecs_struct(world, {
1053+
.entity = ecs_id(Position),
1054+
.members = {
1055+
{ "x", .type = ecs_id(ecs_i32_t) },
1056+
{ "y", .type = ecs_id(ecs_i32_t) }
1057+
}
1058+
});
1059+
1060+
test_assert(s != 0);
1061+
1062+
test_assert(ecs_has(world, e, Position));
1063+
1064+
{
1065+
const Position *p = ecs_get(world, e, Position);
1066+
test_assert(p != NULL);
1067+
test_int(p->x, 10);
1068+
test_int(p->y, 20);
1069+
}
1070+
1071+
ecs_fini(world);
1072+
}
1073+
1074+
1075+
void StructTypes_use_before_registering_reflection_w_hooks(void) {
1076+
ecs_world_t *world = ecs_init();
1077+
1078+
ECS_COMPONENT(world, Position);
1079+
1080+
ecs_set_hooks(world, Position, {
1081+
.ctor = flecs_default_ctor
1082+
});
1083+
1084+
ecs_entity_t e = ecs_new(world);
1085+
ecs_set(world, e, Position, {10, 20});
1086+
1087+
ecs_entity_t s = ecs_struct(world, {
1088+
.entity = ecs_id(Position),
1089+
.members = {
1090+
{ "x", .type = ecs_id(ecs_i32_t) },
1091+
{ "y", .type = ecs_id(ecs_i32_t) }
1092+
}
1093+
});
1094+
1095+
test_assert(s != 0);
1096+
1097+
test_assert(ecs_has(world, e, Position));
1098+
1099+
{
1100+
const Position *p = ecs_get(world, e, Position);
1101+
test_assert(p != NULL);
1102+
test_int(p->x, 10);
1103+
test_int(p->y, 20);
1104+
}
1105+
1106+
ecs_fini(world);
1107+
}
1108+

test/meta/src/main.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ void StructTypes_struct_w_16_alignment(void);
184184
void StructTypes_struct_w_use_offset(void);
185185
void StructTypes_direct_cycle(void);
186186
void StructTypes_indirect_cycle(void);
187+
void StructTypes_use_before_registering_reflection(void);
188+
void StructTypes_use_before_registering_reflection_w_hooks(void);
187189

188190
// Testsuite 'NestedStructTypes'
189191
void NestedStructTypes_1_bool(void);
@@ -1843,6 +1845,14 @@ bake_test_case StructTypes_testcases[] = {
18431845
{
18441846
"indirect_cycle",
18451847
StructTypes_indirect_cycle
1848+
},
1849+
{
1850+
"use_before_registering_reflection",
1851+
StructTypes_use_before_registering_reflection
1852+
},
1853+
{
1854+
"use_before_registering_reflection_w_hooks",
1855+
StructTypes_use_before_registering_reflection_w_hooks
18461856
}
18471857
};
18481858

@@ -5668,6 +5678,7 @@ bake_test_case RttCompare_testcases[] = {
56685678
}
56695679
};
56705680

5681+
56715682
static bake_test_suite suites[] = {
56725683
{
56735684
"PrimitiveTypes",
@@ -5701,7 +5712,7 @@ static bake_test_suite suites[] = {
57015712
"StructTypes",
57025713
NULL,
57035714
NULL,
5704-
34,
5715+
36,
57055716
StructTypes_testcases
57065717
},
57075718
{

0 commit comments

Comments
 (0)