Skip to content

Commit

Permalink
Fix issues with updating empty table administration inside hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Sep 2, 2024
1 parent d311476 commit 31e285a
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 36 deletions.
25 changes: 12 additions & 13 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 3 additions & 1 deletion distr/flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int8_t>(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 ...);
}

Expand Down
25 changes: 12 additions & 13 deletions src/storage/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 3 additions & 1 deletion test/core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
48 changes: 48 additions & 0 deletions test/core/src/ComponentLifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
12 changes: 11 additions & 1 deletion test/core/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
}
};

Expand Down Expand Up @@ -10724,7 +10734,7 @@ static bake_test_suite suites[] = {
"ComponentLifecycle",
ComponentLifecycle_setup,
NULL,
94,
96,
ComponentLifecycle_testcases
},
{
Expand Down
3 changes: 2 additions & 1 deletion test/cpp/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
43 changes: 41 additions & 2 deletions test/cpp/src/ComponentLifecycle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Position>().on_add([&](Position& p) {
count = ecs.count<Position>();
});

auto ent = ecs.entity().set<Position>({1, 2});
test_int(count, 1);

int matched = 0;
ecs.query<Position>().each([&](Position& p) {
matched ++;
});

test_int(matched, 1);
}

void ComponentLifecycle_count_in_remove_hook(void) {
flecs::world ecs;

int count = 0;

ecs.component<Position>().on_remove([&](Position& p) {
count = ecs.count<Position>();
});

auto ent = ecs.entity().set<Position>({1, 2});
test_int(count, 0);

ent.destruct();
test_int(count, 1);

int matched = 0;
ecs.query<Position>().each([&](Position& p) {
matched ++;
});

test_int(matched, 0);
}
13 changes: 9 additions & 4 deletions test/cpp/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
}
};

Expand Down Expand Up @@ -6633,7 +6638,7 @@ static bake_test_suite suites[] = {
"ComponentLifecycle",
NULL,
NULL,
78,
79,
ComponentLifecycle_testcases
},
{
Expand Down

0 comments on commit 31e285a

Please sign in to comment.