Skip to content

Commit

Permalink
#1209 Fix issue with disabling components & suspending deferred mode
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Jun 20, 2024
1 parent 3db34c1 commit ae42a42
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 48 deletions.
46 changes: 23 additions & 23 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -7522,8 +7522,8 @@ bool flecs_on_delete_clear_tables(
flecs_remove_from_table(world, table);
} else {
ecs_dbg_3(
"#[red]delete#[reset] entities from table %u [%s]",
(uint32_t)table->id, ecs_table_str(world, table));
"#[red]delete#[reset] entities from table %u",
(uint32_t)table->id);
flecs_table_delete_entities(world, table);
}
}
Expand Down Expand Up @@ -8423,9 +8423,6 @@ void ecs_enable_id(

if (flecs_defer_enable(stage, entity, id, enable)) {
return;
} else {
/* Operations invoked by enable/disable should not be deferred */
stage->defer --;
}

ecs_record_t *r = flecs_entities_get(world, entity);
Expand All @@ -8439,6 +8436,7 @@ void ecs_enable_id(

if (index == -1) {
ecs_add_id(world, entity, bs_id);
flecs_defer_end(world, stage);
ecs_enable_id(world, entity, id, enable);
return;
}
Expand All @@ -8452,6 +8450,8 @@ void ecs_enable_id(
ecs_assert(bs != NULL, ECS_INTERNAL_ERROR, NULL);

flecs_bitset_set(bs, ECS_RECORD_TO_ROW(r->row), enable);

flecs_defer_end(world, stage);
error:
return;
}
Expand Down Expand Up @@ -36252,8 +36252,8 @@ void flecs_table_dtor_all(
}
}

static const char *flecs_locked_storage_msg =
"to fix, defer operations with defer_begin/defer_end";
#define FLECS_LOCKED_STORAGE_MSG \
"to fix, defer operations with defer_begin/defer_end"

/* Cleanup table storage */
static
Expand All @@ -36265,7 +36265,7 @@ void flecs_table_fini_data(
bool is_delete,
bool deactivate)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

if (!data) {
return;
Expand Down Expand Up @@ -36367,7 +36367,7 @@ void flecs_table_fini(
ecs_table_t *table)
{
bool is_root = table == &world->store.root;
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(is_root || table->id != 0, ECS_INTERNAL_ERROR, NULL);
ecs_assert(is_root || flecs_sparse_is_alive(&world->store.tables, table->id),
ECS_INTERNAL_ERROR, NULL);
Expand Down Expand Up @@ -36438,7 +36438,7 @@ void flecs_table_reset(
ecs_world_t *world,
ecs_table_t *table)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
flecs_table_clear_edges(world, table);
}

Expand Down Expand Up @@ -36479,7 +36479,7 @@ void flecs_table_mark_dirty(
ecs_table_t *table,
ecs_entity_t component)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);

if (table->dirty_state) {
Expand Down Expand Up @@ -36748,7 +36748,7 @@ int32_t flecs_table_append(
bool on_add)
{
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);

Expand Down Expand Up @@ -36860,7 +36860,7 @@ void flecs_table_delete(
{
ecs_assert(world != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);

Expand Down Expand Up @@ -37023,8 +37023,8 @@ void flecs_table_move(
{
ecs_assert(dst_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(src_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

ecs_assert(src_index >= 0, ECS_INTERNAL_ERROR, NULL);
ecs_assert(dst_index >= 0, ECS_INTERNAL_ERROR, NULL);
Expand Down Expand Up @@ -37131,7 +37131,7 @@ int32_t flecs_table_appendn(
int32_t to_add,
const ecs_entity_t *ids)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);
int32_t cur_count = flecs_table_data_count(data);
Expand All @@ -37149,8 +37149,8 @@ void flecs_table_set_size(
ecs_data_t *data,
int32_t size)
{
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);

Expand All @@ -37167,8 +37167,8 @@ bool flecs_table_shrink(
ecs_world_t *world,
ecs_table_t *table)
{
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
(void)world;

flecs_table_check_sanity(table);
Expand Down Expand Up @@ -37222,7 +37222,7 @@ void flecs_table_swap(
{
(void)world;

ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(row_1 >= 0, ECS_INTERNAL_ERROR, NULL);
ecs_assert(row_2 >= 0, ECS_INTERNAL_ERROR, NULL);

Expand Down Expand Up @@ -37466,8 +37466,8 @@ void flecs_table_merge(
{
ecs_assert(src_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(dst_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(src_table);
flecs_table_check_sanity(dst_table);
Expand Down
10 changes: 5 additions & 5 deletions src/entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -2532,8 +2532,8 @@ bool flecs_on_delete_clear_tables(
flecs_remove_from_table(world, table);
} else {
ecs_dbg_3(
"#[red]delete#[reset] entities from table %u [%s]",
(uint32_t)table->id, ecs_table_str(world, table));
"#[red]delete#[reset] entities from table %u",
(uint32_t)table->id);
flecs_table_delete_entities(world, table);
}
}
Expand Down Expand Up @@ -3433,9 +3433,6 @@ void ecs_enable_id(

if (flecs_defer_enable(stage, entity, id, enable)) {
return;
} else {
/* Operations invoked by enable/disable should not be deferred */
stage->defer --;
}

ecs_record_t *r = flecs_entities_get(world, entity);
Expand All @@ -3449,6 +3446,7 @@ void ecs_enable_id(

if (index == -1) {
ecs_add_id(world, entity, bs_id);
flecs_defer_end(world, stage);
ecs_enable_id(world, entity, id, enable);
return;
}
Expand All @@ -3462,6 +3460,8 @@ void ecs_enable_id(
ecs_assert(bs != NULL, ECS_INTERNAL_ERROR, NULL);

flecs_bitset_set(bs, ECS_RECORD_TO_ROW(r->row), enable);

flecs_defer_end(world, stage);
error:
return;
}
Expand Down
36 changes: 18 additions & 18 deletions src/storage/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,8 +822,8 @@ void flecs_table_dtor_all(
}
}

static const char *flecs_locked_storage_msg =
"to fix, defer operations with defer_begin/defer_end";
#define FLECS_LOCKED_STORAGE_MSG \
"to fix, defer operations with defer_begin/defer_end"

/* Cleanup table storage */
static
Expand All @@ -835,7 +835,7 @@ void flecs_table_fini_data(
bool is_delete,
bool deactivate)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

if (!data) {
return;
Expand Down Expand Up @@ -937,7 +937,7 @@ void flecs_table_fini(
ecs_table_t *table)
{
bool is_root = table == &world->store.root;
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(is_root || table->id != 0, ECS_INTERNAL_ERROR, NULL);
ecs_assert(is_root || flecs_sparse_is_alive(&world->store.tables, table->id),
ECS_INTERNAL_ERROR, NULL);
Expand Down Expand Up @@ -1008,7 +1008,7 @@ void flecs_table_reset(
ecs_world_t *world,
ecs_table_t *table)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
flecs_table_clear_edges(world, table);
}

Expand Down Expand Up @@ -1049,7 +1049,7 @@ void flecs_table_mark_dirty(
ecs_table_t *table,
ecs_entity_t component)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);

if (table->dirty_state) {
Expand Down Expand Up @@ -1318,7 +1318,7 @@ int32_t flecs_table_append(
bool on_add)
{
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);

Expand Down Expand Up @@ -1430,7 +1430,7 @@ void flecs_table_delete(
{
ecs_assert(world != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);

Expand Down Expand Up @@ -1593,8 +1593,8 @@ void flecs_table_move(
{
ecs_assert(dst_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(src_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

ecs_assert(src_index >= 0, ECS_INTERNAL_ERROR, NULL);
ecs_assert(dst_index >= 0, ECS_INTERNAL_ERROR, NULL);
Expand Down Expand Up @@ -1701,7 +1701,7 @@ int32_t flecs_table_appendn(
int32_t to_add,
const ecs_entity_t *ids)
{
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);
int32_t cur_count = flecs_table_data_count(data);
Expand All @@ -1719,8 +1719,8 @@ void flecs_table_set_size(
ecs_data_t *data,
int32_t size)
{
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(table);

Expand All @@ -1737,8 +1737,8 @@ bool flecs_table_shrink(
ecs_world_t *world,
ecs_table_t *table)
{
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(table != NULL, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
(void)world;

flecs_table_check_sanity(table);
Expand Down Expand Up @@ -1792,7 +1792,7 @@ void flecs_table_swap(
{
(void)world;

ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(row_1 >= 0, ECS_INTERNAL_ERROR, NULL);
ecs_assert(row_2 >= 0, ECS_INTERNAL_ERROR, NULL);

Expand Down Expand Up @@ -2036,8 +2036,8 @@ void flecs_table_merge(
{
ecs_assert(src_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(dst_table != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, flecs_locked_storage_msg);
ecs_assert(!src_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);
ecs_assert(!dst_table->_->lock, ECS_LOCKED_STORAGE, FLECS_LOCKED_STORAGE_MSG);

flecs_table_check_sanity(src_table);
flecs_table_check_sanity(dst_table);
Expand Down
3 changes: 2 additions & 1 deletion test/addons/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@
"run_pipeline_multithreaded",
"run_pipeline_multithreaded_tasks",
"pipeline_init_no_terms",
"pipeline_init_no_system_term"
"pipeline_init_no_system_term",
"disable_component_from_immediate_system"
]
}, {
"id": "SystemMisc",
Expand Down
33 changes: 33 additions & 0 deletions test/addons/src/Pipeline.c
Original file line number Diff line number Diff line change
Expand Up @@ -3213,3 +3213,36 @@ void Pipeline_pipeline_init_no_system_term(void) {
.query.terms = {{ ecs_id(Position) }}
});
}

static ECS_DECLARE(ToggleTag);
static ecs_entity_t toggle_entity = 0;
static int toggle_immediate_system_invoked = 0;

static void ToggleImmediateSystem(ecs_iter_t *it) {
ecs_defer_suspend(it->world);
ecs_enable_id(it->world, toggle_entity, ToggleTag, false);
ecs_defer_resume(it->world);
toggle_immediate_system_invoked ++;
}

void Pipeline_disable_component_from_immediate_system(void) {
ecs_world_t *world = ecs_init();

ECS_ENTITY_DEFINE(world, ToggleTag, CanToggle);

toggle_entity = ecs_new_w(world, ToggleTag);

ecs_system(world, {
.entity = ecs_entity(world, {
.add = ecs_ids(ecs_pair(EcsDependsOn, EcsOnUpdate))
}),
.callback = ToggleImmediateSystem,
.immediate = true
});

ecs_progress(world, 0);
test_int(toggle_immediate_system_invoked, 1);
test_bool(ecs_is_deferred(world), false);

ecs_fini(world);
}

0 comments on commit ae42a42

Please sign in to comment.