Skip to content

Commit

Permalink
Fix issue with raising an alert for a previously cleared source
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Jun 5, 2023
1 parent a63116a commit 6b67d7a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 12 deletions.
10 changes: 5 additions & 5 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19720,16 +19720,16 @@ void MonitorAlertInstances(ecs_iter_t *it) {

int32_t i, count = it->count;
for (i = 0; i < count; i ++) {
ecs_entity_t e = it->entities[i];
ecs_entity_t s = source[i].entity;
ecs_entity_t ai = it->entities[i];
ecs_entity_t e = source[i].entity;

value[i].value += (double)it->delta_system_time;

/* Check if alert instance still matches rule */
ecs_iter_t rit = ecs_rule_iter(world, rule);
rit.flags |= EcsIterNoData;
rit.flags |= EcsIterIsInstanced;
ecs_iter_set_var(&rit, 0, s);
ecs_iter_set_var(&rit, 0, e);

if (ecs_rule_next(&rit)) {
bool generate_message = alert->message;
Expand Down Expand Up @@ -19758,9 +19758,9 @@ void MonitorAlertInstances(ecs_iter_t *it) {
}

/* Alert instance no longer matches rule, remove it */
flecs_alerts_remove_alert_from_src(world, s, parent);
flecs_alerts_remove_alert_from_src(world, e, parent);
ecs_map_remove(&alert->instances, e);
ecs_delete(world, e);
ecs_delete(world, ai);
}

ecs_vars_fini(&vars);
Expand Down
10 changes: 5 additions & 5 deletions src/addons/alerts.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,16 @@ void MonitorAlertInstances(ecs_iter_t *it) {

int32_t i, count = it->count;
for (i = 0; i < count; i ++) {
ecs_entity_t e = it->entities[i];
ecs_entity_t s = source[i].entity;
ecs_entity_t ai = it->entities[i];
ecs_entity_t e = source[i].entity;

value[i].value += (double)it->delta_system_time;

/* Check if alert instance still matches rule */
ecs_iter_t rit = ecs_rule_iter(world, rule);
rit.flags |= EcsIterNoData;
rit.flags |= EcsIterIsInstanced;
ecs_iter_set_var(&rit, 0, s);
ecs_iter_set_var(&rit, 0, e);

if (ecs_rule_next(&rit)) {
bool generate_message = alert->message;
Expand Down Expand Up @@ -195,9 +195,9 @@ void MonitorAlertInstances(ecs_iter_t *it) {
}

/* Alert instance no longer matches rule, remove it */
flecs_alerts_remove_alert_from_src(world, s, parent);
flecs_alerts_remove_alert_from_src(world, e, parent);
ecs_map_remove(&alert->instances, e);
ecs_delete(world, e);
ecs_delete(world, ai);
}

ecs_vars_fini(&vars);
Expand Down
3 changes: 2 additions & 1 deletion test/addons/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1557,7 +1557,8 @@
"alert_message_w_var",
"alert_message_w_changed_var",
"set_brief",
"alert_instance_has_doc_name"
"alert_instance_has_doc_name",
"reraise_alert"
]
}]
}
Expand Down
83 changes: 83 additions & 0 deletions test/addons/src/Alerts.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,3 +545,86 @@ void Alerts_alert_instance_has_doc_name() {

ecs_fini(world);
}

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

ECS_IMPORT(world, FlecsAlerts);

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

ecs_entity_t e1 = ecs_new_entity(world, "e1");

ecs_add(world, e1, Position);

ecs_entity_t alert = ecs_alert(world, {
.entity = ecs_new_entity(world, "position_without_velocity"),
.filter.expr = "Position, !Velocity"
});
test_assert(alert != 0);

ecs_progress(world, 1.0);

test_assert(ecs_has(world, e1, EcsAlertsActive));
test_int(ecs_count(world, EcsAlertInstance), 1);
{
test_assert(ecs_get_alert_count(world, e1, alert) == 1);

ecs_filter_t *alerts = ecs_filter(world, { .expr = "flecs.alerts.Instance" });
ecs_iter_t it = ecs_filter_iter(world, alerts);
test_bool(ecs_filter_next(&it), true);
test_int(it.count, 1);

test_assert(it.entities[0] != 0);
test_assert(ecs_get_parent(world, it.entities[0]) == alert);
const EcsAlertInstance *instance = ecs_get(world, it.entities[0], EcsAlertInstance);
test_assert(instance != NULL);

const EcsMetricSource *source = ecs_get(world, it.entities[0], EcsMetricSource);
test_assert(source != NULL);
test_int(source->entity, e1);

test_bool(ecs_filter_next(&it), false);
ecs_filter_fini(alerts);
}

/* Clear the alert */
ecs_add(world, e1, Velocity);

ecs_progress(world, 1.0);

/* Verify the alert has cleared */
test_assert(!ecs_has(world, e1, EcsAlertsActive));

/* Reraise the alert */
ecs_remove(world, e1, Velocity);

ecs_progress(world, 1.0);

/* Verify the alert has been raised again */
test_assert(ecs_has(world, e1, EcsAlertsActive));
test_int(ecs_count(world, EcsAlertInstance), 1);
{
test_assert(ecs_get_alert_count(world, e1, alert) == 1);

ecs_filter_t *alerts = ecs_filter(world, { .expr = "flecs.alerts.Instance" });
ecs_iter_t it = ecs_filter_iter(world, alerts);
test_bool(ecs_filter_next(&it), true);
test_int(it.count, 1);

test_assert(it.entities[0] != 0);
test_assert(ecs_get_parent(world, it.entities[0]) == alert);
const EcsAlertInstance *instance = ecs_get(world, it.entities[0], EcsAlertInstance);
test_assert(instance != NULL);

const EcsMetricSource *source = ecs_get(world, it.entities[0], EcsMetricSource);
test_assert(source != NULL);
test_int(source->entity, e1);

test_bool(ecs_filter_next(&it), false);
ecs_filter_fini(alerts);
}

ecs_fini(world);
}
7 changes: 6 additions & 1 deletion test/addons/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,7 @@ void Alerts_alert_message_w_var(void);
void Alerts_alert_message_w_changed_var(void);
void Alerts_set_brief(void);
void Alerts_alert_instance_has_doc_name(void);
void Alerts_reraise_alert(void);

bake_test_case Parser_testcases[] = {
{
Expand Down Expand Up @@ -7188,6 +7189,10 @@ bake_test_case Alerts_testcases[] = {
{
"alert_instance_has_doc_name",
Alerts_alert_instance_has_doc_name
},
{
"reraise_alert",
Alerts_reraise_alert
}
};

Expand Down Expand Up @@ -7434,7 +7439,7 @@ static bake_test_suite suites[] = {
"Alerts",
NULL,
NULL,
8,
9,
Alerts_testcases
}
};
Expand Down

0 comments on commit 6b67d7a

Please sign in to comment.