Skip to content

Commit de96203

Browse files
#1600 Remove ordering guarantee between batched OnAdd/on_set on different components
1 parent dd7aa89 commit de96203

File tree

7 files changed

+5
-217
lines changed

7 files changed

+5
-217
lines changed

distr/flecs.c

Lines changed: 2 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -9299,51 +9299,6 @@ bool flecs_remove_invalid(
92999299
return true;
93009300
}
93019301

9302-
static
9303-
ecs_table_t* flecs_cmd_batch_add_diff(
9304-
ecs_world_t *world,
9305-
ecs_table_t *dst,
9306-
ecs_table_t *cur,
9307-
ecs_table_t *prev)
9308-
{
9309-
int32_t p = 0, p_count = prev->type.count;
9310-
int32_t c = 0, c_count = cur->type.count;
9311-
ecs_id_t *p_ids = prev->type.array;
9312-
ecs_id_t *c_ids = cur->type.array;
9313-
9314-
for (; c < c_count;) {
9315-
ecs_id_t c_id = c_ids[c];
9316-
ecs_id_t p_id = p_ids[p];
9317-
9318-
if (p_id < c_id) {
9319-
/* Previous id no longer exists in new table, so it was removed */
9320-
dst = ecs_table_remove_id(world, dst, p_id);
9321-
}
9322-
if (c_id < p_id) {
9323-
/* Current id didn't exist in previous table, so it was added */
9324-
dst = ecs_table_add_id(world, dst, c_id);
9325-
}
9326-
9327-
c += c_id <= p_id;
9328-
p += p_id <= c_id;
9329-
if (p == p_count) {
9330-
break;
9331-
}
9332-
}
9333-
9334-
/* Remainder */
9335-
for (; p < p_count; p ++) {
9336-
ecs_id_t p_id = p_ids[p];
9337-
dst = ecs_table_remove_id(world, dst, p_id);
9338-
}
9339-
for (; c < c_count; c ++) {
9340-
ecs_id_t c_id = c_ids[c];
9341-
dst = ecs_table_add_id(world, dst, c_id);
9342-
}
9343-
9344-
return dst;
9345-
}
9346-
93479302
static
93489303
void flecs_cmd_batch_for_entity(
93499304
ecs_world_t *world,
@@ -9414,43 +9369,6 @@ void flecs_cmd_batch_for_entity(
94149369
table = flecs_find_table_add(world, table, id, diff);
94159370
world->info.cmd.batched_command_count ++;
94169371
break;
9417-
case EcsCmdModified: {
9418-
/* If a modified was inserted for an existing component, the value
9419-
* of the component could have been changed. If this is the case,
9420-
* call on_set hooks before the OnAdd/OnRemove observers are invoked
9421-
* when moving the entity to a different table.
9422-
* This ensures that if OnAdd/OnRemove observers access the modified
9423-
* component value, the on_set hook has had the opportunity to
9424-
* run first to set any computed values of the component. */
9425-
int32_t row = ECS_RECORD_TO_ROW(r->row);
9426-
ecs_id_record_t *idr = flecs_id_record_get(world, cmd->id);
9427-
const ecs_table_record_t *tr =
9428-
flecs_id_record_get_table(idr, start_table);
9429-
if (tr) {
9430-
const ecs_type_info_t *ti = idr->type_info;
9431-
ecs_iter_action_t on_set;
9432-
if ((on_set = ti->hooks.on_set)) {
9433-
ecs_table_t *prev_table = r->table;
9434-
ecs_defer_begin(world);
9435-
flecs_invoke_hook(world, start_table, tr, 1, row,
9436-
&entity,cmd->id, ti, EcsOnSet, on_set);
9437-
ecs_defer_end(world);
9438-
9439-
/* Don't run on_set hook twice, but make sure to still
9440-
* invoke observers. */
9441-
cmd->kind = EcsCmdModifiedNoHook;
9442-
9443-
/* If entity changed tables in hook, add difference to
9444-
* destination table, so we don't lose the side effects
9445-
* of the hook. */
9446-
if (r->table != prev_table) {
9447-
table = flecs_cmd_batch_add_diff(
9448-
world, table, r->table, prev_table);
9449-
}
9450-
}
9451-
}
9452-
break;
9453-
}
94549372
case EcsCmdSet:
94559373
case EcsCmdEnsure: {
94569374
ecs_id_t *ids = diff->added.array;
@@ -9505,6 +9423,7 @@ void flecs_cmd_batch_for_entity(
95059423
case EcsCmdEvent:
95069424
case EcsCmdSkip:
95079425
case EcsCmdModifiedNoHook:
9426+
case EcsCmdModified:
95089427
break;
95099428
}
95109429

@@ -16418,7 +16337,7 @@ bool flecs_defer_modified(
1641816337
ecs_id_t id)
1641916338
{
1642016339
if (flecs_defer_cmd(stage)) {
16421-
ecs_cmd_t *cmd = flecs_cmd_new_batched(stage, entity);
16340+
ecs_cmd_t *cmd = flecs_cmd_new(stage);
1642216341
if (cmd) {
1642316342
cmd->kind = EcsCmdModified;
1642416343
cmd->id = id;
@@ -67971,8 +67890,6 @@ ecs_var_id_t flecs_query_find_var_id(
6797167890
if (query->pub.flags & EcsQueryHasTableThisVar) {
6797267891
return 0;
6797367892
} else {
67974-
printf("VARNONE\n");
67975-
flecs_dump_backtrace(stdout);
6797667893
return EcsVarNone;
6797767894
}
6797867895
}

src/entity.c

Lines changed: 1 addition & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4694,51 +4694,6 @@ bool flecs_remove_invalid(
46944694
return true;
46954695
}
46964696

4697-
static
4698-
ecs_table_t* flecs_cmd_batch_add_diff(
4699-
ecs_world_t *world,
4700-
ecs_table_t *dst,
4701-
ecs_table_t *cur,
4702-
ecs_table_t *prev)
4703-
{
4704-
int32_t p = 0, p_count = prev->type.count;
4705-
int32_t c = 0, c_count = cur->type.count;
4706-
ecs_id_t *p_ids = prev->type.array;
4707-
ecs_id_t *c_ids = cur->type.array;
4708-
4709-
for (; c < c_count;) {
4710-
ecs_id_t c_id = c_ids[c];
4711-
ecs_id_t p_id = p_ids[p];
4712-
4713-
if (p_id < c_id) {
4714-
/* Previous id no longer exists in new table, so it was removed */
4715-
dst = ecs_table_remove_id(world, dst, p_id);
4716-
}
4717-
if (c_id < p_id) {
4718-
/* Current id didn't exist in previous table, so it was added */
4719-
dst = ecs_table_add_id(world, dst, c_id);
4720-
}
4721-
4722-
c += c_id <= p_id;
4723-
p += p_id <= c_id;
4724-
if (p == p_count) {
4725-
break;
4726-
}
4727-
}
4728-
4729-
/* Remainder */
4730-
for (; p < p_count; p ++) {
4731-
ecs_id_t p_id = p_ids[p];
4732-
dst = ecs_table_remove_id(world, dst, p_id);
4733-
}
4734-
for (; c < c_count; c ++) {
4735-
ecs_id_t c_id = c_ids[c];
4736-
dst = ecs_table_add_id(world, dst, c_id);
4737-
}
4738-
4739-
return dst;
4740-
}
4741-
47424697
static
47434698
void flecs_cmd_batch_for_entity(
47444699
ecs_world_t *world,
@@ -4809,43 +4764,6 @@ void flecs_cmd_batch_for_entity(
48094764
table = flecs_find_table_add(world, table, id, diff);
48104765
world->info.cmd.batched_command_count ++;
48114766
break;
4812-
case EcsCmdModified: {
4813-
/* If a modified was inserted for an existing component, the value
4814-
* of the component could have been changed. If this is the case,
4815-
* call on_set hooks before the OnAdd/OnRemove observers are invoked
4816-
* when moving the entity to a different table.
4817-
* This ensures that if OnAdd/OnRemove observers access the modified
4818-
* component value, the on_set hook has had the opportunity to
4819-
* run first to set any computed values of the component. */
4820-
int32_t row = ECS_RECORD_TO_ROW(r->row);
4821-
ecs_id_record_t *idr = flecs_id_record_get(world, cmd->id);
4822-
const ecs_table_record_t *tr =
4823-
flecs_id_record_get_table(idr, start_table);
4824-
if (tr) {
4825-
const ecs_type_info_t *ti = idr->type_info;
4826-
ecs_iter_action_t on_set;
4827-
if ((on_set = ti->hooks.on_set)) {
4828-
ecs_table_t *prev_table = r->table;
4829-
ecs_defer_begin(world);
4830-
flecs_invoke_hook(world, start_table, tr, 1, row,
4831-
&entity,cmd->id, ti, EcsOnSet, on_set);
4832-
ecs_defer_end(world);
4833-
4834-
/* Don't run on_set hook twice, but make sure to still
4835-
* invoke observers. */
4836-
cmd->kind = EcsCmdModifiedNoHook;
4837-
4838-
/* If entity changed tables in hook, add difference to
4839-
* destination table, so we don't lose the side effects
4840-
* of the hook. */
4841-
if (r->table != prev_table) {
4842-
table = flecs_cmd_batch_add_diff(
4843-
world, table, r->table, prev_table);
4844-
}
4845-
}
4846-
}
4847-
break;
4848-
}
48494767
case EcsCmdSet:
48504768
case EcsCmdEnsure: {
48514769
ecs_id_t *ids = diff->added.array;
@@ -4900,6 +4818,7 @@ void flecs_cmd_batch_for_entity(
49004818
case EcsCmdEvent:
49014819
case EcsCmdSkip:
49024820
case EcsCmdModifiedNoHook:
4821+
case EcsCmdModified:
49034822
break;
49044823
}
49054824

src/query/compiler/compiler_term.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ ecs_var_id_t flecs_query_find_var_id(
1919
if (query->pub.flags & EcsQueryHasTableThisVar) {
2020
return 0;
2121
} else {
22-
printf("VARNONE\n");
23-
flecs_dump_backtrace(stdout);
2422
return EcsVarNone;
2523
}
2624
}

src/stage.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ bool flecs_defer_modified(
175175
ecs_id_t id)
176176
{
177177
if (flecs_defer_cmd(stage)) {
178-
ecs_cmd_t *cmd = flecs_cmd_new_batched(stage, entity);
178+
ecs_cmd_t *cmd = flecs_cmd_new(stage);
179179
if (cmd) {
180180
cmd->kind = EcsCmdModified;
181181
cmd->id = id;

test/core/project.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2261,7 +2261,6 @@
22612261
"ensure_override",
22622262
"set_override",
22632263
"absent_ensure_for_entity_w_tag",
2264-
"on_set_hook_before_on_add_for_existing_component",
22652264
"defer_2_sets_w_observer_same_component",
22662265
"defer_2_sets_w_observer_other_component",
22672266
"on_remove_after_deferred_clear_and_add",

test/core/src/Commands.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3742,7 +3742,6 @@ void Commands_absent_ensure_for_entity_w_tag(void) {
37423742

37433743
static int set_position_invoked = 0;
37443744
static int set_velocity_invoked = 0;
3745-
static int add_tag_invoked = 0;
37463745

37473746
static void set_position_hook(ecs_iter_t *it) {
37483747
set_position_invoked ++;
@@ -3752,45 +3751,6 @@ static void set_velocity_hook(ecs_iter_t *it) {
37523751
set_velocity_invoked ++;
37533752
}
37543753

3755-
static void add_tag(ecs_iter_t *it) {
3756-
test_int(set_position_invoked, 1);
3757-
add_tag_invoked ++;
3758-
}
3759-
3760-
void Commands_on_set_hook_before_on_add_for_existing_component(void) {
3761-
ecs_world_t *world = ecs_mini();
3762-
3763-
ECS_COMPONENT(world, Position);
3764-
ECS_TAG(world, TagA);
3765-
ECS_TAG(world, TagB);
3766-
3767-
ecs_set_hooks(world, Position, {
3768-
.on_set = set_position_hook
3769-
});
3770-
3771-
ecs_observer(world, {
3772-
.query.terms[0].id = TagA,
3773-
.events = { EcsOnAdd },
3774-
.callback = add_tag
3775-
});
3776-
3777-
ecs_entity_t e = ecs_new_w(world, Position);
3778-
3779-
ecs_defer_begin(world);
3780-
ecs_add(world, e, TagB); /* 2 add commands, to trigger batching */
3781-
ecs_modified(world, e, Position);
3782-
ecs_add(world, e, TagA);
3783-
3784-
test_int(set_position_invoked, 0);
3785-
test_int(add_tag_invoked, 0);
3786-
ecs_defer_end(world);
3787-
3788-
test_assert(set_position_invoked != 0);
3789-
test_int(add_tag_invoked, 1);
3790-
3791-
ecs_fini(world);
3792-
}
3793-
37943754
void Commands_defer_2_sets_w_observer_same_component(void) {
37953755
ecs_world_t *world = ecs_mini();
37963756

test/core/src/main.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,6 @@ void Commands_defer_existing_ensure_no_on_set(void);
21802180
void Commands_ensure_override(void);
21812181
void Commands_set_override(void);
21822182
void Commands_absent_ensure_for_entity_w_tag(void);
2183-
void Commands_on_set_hook_before_on_add_for_existing_component(void);
21842183
void Commands_defer_2_sets_w_observer_same_component(void);
21852184
void Commands_defer_2_sets_w_observer_other_component(void);
21862185
void Commands_on_remove_after_deferred_clear_and_add(void);
@@ -10831,10 +10830,6 @@ bake_test_case Commands_testcases[] = {
1083110830
"absent_ensure_for_entity_w_tag",
1083210831
Commands_absent_ensure_for_entity_w_tag
1083310832
},
10834-
{
10835-
"on_set_hook_before_on_add_for_existing_component",
10836-
Commands_on_set_hook_before_on_add_for_existing_component
10837-
},
1083810833
{
1083910834
"defer_2_sets_w_observer_same_component",
1084010835
Commands_defer_2_sets_w_observer_same_component
@@ -11850,7 +11845,7 @@ static bake_test_suite suites[] = {
1185011845
"Commands",
1185111846
NULL,
1185211847
NULL,
11853-
156,
11848+
155,
1185411849
Commands_testcases
1185511850
},
1185611851
{

0 commit comments

Comments
 (0)