diff --git a/distr/flecs.c b/distr/flecs.c index 5ea554ff3..5ddbd4a61 100644 --- a/distr/flecs.c +++ b/distr/flecs.c @@ -37290,6 +37290,12 @@ int32_t flecs_table_append( table->data.count = v_entities.count; table->data.size = v_entities.size; + /* If this is the first entity in this table, signal queries so that the + * table moves from an inactive table to an active table. */ + if (!count) { + flecs_table_set_empty(world, table); + } + /* Reobtain size to ensure that the columns have the same size as the * entities and record vectors. This keeps reasoning about when allocations * occur easier. */ @@ -37326,12 +37332,6 @@ int32_t flecs_table_append( flecs_bitset_addn(bs, 1); } - /* If this is the first entity in this table, signal queries so that the - * table moves from an inactive table to an active table. */ - if (!count) { - flecs_table_set_empty(world, table); - } - flecs_table_check_sanity(world, table); return count; @@ -37392,13 +37392,6 @@ void flecs_table_delete( /* If the table is monitored indicate that there has been a change */ flecs_table_mark_table_dirty(world, table, 0); - /* If table is empty, deactivate it */ - if (!count) { - table->data.count --; - flecs_table_set_empty(world, table); - table->data.count ++; - } - /* Destruct component data */ ecs_column_t *columns = table->data.columns; int32_t column_count = table->column_count; @@ -37412,6 +37405,9 @@ void flecs_table_delete( } table->data.count --; + if (!count) { + flecs_table_set_empty(world, table); + } flecs_table_check_sanity(world, table); return; @@ -37475,6 +37471,9 @@ void flecs_table_delete( } table->data.count --; + if (!count) { + flecs_table_set_empty(world, table); + } flecs_table_check_sanity(world, table); } diff --git a/distr/flecs.h b/distr/flecs.h index c79064403..9aef1094d 100644 --- a/distr/flecs.h +++ b/distr/flecs.h @@ -25697,7 +25697,9 @@ struct field_ptrs { void populate_self(const ecs_iter_t *iter, size_t index, T, Targs... comps) { fields_[index].ptr = ecs_field_w_size(iter, sizeof(A), static_cast(index)); - fields_[index].is_ref = iter->sources[index] != 0; + // fields_[index].is_ref = iter->sources[index] != 0; + fields_[index].is_ref = false; + ecs_assert(iter->sources[index] == 0, ECS_INTERNAL_ERROR, NULL); populate_self(iter, index + 1, comps ...); } diff --git a/src/storage/table.c b/src/storage/table.c index 2322ff019..2b332b49d 100644 --- a/src/storage/table.c +++ b/src/storage/table.c @@ -1436,6 +1436,12 @@ int32_t flecs_table_append( table->data.count = v_entities.count; table->data.size = v_entities.size; + /* If this is the first entity in this table, signal queries so that the + * table moves from an inactive table to an active table. */ + if (!count) { + flecs_table_set_empty(world, table); + } + /* Reobtain size to ensure that the columns have the same size as the * entities and record vectors. This keeps reasoning about when allocations * occur easier. */ @@ -1472,12 +1478,6 @@ int32_t flecs_table_append( flecs_bitset_addn(bs, 1); } - /* If this is the first entity in this table, signal queries so that the - * table moves from an inactive table to an active table. */ - if (!count) { - flecs_table_set_empty(world, table); - } - flecs_table_check_sanity(world, table); return count; @@ -1538,13 +1538,6 @@ void flecs_table_delete( /* If the table is monitored indicate that there has been a change */ flecs_table_mark_table_dirty(world, table, 0); - /* If table is empty, deactivate it */ - if (!count) { - table->data.count --; - flecs_table_set_empty(world, table); - table->data.count ++; - } - /* Destruct component data */ ecs_column_t *columns = table->data.columns; int32_t column_count = table->column_count; @@ -1558,6 +1551,9 @@ void flecs_table_delete( } table->data.count --; + if (!count) { + flecs_table_set_empty(world, table); + } flecs_table_check_sanity(world, table); return; @@ -1621,6 +1617,9 @@ void flecs_table_delete( } table->data.count --; + if (!count) { + flecs_table_set_empty(world, table); + } flecs_table_check_sanity(world, table); } diff --git a/test/core/project.json b/test/core/project.json index 2f4b539e9..9ecd041e3 100644 --- a/test/core/project.json +++ b/test/core/project.json @@ -1150,7 +1150,9 @@ "on_nested_prefab_copy_test_invokes_copy_count", "no_move_no_move_ctor_with_move_dtor_with_ctor_move_dtor", "new_w_table_ctor", - "new_w_table_on_add_hook" + "new_w_table_on_add_hook", + "count_in_on_add", + "count_in_on_remove" ] }, { "id": "Pairs", diff --git a/test/core/src/ComponentLifecycle.c b/test/core/src/ComponentLifecycle.c index 1d9111930..7357c5b01 100644 --- a/test/core/src/ComponentLifecycle.c +++ b/test/core/src/ComponentLifecycle.c @@ -3421,3 +3421,51 @@ void ComponentLifecycle_new_w_table_on_add_hook(void) { ecs_fini(world); } + +static int hook_count = 0; +static void hook_w_count(ecs_iter_t *it) { + hook_count = ecs_count_id(it->world, ecs_field_id(it, 0)); + test_int(hook_count, 1); +} + +void ComponentLifecycle_count_in_on_add(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + ecs_set_hooks(world, Position, { + .on_add = hook_w_count + }); + + ecs_entity_t e = ecs_new_w(world, Position); + test_int(hook_count, 1); + + ecs_iter_t it = ecs_each(world, Position); + test_bool(true, ecs_each_next(&it)); + test_int(1, it.count); + test_uint(e, it.entities[0]); + test_bool(false, ecs_each_next(&it)); + + ecs_fini(world); +} + +void ComponentLifecycle_count_in_on_remove(void) { + ecs_world_t *world = ecs_mini(); + + ECS_COMPONENT(world, Position); + + ecs_set_hooks(world, Position, { + .on_remove = hook_w_count + }); + + ecs_entity_t e = ecs_new_w(world, Position); + test_int(hook_count, 0); + + ecs_delete(world, e); + test_int(hook_count, 1); + + ecs_iter_t it = ecs_each(world, Position); + test_bool(false, ecs_each_next(&it)); + + ecs_fini(world); +} diff --git a/test/core/src/main.c b/test/core/src/main.c index cc394f314..ab47f30ae 100644 --- a/test/core/src/main.c +++ b/test/core/src/main.c @@ -1095,6 +1095,8 @@ void ComponentLifecycle_on_nested_prefab_copy_test_invokes_copy_count(void); void ComponentLifecycle_no_move_no_move_ctor_with_move_dtor_with_ctor_move_dtor(void); void ComponentLifecycle_new_w_table_ctor(void); void ComponentLifecycle_new_w_table_on_add_hook(void); +void ComponentLifecycle_count_in_on_add(void); +void ComponentLifecycle_count_in_on_remove(void); // Testsuite 'Pairs' void Pairs_type_w_one_pair(void); @@ -6364,6 +6366,14 @@ bake_test_case ComponentLifecycle_testcases[] = { { "new_w_table_on_add_hook", ComponentLifecycle_new_w_table_on_add_hook + }, + { + "count_in_on_add", + ComponentLifecycle_count_in_on_add + }, + { + "count_in_on_remove", + ComponentLifecycle_count_in_on_remove } }; @@ -10724,7 +10734,7 @@ static bake_test_suite suites[] = { "ComponentLifecycle", ComponentLifecycle_setup, NULL, - 94, + 96, ComponentLifecycle_testcases }, { diff --git a/test/cpp/project.json b/test/cpp/project.json index ed8799d29..52a0b1b5e 100644 --- a/test/cpp/project.json +++ b/test/cpp/project.json @@ -996,7 +996,8 @@ "register_parent_after_child_w_hooks", "register_parent_after_child_w_hooks_implicit", "sparse_component", - "count_in_hook" + "count_in_add_hook", + "count_in_remove_hook" ] }, { "id": "Refs", diff --git a/test/cpp/src/ComponentLifecycle.cpp b/test/cpp/src/ComponentLifecycle.cpp index e58b360f9..cc6ecb677 100644 --- a/test/cpp/src/ComponentLifecycle.cpp +++ b/test/cpp/src/ComponentLifecycle.cpp @@ -1921,6 +1921,45 @@ void ComponentLifecycle_sparse_component(void) { test_int(Pod::move_ctor_invoked, 0); } -void ComponentLifecycle_count_in_hook(void) { - // Implement testcase +void ComponentLifecycle_count_in_add_hook(void) { + flecs::world ecs; + + int count = 0; + + ecs.component().on_add([&](Position& p) { + count = ecs.count(); + }); + + auto ent = ecs.entity().set({1, 2}); + test_int(count, 1); + + int matched = 0; + ecs.query().each([&](Position& p) { + matched ++; + }); + + test_int(matched, 1); +} + +void ComponentLifecycle_count_in_remove_hook(void) { + flecs::world ecs; + + int count = 0; + + ecs.component().on_remove([&](Position& p) { + count = ecs.count(); + }); + + auto ent = ecs.entity().set({1, 2}); + test_int(count, 0); + + ent.destruct(); + test_int(count, 1); + + int matched = 0; + ecs.query().each([&](Position& p) { + matched ++; + }); + + test_int(matched, 0); } diff --git a/test/cpp/src/main.cpp b/test/cpp/src/main.cpp index bcd7187ff..ccbb7ca4f 100644 --- a/test/cpp/src/main.cpp +++ b/test/cpp/src/main.cpp @@ -961,7 +961,8 @@ void ComponentLifecycle_dtor_relation_target(void); void ComponentLifecycle_register_parent_after_child_w_hooks(void); void ComponentLifecycle_register_parent_after_child_w_hooks_implicit(void); void ComponentLifecycle_sparse_component(void); -void ComponentLifecycle_count_in_hook(void); +void ComponentLifecycle_count_in_add_hook(void); +void ComponentLifecycle_count_in_remove_hook(void); // Testsuite 'Refs' void Refs_get_ref_by_ptr(void); @@ -5079,8 +5080,12 @@ bake_test_case ComponentLifecycle_testcases[] = { ComponentLifecycle_sparse_component }, { - "count_in_hook", - ComponentLifecycle_count_in_hook + "count_in_add_hook", + ComponentLifecycle_count_in_add_hook + }, + { + "count_in_remove_hook", + ComponentLifecycle_count_in_remove_hook } }; @@ -6633,7 +6638,7 @@ static bake_test_suite suites[] = { "ComponentLifecycle", NULL, NULL, - 78, + 79, ComponentLifecycle_testcases }, {