Skip to content

Commit e75f6f0

Browse files
committed
#788 call on_add hook for emplace
1 parent f461b4f commit e75f6f0

File tree

11 files changed

+197
-57
lines changed

11 files changed

+197
-57
lines changed

flecs.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,8 @@ int32_t flecs_table_append(
12691269
ecs_table_t *table,
12701270
ecs_entity_t entity,
12711271
ecs_record_t *record,
1272-
bool construct);
1272+
bool construct,
1273+
bool on_add);
12731274

12741275
/* Delete an entity from the table. */
12751276
void flecs_table_delete(
@@ -3013,11 +3014,14 @@ void add_component(
30133014
ecs_entity_t *entities,
30143015
ecs_id_t id,
30153016
int32_t row,
3016-
int32_t count)
3017+
int32_t count,
3018+
bool construct)
30173019
{
30183020
ecs_assert(ti != NULL, ECS_INTERNAL_ERROR, NULL);
30193021

3020-
ctor_component(ti, column, row, count);
3022+
if (construct) {
3023+
ctor_component(ti, column, row, count);
3024+
}
30213025

30223026
ecs_iter_action_t on_add = ti->hooks.on_add;
30233027
if (on_add) {
@@ -3745,7 +3749,8 @@ int32_t flecs_table_append(
37453749
ecs_table_t *table,
37463750
ecs_entity_t entity,
37473751
ecs_record_t *record,
3748-
bool construct)
3752+
bool construct,
3753+
bool on_add)
37493754
{
37503755
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
37513756
ecs_assert(!table->lock, ECS_LOCKED_STORAGE, NULL);
@@ -3802,9 +3807,9 @@ int32_t flecs_table_append(
38023807
ecs_type_info_t *ti = type_info[i];
38033808
grow_column(column, ti, 1, size, construct);
38043809

3805-
ecs_iter_action_t on_add;
3806-
if (construct && (on_add = ti->hooks.on_add)) {
3807-
on_component_callback(world, table, on_add, EcsOnAdd, column,
3810+
ecs_iter_action_t on_add_hook;
3811+
if (on_add && (on_add_hook = ti->hooks.on_add)) {
3812+
on_component_callback(world, table, on_add_hook, EcsOnAdd, column,
38083813
&entities[count], table->storage_ids[i], count, 1, ti);
38093814
}
38103815

@@ -4110,11 +4115,9 @@ void flecs_table_move(
41104115
}
41114116
} else {
41124117
if (dst_id < src_id) {
4113-
if (construct) {
4114-
add_component(world, dst_table, dst_type_info[i_new],
4115-
&dst_columns[i_new], &dst_entity, dst_id,
4116-
dst_index, 1);
4117-
}
4118+
add_component(world, dst_table, dst_type_info[i_new],
4119+
&dst_columns[i_new], &dst_entity, dst_id,
4120+
dst_index, 1, construct);
41184121
} else {
41194122
remove_component(world, src_table, src_type_info[i_old],
41204123
&src_columns[i_old], &src_entity, src_id,
@@ -4126,11 +4129,10 @@ void flecs_table_move(
41264129
i_old += dst_id >= src_id;
41274130
}
41284131

4129-
if (construct) {
4130-
for (; (i_new < dst_column_count); i_new ++) {
4131-
add_component(world, dst_table, dst_type_info[i_new],
4132-
&dst_columns[i_new], &dst_entity, dst_ids[i_new], dst_index, 1);
4133-
}
4132+
for (; (i_new < dst_column_count); i_new ++) {
4133+
add_component(world, dst_table, dst_type_info[i_new],
4134+
&dst_columns[i_new], &dst_entity, dst_ids[i_new], dst_index, 1,
4135+
construct);
41344136
}
41354137

41364138
for (; (i_old < src_column_count); i_old ++) {
@@ -6055,7 +6057,8 @@ ecs_record_t* new_entity(
60556057
record = flecs_entities_ensure(world, entity);
60566058
}
60576059

6058-
new_row = flecs_table_append(world, new_table, entity, record, construct);
6060+
new_row = flecs_table_append(world, new_table, entity, record,
6061+
construct, true);
60596062

60606063
record->table = new_table;
60616064
record->row = ECS_ROW_TO_RECORD(new_row, record->row & ECS_ROW_FLAGS_MASK);
@@ -6098,7 +6101,7 @@ void move_entity(
60986101
ecs_assert(record == flecs_entities_get(world, entity), ECS_INTERNAL_ERROR, NULL);
60996102

61006103
int32_t dst_row = flecs_table_append(world, dst_table, entity,
6101-
record, false);
6104+
record, false, false);
61026105

61036106
/* Copy entity & components from src_table to dst_table */
61046107
if (src_table->type.count) {
@@ -48598,7 +48601,7 @@ void _bootstrap_component(
4859848601
ecs_record_t *record = flecs_entities_ensure(world, entity);
4859948602
record->table = table;
4860048603

48601-
int32_t index = flecs_table_append(world, table, entity, record, false);
48604+
int32_t index = flecs_table_append(world, table, entity, record, false, false);
4860248605
record->row = ECS_ROW_TO_RECORD(index, 0);
4860348606

4860448607
EcsComponent *component = ecs_storage_first(&columns[0]);

src/bootstrap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void _bootstrap_component(
552552
ecs_record_t *record = flecs_entities_ensure(world, entity);
553553
record->table = table;
554554

555-
int32_t index = flecs_table_append(world, table, entity, record, false);
555+
int32_t index = flecs_table_append(world, table, entity, record, false, false);
556556
record->row = ECS_ROW_TO_RECORD(index, 0);
557557

558558
EcsComponent *component = ecs_storage_first(&columns[0]);

src/entity.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,8 @@ ecs_record_t* new_entity(
826826
record = flecs_entities_ensure(world, entity);
827827
}
828828

829-
new_row = flecs_table_append(world, new_table, entity, record, construct);
829+
new_row = flecs_table_append(world, new_table, entity, record,
830+
construct, true);
830831

831832
record->table = new_table;
832833
record->row = ECS_ROW_TO_RECORD(new_row, record->row & ECS_ROW_FLAGS_MASK);
@@ -869,7 +870,7 @@ void move_entity(
869870
ecs_assert(record == flecs_entities_get(world, entity), ECS_INTERNAL_ERROR, NULL);
870871

871872
int32_t dst_row = flecs_table_append(world, dst_table, entity,
872-
record, false);
873+
record, false, false);
873874

874875
/* Copy entity & components from src_table to dst_table */
875876
if (src_table->type.count) {

src/table.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -734,11 +734,14 @@ void add_component(
734734
ecs_entity_t *entities,
735735
ecs_id_t id,
736736
int32_t row,
737-
int32_t count)
737+
int32_t count,
738+
bool construct)
738739
{
739740
ecs_assert(ti != NULL, ECS_INTERNAL_ERROR, NULL);
740741

741-
ctor_component(ti, column, row, count);
742+
if (construct) {
743+
ctor_component(ti, column, row, count);
744+
}
742745

743746
ecs_iter_action_t on_add = ti->hooks.on_add;
744747
if (on_add) {
@@ -1466,7 +1469,8 @@ int32_t flecs_table_append(
14661469
ecs_table_t *table,
14671470
ecs_entity_t entity,
14681471
ecs_record_t *record,
1469-
bool construct)
1472+
bool construct,
1473+
bool on_add)
14701474
{
14711475
ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
14721476
ecs_assert(!table->lock, ECS_LOCKED_STORAGE, NULL);
@@ -1523,9 +1527,9 @@ int32_t flecs_table_append(
15231527
ecs_type_info_t *ti = type_info[i];
15241528
grow_column(column, ti, 1, size, construct);
15251529

1526-
ecs_iter_action_t on_add;
1527-
if (construct && (on_add = ti->hooks.on_add)) {
1528-
on_component_callback(world, table, on_add, EcsOnAdd, column,
1530+
ecs_iter_action_t on_add_hook;
1531+
if (on_add && (on_add_hook = ti->hooks.on_add)) {
1532+
on_component_callback(world, table, on_add_hook, EcsOnAdd, column,
15291533
&entities[count], table->storage_ids[i], count, 1, ti);
15301534
}
15311535

@@ -1831,11 +1835,9 @@ void flecs_table_move(
18311835
}
18321836
} else {
18331837
if (dst_id < src_id) {
1834-
if (construct) {
1835-
add_component(world, dst_table, dst_type_info[i_new],
1836-
&dst_columns[i_new], &dst_entity, dst_id,
1837-
dst_index, 1);
1838-
}
1838+
add_component(world, dst_table, dst_type_info[i_new],
1839+
&dst_columns[i_new], &dst_entity, dst_id,
1840+
dst_index, 1, construct);
18391841
} else {
18401842
remove_component(world, src_table, src_type_info[i_old],
18411843
&src_columns[i_old], &src_entity, src_id,
@@ -1847,11 +1849,10 @@ void flecs_table_move(
18471849
i_old += dst_id >= src_id;
18481850
}
18491851

1850-
if (construct) {
1851-
for (; (i_new < dst_column_count); i_new ++) {
1852-
add_component(world, dst_table, dst_type_info[i_new],
1853-
&dst_columns[i_new], &dst_entity, dst_ids[i_new], dst_index, 1);
1854-
}
1852+
for (; (i_new < dst_column_count); i_new ++) {
1853+
add_component(world, dst_table, dst_type_info[i_new],
1854+
&dst_columns[i_new], &dst_entity, dst_ids[i_new], dst_index, 1,
1855+
construct);
18551856
}
18561857

18571858
for (; (i_old < src_column_count); i_old ++) {

src/table.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ int32_t flecs_table_append(
6060
ecs_table_t *table,
6161
ecs_entity_t entity,
6262
ecs_record_t *record,
63-
bool construct);
63+
bool construct,
64+
bool on_add);
6465

6566
/* Delete an entity from the table. */
6667
void flecs_table_delete(

test/api/project.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,9 @@
816816
"valid_entity_in_dtor_after_delete",
817817
"ctor_w_emplace",
818818
"ctor_w_emplace_defer",
819+
"on_add_w_emplace",
820+
"on_add_w_emplace_existing",
821+
"on_add_w_emplace_defer",
819822
"dtor_on_fini",
820823
"valid_type_in_dtor_on_fini",
821824
"valid_other_type_of_entity_in_dtor_on_fini",

test/api/src/ComponentLifecycle.c

Lines changed: 86 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,24 @@ ECS_MOVE(Position, dst, src, {
536536
move_position ++;
537537
})
538538

539+
static int on_add_position = 0;
540+
541+
static void ecs_on_add(Position)(ecs_iter_t *it) {
542+
test_assert(it->count >= 1);
543+
test_assert(it->event == EcsOnAdd);
544+
545+
Position *p = ecs_field(it, Position, 1);
546+
for (int i = 0; i < it->count; i ++) {
547+
on_add_position ++;
548+
test_int(p[i].x, 0);
549+
test_int(p[i].y, 0);
550+
}
551+
}
552+
553+
static void on_add_position_emplace(ecs_iter_t *it) {
554+
on_add_position += it->count;
555+
}
556+
539557
/* Velocity */
540558

541559
static int ctor_velocity = 0;
@@ -1327,6 +1345,74 @@ void ComponentLifecycle_ctor_w_emplace_defer() {
13271345
ecs_fini(world);
13281346
}
13291347

1348+
void ComponentLifecycle_on_add_w_emplace() {
1349+
ecs_world_t *world = ecs_mini();
1350+
1351+
ECS_COMPONENT(world, Position);
1352+
1353+
ecs_set_hooks(world, Position, {
1354+
.on_add = on_add_position_emplace
1355+
});
1356+
1357+
ecs_entity_t e = ecs_new_id(world);
1358+
test_assert(e != 0);
1359+
1360+
test_int(on_add_position, 0);
1361+
const Position *ptr = ecs_emplace(world, e, Position);
1362+
test_assert(ptr != NULL);
1363+
test_int(on_add_position, 1);
1364+
1365+
ecs_fini(world);
1366+
}
1367+
1368+
void ComponentLifecycle_on_add_w_emplace_existing() {
1369+
ecs_world_t *world = ecs_mini();
1370+
1371+
ECS_COMPONENT(world, Position);
1372+
ECS_COMPONENT(world, Velocity);
1373+
1374+
ecs_set_hooks(world, Position, {
1375+
.ctor = ecs_ctor(Position),
1376+
.on_add = on_add_position_emplace
1377+
});
1378+
1379+
ecs_entity_t e = ecs_new(world, Velocity);
1380+
test_assert(e != 0);
1381+
1382+
test_int(ctor_position, 0);
1383+
test_int(on_add_position, 0);
1384+
const Position *ptr = ecs_emplace(world, e, Position);
1385+
test_assert(ptr != NULL);
1386+
test_int(ctor_position, 0);
1387+
test_int(on_add_position, 1);
1388+
1389+
ecs_fini(world);
1390+
}
1391+
1392+
void ComponentLifecycle_on_add_w_emplace_defer() {
1393+
ecs_world_t *world = ecs_mini();
1394+
1395+
ECS_COMPONENT(world, Position);
1396+
1397+
ecs_set_hooks(world, Position, {
1398+
.on_add = on_add_position_emplace
1399+
});
1400+
1401+
ecs_entity_t e = ecs_new_id(world);
1402+
test_assert(e != 0);
1403+
1404+
ecs_defer_begin(world);
1405+
test_int(on_add_position, 0);
1406+
const Position *ptr = ecs_emplace(world, e, Position);
1407+
test_assert(ptr != NULL);
1408+
test_int(on_add_position, 0);
1409+
ecs_defer_end(world);
1410+
1411+
test_int(on_add_position, 1);
1412+
1413+
ecs_fini(world);
1414+
}
1415+
13301416
void ComponentLifecycle_dtor_on_fini() {
13311417
ecs_world_t *world = ecs_mini();
13321418

@@ -1798,20 +1884,6 @@ void ComponentLifecycle_on_set_after_set() {
17981884
ecs_fini(world);
17991885
}
18001886

1801-
static int on_add_position = 0;
1802-
1803-
static void ecs_on_add(Position)(ecs_iter_t *it) {
1804-
test_assert(it->count >= 1);
1805-
test_assert(it->event == EcsOnAdd);
1806-
1807-
Position *p = ecs_field(it, Position, 1);
1808-
for (int i = 0; i < it->count; i ++) {
1809-
on_add_position ++;
1810-
test_int(p[i].x, 0);
1811-
test_int(p[i].y, 0);
1812-
}
1813-
}
1814-
18151887
void ComponentLifecycle_on_add_after_new() {
18161888
ecs_world_t *world = ecs_mini();
18171889

test/api/src/main.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,9 @@ void ComponentLifecycle_set_lifecycle_after_trigger(void);
765765
void ComponentLifecycle_valid_entity_in_dtor_after_delete(void);
766766
void ComponentLifecycle_ctor_w_emplace(void);
767767
void ComponentLifecycle_ctor_w_emplace_defer(void);
768+
void ComponentLifecycle_on_add_w_emplace(void);
769+
void ComponentLifecycle_on_add_w_emplace_existing(void);
770+
void ComponentLifecycle_on_add_w_emplace_defer(void);
768771
void ComponentLifecycle_dtor_on_fini(void);
769772
void ComponentLifecycle_valid_type_in_dtor_on_fini(void);
770773
void ComponentLifecycle_valid_other_type_of_entity_in_dtor_on_fini(void);
@@ -5045,6 +5048,18 @@ bake_test_case ComponentLifecycle_testcases[] = {
50455048
"ctor_w_emplace_defer",
50465049
ComponentLifecycle_ctor_w_emplace_defer
50475050
},
5051+
{
5052+
"on_add_w_emplace",
5053+
ComponentLifecycle_on_add_w_emplace
5054+
},
5055+
{
5056+
"on_add_w_emplace_existing",
5057+
ComponentLifecycle_on_add_w_emplace_existing
5058+
},
5059+
{
5060+
"on_add_w_emplace_defer",
5061+
ComponentLifecycle_on_add_w_emplace_defer
5062+
},
50485063
{
50495064
"dtor_on_fini",
50505065
ComponentLifecycle_dtor_on_fini
@@ -10649,7 +10664,7 @@ static bake_test_suite suites[] = {
1064910664
"ComponentLifecycle",
1065010665
ComponentLifecycle_setup,
1065110666
NULL,
10652-
69,
10667+
72,
1065310668
ComponentLifecycle_testcases
1065410669
},
1065510670
{

test/cpp_api/project.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,9 @@
816816
"chained_hooks",
817817
"ctor_w_2_worlds",
818818
"ctor_w_2_worlds_explicit_registration",
819-
"defer_emplace"
819+
"defer_emplace",
820+
"emplace_w_on_add",
821+
"emplace_w_on_add_existing"
820822
]
821823
}, {
822824
"id": "Refs",

0 commit comments

Comments
 (0)