Skip to content

Commit

Permalink
Free system/observer ctx/binding_ctx before updating it
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed May 11, 2023
1 parent 9c08d11 commit a13cbd0
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 10 deletions.
48 changes: 44 additions & 4 deletions flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -31387,12 +31387,30 @@ ecs_entity_t ecs_system_init(
if (desc->callback) {
system->action = desc->callback;
}

if (system->ctx_free) {
if (system->ctx && system->ctx != desc->ctx) {
system->ctx_free(system->ctx);
}
}
if (system->binding_ctx_free) {
if (system->binding_ctx && system->binding_ctx != desc->binding_ctx) {
system->binding_ctx_free(system->binding_ctx);
}
}

if (desc->ctx) {
system->ctx = desc->ctx;
}
if (desc->binding_ctx) {
system->binding_ctx = desc->binding_ctx;
}
if (desc->ctx_free) {
system->ctx_free = desc->ctx_free;
}
if (desc->binding_ctx_free) {
system->binding_ctx_free = desc->binding_ctx_free;
}
if (desc->query.filter.instanced) {
ECS_BIT_SET(system->query->filter.flags, EcsFilterIsInstanced);
}
Expand Down Expand Up @@ -52217,15 +52235,37 @@ ecs_entity_t ecs_observer_init(
ecs_get_name(world, entity));
}
} else {
/* If existing entity handle was provided, override existing params */
ecs_observer_t *observer = ecs_poly(poly->poly, ecs_observer_t);

if (desc->run) {
observer->run = desc->run;
}
if (desc->callback) {
ecs_poly(poly->poly, ecs_observer_t)->callback = desc->callback;
observer->callback = desc->callback;
}

if (observer->ctx_free) {
if (observer->ctx && observer->ctx != desc->ctx) {
observer->ctx_free(observer->ctx);
}
}
if (observer->binding_ctx_free) {
if (observer->binding_ctx && observer->binding_ctx != desc->binding_ctx) {
observer->binding_ctx_free(observer->binding_ctx);
}
}

if (desc->ctx) {
ecs_poly(poly->poly, ecs_observer_t)->ctx = desc->ctx;
observer->ctx = desc->ctx;
}
if (desc->binding_ctx) {
ecs_poly(poly->poly, ecs_observer_t)->binding_ctx = desc->binding_ctx;
observer->binding_ctx = desc->binding_ctx;
}
if (desc->ctx_free) {
observer->ctx_free = desc->ctx_free;
}
if (desc->binding_ctx_free) {
observer->binding_ctx_free = desc->binding_ctx_free;
}
}

Expand Down
18 changes: 18 additions & 0 deletions src/addons/system/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,30 @@ ecs_entity_t ecs_system_init(
if (desc->callback) {
system->action = desc->callback;
}

if (system->ctx_free) {
if (system->ctx && system->ctx != desc->ctx) {
system->ctx_free(system->ctx);
}
}
if (system->binding_ctx_free) {
if (system->binding_ctx && system->binding_ctx != desc->binding_ctx) {
system->binding_ctx_free(system->binding_ctx);
}
}

if (desc->ctx) {
system->ctx = desc->ctx;
}
if (desc->binding_ctx) {
system->binding_ctx = desc->binding_ctx;
}
if (desc->ctx_free) {
system->ctx_free = desc->ctx_free;
}
if (desc->binding_ctx_free) {
system->binding_ctx_free = desc->binding_ctx_free;
}
if (desc->query.filter.instanced) {
ECS_BIT_SET(system->query->filter.flags, EcsFilterIsInstanced);
}
Expand Down
30 changes: 26 additions & 4 deletions src/observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,15 +907,37 @@ ecs_entity_t ecs_observer_init(
ecs_get_name(world, entity));
}
} else {
/* If existing entity handle was provided, override existing params */
ecs_observer_t *observer = ecs_poly(poly->poly, ecs_observer_t);

if (desc->run) {
observer->run = desc->run;
}
if (desc->callback) {
ecs_poly(poly->poly, ecs_observer_t)->callback = desc->callback;
observer->callback = desc->callback;
}

if (observer->ctx_free) {
if (observer->ctx && observer->ctx != desc->ctx) {
observer->ctx_free(observer->ctx);
}
}
if (observer->binding_ctx_free) {
if (observer->binding_ctx && observer->binding_ctx != desc->binding_ctx) {
observer->binding_ctx_free(observer->binding_ctx);
}
}

if (desc->ctx) {
ecs_poly(poly->poly, ecs_observer_t)->ctx = desc->ctx;
observer->ctx = desc->ctx;
}
if (desc->binding_ctx) {
ecs_poly(poly->poly, ecs_observer_t)->binding_ctx = desc->binding_ctx;
observer->binding_ctx = desc->binding_ctx;
}
if (desc->ctx_free) {
observer->ctx_free = desc->ctx_free;
}
if (desc->binding_ctx_free) {
observer->binding_ctx_free = desc->binding_ctx_free;
}
}

Expand Down
1 change: 1 addition & 0 deletions test/addons/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@
"delete_system",
"delete_pipeline_system",
"delete_system_w_ctx",
"update_ctx",
"run_custom_run_action",
"run_w_offset_limit_custom_run_action",
"pipeline_custom_run_action",
Expand Down
69 changes: 69 additions & 0 deletions test/addons/src/SystemMisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,20 @@ void binding_ctx_free(void *ctx) {
binding_ctx_value ++;
}

static int ctx_value_2;
static
void ctx_free_2(void *ctx) {
test_assert(&ctx_value_2 == ctx);
ctx_value_2 ++;
}

static int binding_ctx_value_2;
static
void binding_ctx_free_2(void *ctx) {
test_assert(&binding_ctx_value_2 == ctx);
binding_ctx_value_2 ++;
}

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

Expand Down Expand Up @@ -1347,6 +1361,61 @@ void SystemMisc_delete_system_w_ctx() {
ecs_fini(world);
}

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

ECS_TAG(world, Tag);

ecs_entity_t system = ecs_system_init(world, &(ecs_system_desc_t){
.query.filter.terms = {{.id = Tag}},
.callback = Dummy,
.ctx = &ctx_value,
.ctx_free = ctx_free,
.binding_ctx = &binding_ctx_value,
.binding_ctx_free = binding_ctx_free
});
test_assert(system != 0);

test_assert(ecs_get_system_ctx(world, system) == &ctx_value);
test_assert(ecs_get_system_binding_ctx(world, system)
== &binding_ctx_value);

ecs_system(world, {
.entity = system,
.ctx = &ctx_value,
.ctx_free = ctx_free,
.binding_ctx = &binding_ctx_value,
.binding_ctx_free = binding_ctx_free
});

test_int(ctx_value, 0);
test_int(binding_ctx_value, 0);
test_int(ctx_value_2, 0);
test_int(binding_ctx_value_2, 0);

ecs_system(world, {
.entity = system,
.ctx = &ctx_value_2,
.ctx_free = ctx_free_2,
.binding_ctx = &binding_ctx_value_2,
.binding_ctx_free = binding_ctx_free_2
});

test_int(ctx_value, 1);
test_int(binding_ctx_value, 1);
test_int(ctx_value_2, 0);
test_int(binding_ctx_value_2, 0);

ecs_delete(world, system);

test_int(ctx_value, 1);
test_int(binding_ctx_value, 1);
test_int(ctx_value_2, 1);
test_int(binding_ctx_value_2, 1);

ecs_fini(world);
}

static int run_invoked = 0;

static void Run(ecs_iter_t *it) {
Expand Down
7 changes: 6 additions & 1 deletion test/addons/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ void SystemMisc_deactivate_after_disable(void);
void SystemMisc_delete_system(void);
void SystemMisc_delete_pipeline_system(void);
void SystemMisc_delete_system_w_ctx(void);
void SystemMisc_update_ctx(void);
void SystemMisc_run_custom_run_action(void);
void SystemMisc_run_w_offset_limit_custom_run_action(void);
void SystemMisc_pipeline_custom_run_action(void);
Expand Down Expand Up @@ -3639,6 +3640,10 @@ bake_test_case SystemMisc_testcases[] = {
"delete_system_w_ctx",
SystemMisc_delete_system_w_ctx
},
{
"update_ctx",
SystemMisc_update_ctx
},
{
"run_custom_run_action",
SystemMisc_run_custom_run_action
Expand Down Expand Up @@ -6652,7 +6657,7 @@ static bake_test_suite suites[] = {
"SystemMisc",
NULL,
NULL,
62,
63,
SystemMisc_testcases
},
{
Expand Down
1 change: 1 addition & 0 deletions test/api/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -1927,6 +1927,7 @@
"add_after_delete_observer",
"remove_after_delete_observer",
"delete_observer_w_ctx",
"update_ctx",
"filter_w_strings",
"iter_type_set",
"readonly_term",
Expand Down
71 changes: 71 additions & 0 deletions test/api/src/Observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,20 @@ void binding_ctx_free(void *ctx) {
binding_ctx_value ++;
}

static int ctx_value_2;
static
void ctx_free_2(void *ctx) {
test_assert(&ctx_value_2 == ctx);
ctx_value_2 ++;
}

static int binding_ctx_value_2;
static
void binding_ctx_free_2(void *ctx) {
test_assert(&binding_ctx_value_2 == ctx);
binding_ctx_value_2 ++;
}

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

Expand Down Expand Up @@ -1266,6 +1280,62 @@ void Observer_delete_observer_w_ctx() {
ecs_fini(world);
}

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

ECS_TAG(world, Tag);

ecs_entity_t system = ecs_observer(world, {
.filter.terms = {{.id = Tag}},
.callback = Dummy,
.events = {EcsOnAdd},
.ctx = &ctx_value,
.ctx_free = ctx_free,
.binding_ctx = &binding_ctx_value,
.binding_ctx_free = binding_ctx_free
});
test_assert(system != 0);

test_assert(ecs_get_observer_ctx(world, system) == &ctx_value);
test_assert(ecs_get_observer_binding_ctx(world, system)
== &binding_ctx_value);

ecs_observer(world, {
.entity = system,
.ctx = &ctx_value,
.ctx_free = ctx_free,
.binding_ctx = &binding_ctx_value,
.binding_ctx_free = binding_ctx_free
});

test_int(ctx_value, 0);
test_int(binding_ctx_value, 0);
test_int(ctx_value_2, 0);
test_int(binding_ctx_value_2, 0);

ecs_observer(world, {
.entity = system,
.ctx = &ctx_value_2,
.ctx_free = ctx_free_2,
.binding_ctx = &binding_ctx_value_2,
.binding_ctx_free = binding_ctx_free_2
});

test_int(ctx_value, 1);
test_int(binding_ctx_value, 1);
test_int(ctx_value_2, 0);
test_int(binding_ctx_value_2, 0);

ecs_delete(world, system);

test_int(ctx_value, 1);
test_int(binding_ctx_value, 1);
test_int(ctx_value_2, 1);
test_int(binding_ctx_value_2, 1);

ecs_fini(world);
}

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

Expand Down Expand Up @@ -4735,3 +4805,4 @@ void Observer_notify_after_defer_batched_2_entities_in_table_w_tgt() {

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 @@ -1856,6 +1856,7 @@ void Observer_2_terms_on_remove_on_delete(void);
void Observer_add_after_delete_observer(void);
void Observer_remove_after_delete_observer(void);
void Observer_delete_observer_w_ctx(void);
void Observer_update_ctx(void);
void Observer_filter_w_strings(void);
void Observer_iter_type_set(void);
void Observer_readonly_term(void);
Expand Down Expand Up @@ -9739,6 +9740,10 @@ bake_test_case Observer_testcases[] = {
"delete_observer_w_ctx",
Observer_delete_observer_w_ctx
},
{
"update_ctx",
Observer_update_ctx
},
{
"filter_w_strings",
Observer_filter_w_strings
Expand Down Expand Up @@ -12609,7 +12614,7 @@ static bake_test_suite suites[] = {
"Observer",
NULL,
NULL,
109,
110,
Observer_testcases
},
{
Expand Down

0 comments on commit a13cbd0

Please sign in to comment.