Skip to content

Commit

Permalink
Invalidate flecs::ref after table deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Jan 15, 2025
1 parent 85f5e9c commit 5b6ef83
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 2 deletions.
2 changes: 2 additions & 0 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -38317,6 +38317,8 @@ void flecs_table_fini(
{
flecs_poly_assert(world, ecs_world_t);

flecs_increment_table_version(world, table);

bool is_root = table == &world->store.root;
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(is_root || table->id != 0, ECS_INTERNAL_ERROR, NULL);
Expand Down
2 changes: 2 additions & 0 deletions src/storage/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,8 @@ void flecs_table_fini(
{
flecs_poly_assert(world, ecs_world_t);

flecs_increment_table_version(world, table);

bool is_root = table == &world->store.root;
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(is_root || table->id != 0, ECS_INTERNAL_ERROR, NULL);
Expand Down
2 changes: 2 additions & 0 deletions test/core/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,8 @@
"get_ref_after_remove_other",
"get_ref_after_remove_component",
"get_ref_after_delete",
"get_ref_after_delete_other",
"get_ref_after_delete_child",
"get_ref_after_clear",
"get_ref_after_clear_other",
"get_ref_after_realloc",
Expand Down
46 changes: 46 additions & 0 deletions test/core/src/Reference.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,28 @@ void Reference_get_ref_after_delete(void) {

ECS_COMPONENT(world, Position);

ecs_entity_t e = ecs_insert(world, ecs_value(Position, {10, 20}));

ecs_ref_t ref = ecs_ref_init(world, e, Position);

const Position *p = ecs_ref_get(world, &ref, Position);
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);

ecs_delete(world, e);

const Position *p2 = ecs_ref_get(world, &ref, Position);
test_assert(p2 == NULL);

ecs_fini(world);
}

void Reference_get_ref_after_delete_other(void) {
ecs_world_t *world = ecs_mini();

ECS_COMPONENT(world, Position);

ecs_entity_t dummy = ecs_new_w(world, Position);
ecs_entity_t e = ecs_insert(world, ecs_value(Position, {10, 20}));

Expand Down Expand Up @@ -194,6 +216,30 @@ void Reference_get_ref_after_delete(void) {
ecs_fini(world);
}

void Reference_get_ref_after_delete_child(void) {
ecs_world_t *world = ecs_mini();

ECS_COMPONENT(world, Position);

ecs_entity_t parent = ecs_new(world);
ecs_entity_t e = ecs_insert(world, ecs_value(Position, {10, 20}));
ecs_add_pair(world, e, EcsChildOf, parent);

ecs_ref_t ref = ecs_ref_init(world, e, Position);

const Position *p = ecs_ref_get(world, &ref, Position);
test_assert(p != NULL);
test_int(p->x, 10);
test_int(p->y, 20);

ecs_delete(world, parent);

const Position *p2 = ecs_ref_get(world, &ref, Position);
test_assert(p2 == NULL);

ecs_fini(world);
}

void Reference_get_ref_after_clear(void) {
ecs_world_t *world = ecs_mini();

Expand Down
12 changes: 11 additions & 1 deletion test/core/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,8 @@ void Reference_get_ref_after_remove(void);
void Reference_get_ref_after_remove_other(void);
void Reference_get_ref_after_remove_component(void);
void Reference_get_ref_after_delete(void);
void Reference_get_ref_after_delete_other(void);
void Reference_get_ref_after_delete_child(void);
void Reference_get_ref_after_clear(void);
void Reference_get_ref_after_clear_other(void);
void Reference_get_ref_after_realloc(void);
Expand Down Expand Up @@ -5179,6 +5181,14 @@ bake_test_case Reference_testcases[] = {
"get_ref_after_delete",
Reference_get_ref_after_delete
},
{
"get_ref_after_delete_other",
Reference_get_ref_after_delete_other
},
{
"get_ref_after_delete_child",
Reference_get_ref_after_delete_child
},
{
"get_ref_after_clear",
Reference_get_ref_after_clear
Expand Down Expand Up @@ -11578,7 +11588,7 @@ static bake_test_suite suites[] = {
"Reference",
Reference_setup,
NULL,
18,
20,
Reference_testcases
},
{
Expand Down
1 change: 1 addition & 0 deletions test/cpp/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1097,6 +1097,7 @@
"ctor_from_entity",
"implicit_operator_bool",
"try_get",
"try_get_after_delete",
"has",
"bool_operator",
"base_type",
Expand Down
18 changes: 18 additions & 0 deletions test/cpp/src/Refs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,24 @@ void Refs_try_get(void) {
test_assert(p.try_get() == nullptr);
}

void Refs_try_get_after_delete(void) {
flecs::world world;

flecs::entity e = world.entity().set(Position{10, 20});

flecs::ref<Position> p = e.get_ref<Position>();
Position *ptr = p.try_get();
test_assert(ptr != nullptr);
test_int(ptr->x, 10);
test_int(ptr->y, 20);

e.destruct();

ptr = p.try_get();
test_assert(ptr == nullptr);
}


void Refs_has(void) {
flecs::world world;

Expand Down
7 changes: 6 additions & 1 deletion test/cpp/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,7 @@ void Refs_default_ctor(void);
void Refs_ctor_from_entity(void);
void Refs_implicit_operator_bool(void);
void Refs_try_get(void);
void Refs_try_get_after_delete(void);
void Refs_has(void);
void Refs_bool_operator(void);
void Refs_base_type(void);
Expand Down Expand Up @@ -5567,6 +5568,10 @@ bake_test_case Refs_testcases[] = {
"try_get",
Refs_try_get
},
{
"try_get_after_delete",
Refs_try_get_after_delete
},
{
"has",
Refs_has
Expand Down Expand Up @@ -7130,7 +7135,7 @@ static bake_test_suite suites[] = {
"Refs",
NULL,
NULL,
20,
21,
Refs_testcases
},
{
Expand Down

0 comments on commit 5b6ef83

Please sign in to comment.