Skip to content

Commit 7bc1e14

Browse files
#1762 Fix issue where OrderedChildren from prefab wasn't correctly applied to instance
1 parent bd143f8 commit 7bc1e14

File tree

6 files changed

+142
-6
lines changed

6 files changed

+142
-6
lines changed

distr/flecs.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6651,10 +6651,13 @@ static
66516651
void flecs_on_unparent(
66526652
ecs_world_t *world,
66536653
ecs_table_t *table,
6654+
ecs_table_t *other_table,
66546655
int32_t row,
66556656
int32_t count)
66566657
{
6657-
flecs_unparent_name_index(world, table, row, count);
6658+
if (other_table) {
6659+
flecs_unparent_name_index(world, table, row, count);
6660+
}
66586661
flecs_ordered_children_unparent(world, table, row, count);
66596662
}
66606663

@@ -6880,7 +6883,7 @@ void flecs_notify_on_remove(
68806883
}
68816884

68826885
if (diff_flags & (EcsTableEdgeReparent|EcsTableHasOrderedChildren)) {
6883-
flecs_on_unparent(world, table, row, count);
6886+
flecs_on_unparent(world, table, other_table, row, count);
68846887
}
68856888

68866889
if (diff_flags & EcsTableHasDontFragment) {
@@ -12283,6 +12286,13 @@ void flecs_instantiate(
1228312286
world, base, instance, tr->hdr.table, ctx);
1228412287
}
1228512288
ecs_os_perf_trace_pop("flecs.instantiate");
12289+
12290+
if (cr->flags & EcsIdOrderedChildren) {
12291+
ecs_component_record_t *icr = flecs_components_get(world, ecs_childof(instance));
12292+
/* If base has children, instance must now have children */
12293+
ecs_assert(icr != NULL, ECS_INTERNAL_ERROR, NULL);
12294+
flecs_ordered_children_populate(world, icr);
12295+
}
1228612296
}
1228712297
}
1228812298

src/component_actions.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,13 @@ static
130130
void flecs_on_unparent(
131131
ecs_world_t *world,
132132
ecs_table_t *table,
133+
ecs_table_t *other_table,
133134
int32_t row,
134135
int32_t count)
135136
{
136-
flecs_unparent_name_index(world, table, row, count);
137+
if (other_table) {
138+
flecs_unparent_name_index(world, table, row, count);
139+
}
137140
flecs_ordered_children_unparent(world, table, row, count);
138141
}
139142

@@ -359,7 +362,7 @@ void flecs_notify_on_remove(
359362
}
360363

361364
if (diff_flags & (EcsTableEdgeReparent|EcsTableHasOrderedChildren)) {
362-
flecs_on_unparent(world, table, row, count);
365+
flecs_on_unparent(world, table, other_table, row, count);
363366
}
364367

365368
if (diff_flags & EcsTableHasDontFragment) {

src/instantiate.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,5 +426,12 @@ void flecs_instantiate(
426426
world, base, instance, tr->hdr.table, ctx);
427427
}
428428
ecs_os_perf_trace_pop("flecs.instantiate");
429+
430+
if (cr->flags & EcsIdOrderedChildren) {
431+
ecs_component_record_t *icr = flecs_components_get(world, ecs_childof(instance));
432+
/* If base has children, instance must now have children */
433+
ecs_assert(icr != NULL, ECS_INTERNAL_ERROR, NULL);
434+
flecs_ordered_children_populate(world, icr);
435+
}
429436
}
430437
}

test/core/project.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,10 +790,14 @@
790790
"change_order_not_null_children_zero_count",
791791
"change_order_on_parent_without_ordered_children",
792792
"change_order",
793+
"ordered_children_w_name",
793794
"get_ordered_children_empty",
794795
"get_ordered_children_invalid",
795796
"get_ordered_children",
796-
"get_ordered_children_from_stage"
797+
"get_ordered_children_from_stage",
798+
"get_ordered_children_from_prefab_instance_no_children",
799+
"get_ordered_children_from_prefab_instance_3_children",
800+
"get_ordered_children_from_prefab_instance_nested_children"
797801
]
798802
}, {
799803
"id": "Has",

test/core/src/OrderedChildren.c

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,3 +1241,95 @@ void OrderedChildren_get_ordered_children_from_stage(void) {
12411241

12421242
ecs_fini(world);
12431243
}
1244+
1245+
void OrderedChildren_ordered_children_w_name(void) {
1246+
ecs_world_t *world = ecs_mini();
1247+
1248+
ecs_entity_t e = ecs_new_w_id(world, EcsPrefab);
1249+
ecs_add_id(world, e, EcsOrderedChildren);
1250+
1251+
ecs_entity(world, { .parent = e, .name = "a" });
1252+
ecs_entity(world, { .parent = e, .name = "b" });
1253+
ecs_entity(world, { .parent = e, .name = "c" });
1254+
1255+
ecs_entities_t children = ecs_get_ordered_children(world, e);
1256+
test_int(children.count, 3);
1257+
test_str(ecs_get_name(world, children.ids[0]), "a");
1258+
test_str(ecs_get_name(world, children.ids[1]), "b");
1259+
test_str(ecs_get_name(world, children.ids[2]), "c");
1260+
1261+
ecs_delete(world, e);
1262+
1263+
test_assert(ecs_lookup(world, "a") == 0);
1264+
test_assert(ecs_lookup(world, "b") == 0);
1265+
test_assert(ecs_lookup(world, "c") == 0);
1266+
1267+
ecs_fini(world);
1268+
}
1269+
1270+
void OrderedChildren_get_ordered_children_from_prefab_instance_no_children(void) {
1271+
ecs_world_t *world = ecs_mini();
1272+
1273+
ecs_entity_t p = ecs_new_w_id(world, EcsPrefab);
1274+
ecs_add_id(world, p, EcsOrderedChildren);
1275+
1276+
ecs_entity_t i = ecs_new_w_pair(world, EcsIsA, p);
1277+
test_assert(ecs_has_id(world, i, EcsOrderedChildren));
1278+
1279+
ecs_entities_t children = ecs_get_ordered_children(world, i);
1280+
test_int(children.count, 0);
1281+
1282+
ecs_fini(world);
1283+
}
1284+
1285+
void OrderedChildren_get_ordered_children_from_prefab_instance_3_children(void) {
1286+
ecs_world_t *world = ecs_mini();
1287+
1288+
ecs_entity_t p = ecs_new_w_id(world, EcsPrefab);
1289+
ecs_add_id(world, p, EcsOrderedChildren);
1290+
1291+
ecs_entity(world, { .parent = p, .name = "a" });
1292+
ecs_entity(world, { .parent = p, .name = "b" });
1293+
ecs_entity(world, { .parent = p, .name = "c" });
1294+
1295+
ecs_entity_t i = ecs_new_w_pair(world, EcsIsA, p);
1296+
test_assert(ecs_has_id(world, i, EcsOrderedChildren));
1297+
1298+
ecs_entities_t children = ecs_get_ordered_children(world, i);
1299+
test_int(children.count, 3);
1300+
test_str(ecs_get_name(world, children.ids[0]), "a");
1301+
test_str(ecs_get_name(world, children.ids[1]), "b");
1302+
test_str(ecs_get_name(world, children.ids[2]), "c");
1303+
1304+
ecs_fini(world);
1305+
}
1306+
1307+
void OrderedChildren_get_ordered_children_from_prefab_instance_nested_children(void) {
1308+
ecs_world_t *world = ecs_mini();
1309+
1310+
ecs_entity_t p = ecs_new_w_id(world, EcsPrefab);
1311+
ecs_add_id(world, p, EcsOrderedChildren);
1312+
1313+
ecs_entity(world, { .parent = p, .name = "a" });
1314+
ecs_entity(world, { .parent = p, .name = "b" });
1315+
ecs_entity_t c = ecs_entity(world, { .parent = p, .name = "c" });
1316+
ecs_add_id(world, c, EcsOrderedChildren);
1317+
ecs_entity(world, { .parent = c, .name = "x" });
1318+
ecs_entity(world, { .parent = c, .name = "y" });
1319+
1320+
ecs_entity_t i = ecs_new_w_pair(world, EcsIsA, p);
1321+
test_assert(ecs_has_id(world, i, EcsOrderedChildren));
1322+
1323+
ecs_entities_t children = ecs_get_ordered_children(world, i);
1324+
test_int(children.count, 3);
1325+
test_str(ecs_get_name(world, children.ids[0]), "a");
1326+
test_str(ecs_get_name(world, children.ids[1]), "b");
1327+
test_str(ecs_get_name(world, children.ids[2]), "c");
1328+
1329+
ecs_entities_t grandchildren = ecs_get_ordered_children(world, children.ids[2]);
1330+
test_int(grandchildren.count, 2);
1331+
test_str(ecs_get_name(world, grandchildren.ids[0]), "x");
1332+
test_str(ecs_get_name(world, grandchildren.ids[1]), "y");
1333+
1334+
ecs_fini(world);
1335+
}

test/core/src/main.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,14 @@ void OrderedChildren_change_order_null_children_nonzero_count(void);
756756
void OrderedChildren_change_order_not_null_children_zero_count(void);
757757
void OrderedChildren_change_order_on_parent_without_ordered_children(void);
758758
void OrderedChildren_change_order(void);
759+
void OrderedChildren_ordered_children_w_name(void);
759760
void OrderedChildren_get_ordered_children_empty(void);
760761
void OrderedChildren_get_ordered_children_invalid(void);
761762
void OrderedChildren_get_ordered_children(void);
762763
void OrderedChildren_get_ordered_children_from_stage(void);
764+
void OrderedChildren_get_ordered_children_from_prefab_instance_no_children(void);
765+
void OrderedChildren_get_ordered_children_from_prefab_instance_3_children(void);
766+
void OrderedChildren_get_ordered_children_from_prefab_instance_nested_children(void);
763767

764768
// Testsuite 'Has'
765769
void Has_zero(void);
@@ -5580,6 +5584,10 @@ bake_test_case OrderedChildren_testcases[] = {
55805584
"change_order",
55815585
OrderedChildren_change_order
55825586
},
5587+
{
5588+
"ordered_children_w_name",
5589+
OrderedChildren_ordered_children_w_name
5590+
},
55835591
{
55845592
"get_ordered_children_empty",
55855593
OrderedChildren_get_ordered_children_empty
@@ -5595,6 +5603,18 @@ bake_test_case OrderedChildren_testcases[] = {
55955603
{
55965604
"get_ordered_children_from_stage",
55975605
OrderedChildren_get_ordered_children_from_stage
5606+
},
5607+
{
5608+
"get_ordered_children_from_prefab_instance_no_children",
5609+
OrderedChildren_get_ordered_children_from_prefab_instance_no_children
5610+
},
5611+
{
5612+
"get_ordered_children_from_prefab_instance_3_children",
5613+
OrderedChildren_get_ordered_children_from_prefab_instance_3_children
5614+
},
5615+
{
5616+
"get_ordered_children_from_prefab_instance_nested_children",
5617+
OrderedChildren_get_ordered_children_from_prefab_instance_nested_children
55985618
}
55995619
};
56005620

@@ -13112,7 +13132,7 @@ static bake_test_suite suites[] = {
1311213132
"OrderedChildren",
1311313133
NULL,
1311413134
NULL,
13115-
33,
13135+
37,
1311613136
OrderedChildren_testcases
1311713137
},
1311813138
{

0 commit comments

Comments
 (0)