Skip to content

Commit

Permalink
Fix issue with creating user space observers for table only events
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed May 17, 2023
1 parent 82248b8 commit 5e89c27
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 9 deletions.
6 changes: 4 additions & 2 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -51631,7 +51631,8 @@ void flecs_observer_invoke(

bool instanced = filter->flags & EcsFilterIsInstanced;
bool match_this = filter->flags & EcsFilterMatchThis;
if (match_this && (simple_result || instanced)) {
bool table_only = it->flags & EcsIterTableOnly;
if (match_this && (simple_result || instanced || table_only)) {
callback(it);
} else {
ecs_entity_t observer_src = term->src.id;
Expand Down Expand Up @@ -51778,6 +51779,7 @@ bool flecs_multi_observer_invoke(ecs_iter_t *it) {
user_it.ptrs = NULL;

flecs_iter_init(it->world, &user_it, flecs_iter_cache_all);
user_it.flags |= (it->flags & EcsIterTableOnly);

ecs_table_t *table = it->table;
ecs_table_t *prev_table = it->other_table;
Expand Down Expand Up @@ -57333,7 +57335,7 @@ void flecs_iter_populate_data(
it->offset = offset;
it->count = count;
if (table) {
ecs_assert(count != 0 || !ecs_table_count(table),
ecs_assert(count != 0 || !ecs_table_count(table) || (it->flags & EcsIterTableOnly),
ECS_INTERNAL_ERROR, NULL);
if (count) {
it->entities = ecs_vec_get_t(
Expand Down
4 changes: 2 additions & 2 deletions flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@ extern "C" {
#define EcsIterProfile (1u << 11u) /* Profile iterator performance */

////////////////////////////////////////////////////////////////////////////////
//// Filter flags (used by ecs_filter_t::flags)
//// Event flags (used by ecs_event_decs_t::flags)
////////////////////////////////////////////////////////////////////////////////

#define EcsEventTableOnly (1u << 8u) /* Table event (no data, same as iter flags) */
#define EcsEventTableOnly (1u << 4u) /* Table event (no data, same as iter flags) */
#define EcsEventNoOnSet (1u << 16u) /* Don't emit OnSet/UnSet for inherited ids */

////////////////////////////////////////////////////////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions include/flecs/private/api_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ extern "C" {
#define EcsIterProfile (1u << 11u) /* Profile iterator performance */

////////////////////////////////////////////////////////////////////////////////
//// Filter flags (used by ecs_filter_t::flags)
//// Event flags (used by ecs_event_decs_t::flags)
////////////////////////////////////////////////////////////////////////////////

#define EcsEventTableOnly (1u << 8u) /* Table event (no data, same as iter flags) */
#define EcsEventTableOnly (1u << 4u) /* Table event (no data, same as iter flags) */
#define EcsEventNoOnSet (1u << 16u) /* Don't emit OnSet/UnSet for inherited ids */

////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion src/iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ void flecs_iter_populate_data(
it->offset = offset;
it->count = count;
if (table) {
ecs_assert(count != 0 || !ecs_table_count(table),
ecs_assert(count != 0 || !ecs_table_count(table) || (it->flags & EcsIterTableOnly),
ECS_INTERNAL_ERROR, NULL);
if (count) {
it->entities = ecs_vec_get_t(
Expand Down
4 changes: 3 additions & 1 deletion src/observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ void flecs_observer_invoke(

bool instanced = filter->flags & EcsFilterIsInstanced;
bool match_this = filter->flags & EcsFilterMatchThis;
if (match_this && (simple_result || instanced)) {
bool table_only = it->flags & EcsIterTableOnly;
if (match_this && (simple_result || instanced || table_only)) {
callback(it);
} else {
ecs_entity_t observer_src = term->src.id;
Expand Down Expand Up @@ -427,6 +428,7 @@ bool flecs_multi_observer_invoke(ecs_iter_t *it) {
user_it.ptrs = NULL;

flecs_iter_init(it->world, &user_it, flecs_iter_cache_all);
user_it.flags |= (it->flags & EcsIterTableOnly);

ecs_table_t *table = it->table;
ecs_table_t *prev_table = it->other_table;
Expand Down
1 change: 1 addition & 0 deletions test/api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1995,6 +1995,7 @@
"notify_after_defer_batched",
"notify_after_defer_batched_2_entities_in_table",
"notify_after_defer_batched_2_entities_in_table_w_tgt",
"multi_observer_table_fill_w_singleton",
"cache_test_1",
"cache_test_2",
"cache_test_3",
Expand Down
31 changes: 31 additions & 0 deletions test/api/src/Observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -4806,3 +4806,34 @@ void Observer_notify_after_defer_batched_2_entities_in_table_w_tgt() {
ecs_fini(world);
}

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

ECS_COMPONENT(world, Position);
ECS_COMPONENT(world, Velocity);

Probe ctx = {0};

ecs_observer(world, {
.filter.terms = {
{ .id = ecs_id(Position), .src.flags = EcsIsEntity, .src.id = ecs_id(Position) },
{ .id = ecs_id(Velocity) },
},
.filter.flags = EcsFilterNoData,
.callback = Observer,
.events = { EcsOnTableFill },
.ctx = &ctx
});

ecs_singleton_add(world, Position);
test_int(ctx.invoked, 0);

ecs_entity_t e = ecs_new_id(world);
ecs_add(world, e, Velocity);
test_int(ctx.invoked, 0);

ecs_run_aperiodic(world, 0);
test_int(ctx.invoked, 1);

ecs_fini(world);
}
7 changes: 6 additions & 1 deletion test/api/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1924,6 +1924,7 @@ void Observer_filter_observer_after_observer(void);
void Observer_notify_after_defer_batched(void);
void Observer_notify_after_defer_batched_2_entities_in_table(void);
void Observer_notify_after_defer_batched_2_entities_in_table_w_tgt(void);
void Observer_multi_observer_table_fill_w_singleton(void);
void Observer_cache_test_1(void);
void Observer_cache_test_2(void);
void Observer_cache_test_3(void);
Expand Down Expand Up @@ -10013,6 +10014,10 @@ bake_test_case Observer_testcases[] = {
"notify_after_defer_batched_2_entities_in_table_w_tgt",
Observer_notify_after_defer_batched_2_entities_in_table_w_tgt
},
{
"multi_observer_table_fill_w_singleton",
Observer_multi_observer_table_fill_w_singleton
},
{
"cache_test_1",
Observer_cache_test_1
Expand Down Expand Up @@ -12619,7 +12624,7 @@ static bake_test_suite suites[] = {
"Observer",
NULL,
NULL,
110,
111,
Observer_testcases
},
{
Expand Down

0 comments on commit 5e89c27

Please sign in to comment.