diff --git a/distr/flecs.c b/distr/flecs.c index bab1cf8f4..2688fd0ba 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -31739,6 +31739,7 @@ bool flecs_switch_set( if (!hdr[0]) { hdr[0] = (uint64_t)element; + node->next = 0; } else { ecs_switch_node_t *head = flecs_switch_get_node(sw, (uint32_t)hdr[0]); ecs_assert(head->prev == 0, ECS_INTERNAL_ERROR, NULL); @@ -31746,6 +31747,7 @@ bool flecs_switch_set( node->next = (uint32_t)hdr[0]; hdr[0] = (uint64_t)element; + ecs_assert(node->next != element, ECS_INTERNAL_ERROR, NULL); } node->prev = 0; diff --git a/src/datastructures/switch_list.c b/src/datastructures/switch_list.c index f54fab639..6aa70ac47 100644 --- a/src/datastructures/switch_list.c +++ b/src/datastructures/switch_list.c @@ -131,6 +131,7 @@ bool flecs_switch_set( if (!hdr[0]) { hdr[0] = (uint64_t)element; + node->next = 0; } else { ecs_switch_node_t *head = flecs_switch_get_node(sw, (uint32_t)hdr[0]); ecs_assert(head->prev == 0, ECS_INTERNAL_ERROR, NULL); @@ -138,6 +139,7 @@ bool flecs_switch_set( node->next = (uint32_t)hdr[0]; hdr[0] = (uint64_t)element; + ecs_assert(node->next != element, ECS_INTERNAL_ERROR, NULL); } node->prev = 0; diff --git a/test/core/project.json b/test/core/project.json index 21de46d8c..c6fa8a9b0 100644 --- a/test/core/project.json +++ b/test/core/project.json @@ -595,7 +595,8 @@ "defer_add_union_relationship", "defer_add_existing_union_relationship", "defer_add_union_relationship_2_ops", - "defer_add_existing_union_relationship_2_ops" + "defer_add_existing_union_relationship_2_ops", + "stress_test_1" ] }, { "id": "Hierarchies", diff --git a/test/core/src/Union.c b/test/core/src/Union.c index f901be005..c86013bed 100644 --- a/test/core/src/Union.c +++ b/test/core/src/Union.c @@ -1444,3 +1444,56 @@ void Union_defer_add_existing_union_relationship_2_ops(void) { ecs_fini(world); } + +void Union_stress_test_1(void) { + ecs_world_t *world = ecs_mini(); + + ECS_ENTITY(world, Rel, Union); + ECS_TAG(world, TgtA); + ECS_TAG(world, TgtB); + ECS_TAG(world, TgtC); + + ecs_entity_t e1 = ecs_new(world); + ecs_entity_t e2 = ecs_new(world); + + ecs_add_pair(world, e1, Rel, TgtA); + ecs_add_pair(world, e2, Rel, TgtA); + ecs_add_pair(world, e2, Rel, TgtB); + + ecs_add_pair(world, e2, Rel, TgtA); + ecs_add_pair(world, e2, Rel, TgtB); + ecs_add_pair(world, e1, Rel, TgtC); + + ecs_add_pair(world, e1, Rel, TgtA); + ecs_add_pair(world, e2, Rel, TgtB); + ecs_add_pair(world, e1, Rel, TgtC); + + ecs_add_pair(world, e1, Rel, TgtA); + ecs_add_pair(world, e2, Rel, TgtA); + ecs_add_pair(world, e1, Rel, TgtC); + + test_assert(ecs_has_pair(world, e1, Rel, TgtC)); + test_assert(ecs_has_pair(world, e2, Rel, TgtA)); + + ecs_query_t *q_tgtA = ecs_query(world, { + .terms = {{ ecs_pair(Rel, TgtA) }} + }); + + ecs_query_t *q_tgtB = ecs_query(world, { + .terms = {{ ecs_pair(Rel, TgtB) }} + }); + + ecs_query_t *q_tgtC = ecs_query(world, { + .terms = {{ ecs_pair(Rel, TgtC) }} + }); + + test_int(ecs_query_count(q_tgtA).entities, 1); + test_int(ecs_query_count(q_tgtB).entities, 0); + test_int(ecs_query_count(q_tgtC).entities, 1); + + ecs_query_fini(q_tgtA); + ecs_query_fini(q_tgtB); + ecs_query_fini(q_tgtC); + + ecs_fini(world); +} diff --git a/test/core/src/main.c b/test/core/src/main.c index ecb758b3b..8e72f6e4a 100644 --- a/test/core/src/main.c +++ b/test/core/src/main.c @@ -567,6 +567,7 @@ void Union_defer_add_union_relationship(void); void Union_defer_add_existing_union_relationship(void); void Union_defer_add_union_relationship_2_ops(void); void Union_defer_add_existing_union_relationship_2_ops(void); +void Union_stress_test_1(void); // Testsuite 'Hierarchies' void Hierarchies_setup(void); @@ -4456,6 +4457,10 @@ bake_test_case Union_testcases[] = { { "defer_add_existing_union_relationship_2_ops", Union_defer_add_existing_union_relationship_2_ops + }, + { + "stress_test_1", + Union_stress_test_1 } }; @@ -11208,7 +11213,7 @@ static bake_test_suite suites[] = { "Union", NULL, NULL, - 51, + 52, Union_testcases }, {