@@ -2812,12 +2812,33 @@ void flecs_enqueue(
28122812 ecs_assert(table->component_map != NULL, ECS_INTERNAL_ERROR, NULL);\
28132813 int16_t column_index = table->component_map[id];\
28142814 if (column_index > 0) {\
2815- ecs_column_t *column = &table->data.columns[--column_index];\
2816- return ECS_GET_PTR(\
2817- ECS_ELEM(column->data, column->ti->size, ECS_RECORD_TO_ROW(r->row)),\
2818- NULL, table, column_index);\
2815+ ecs_column_t *column = &table->data.columns[column_index - 1];\
2816+ return ECS_ELEM(column->data, column->ti->size, \
2817+ ECS_RECORD_TO_ROW(r->row));\
28192818 }
28202819
2820+ #ifdef FLECS_MUT_ALIAS_LOCKS
2821+ #define ecs_record_get_low_id(tbl, r, id)\
2822+ ecs_assert(tbl->component_map != NULL, ECS_INTERNAL_ERROR, NULL);\
2823+ int16_t column_index = tbl->component_map[id];\
2824+ if (column_index > 0) {\
2825+ ecs_column_t *column = &tbl->data.columns[--column_index];\
2826+ return (ecs_get_ptr_t){\
2827+ .ptr = ECS_ELEM(column->data, column->ti->size, ECS_RECORD_TO_ROW(r->row)),\
2828+ .lock_target = (ecs_lock_target_t){ .cr = NULL, .table = (tbl), .column_index = column_index }\
2829+ };\
2830+ }
2831+ #else
2832+ #define ecs_record_get_low_id(tbl, r, id)\
2833+ ecs_assert(tbl->component_map != NULL, ECS_INTERNAL_ERROR, NULL);\
2834+ int16_t column_index = tbl->component_map[id];\
2835+ if (column_index > 0) {\
2836+ ecs_column_t *column = &tbl->data.columns[column_index - 1];\
2837+ return (ecs_get_ptr_t)ECS_ELEM(column->data, column->ti->size, \
2838+ ECS_RECORD_TO_ROW(r->row));\
2839+ }
2840+ #endif
2841+
28212842typedef struct {
28222843 const ecs_type_info_t *ti;
28232844 void *ptr;
@@ -2899,7 +2920,7 @@ int32_t flecs_relation_depth(
28992920 const ecs_table_t *table);
29002921
29012922/* Get component from base entity (follows IsA relationship) */
2902- ecs_get_ptr_t flecs_get_base_component(
2923+ void* flecs_get_base_component(
29032924 const ecs_world_t *world,
29042925 ecs_table_t *table,
29052926 ecs_id_t id,
@@ -5704,7 +5725,7 @@ void* flecs_defer_ensure(
57045725 void *base = NULL;
57055726 if (table && (table->flags & EcsTableHasIsA)) {
57065727 ecs_component_record_t *cr = flecs_components_get(world, id);
5707- base = ECS_GET_PTR_PTR( flecs_get_base_component(world, table, id, cr, 0) );
5728+ base = flecs_get_base_component(world, table, id, cr, 0);
57085729 }
57095730
57105731 if (!base) {
@@ -7532,7 +7553,7 @@ void* flecs_get_component(
75327553 return flecs_get_component_ptr(world, table, row, cr).ptr;
75337554}
75347555
7535- ecs_get_ptr_t flecs_get_base_component(
7556+ void* flecs_get_base_component(
75367557 const ecs_world_t *world,
75377558 ecs_table_t *table,
75387559 ecs_id_t component,
@@ -7544,16 +7565,16 @@ ecs_get_ptr_t flecs_get_base_component(
75447565
75457566 /* Table (and thus entity) does not have component, look for base */
75467567 if (!(table->flags & EcsTableHasIsA)) {
7547- return ECS_GET_PTR_NULL ;
7568+ return NULL ;
75487569 }
75497570
75507571 if (!(cr->flags & EcsIdOnInstantiateInherit)) {
7551- return ECS_GET_PTR_NULL ;
7572+ return NULL ;
75527573 }
75537574
75547575 /* Exclude Name */
75557576 if (component == ecs_pair(ecs_id(EcsIdentifier), EcsName)) {
7556- return ECS_GET_PTR_NULL ;
7577+ return NULL ;
75577578 }
75587579
75597580 /* Table should always be in the table index for (IsA, *), otherwise the
@@ -7565,7 +7586,7 @@ ecs_get_ptr_t flecs_get_base_component(
75657586 ecs_type_t type = table->type;
75667587 ecs_id_t *ids = type.array;
75677588 int32_t i = tr_isa->index, end = tr_isa->count + tr_isa->index;
7568- ecs_get_ptr_t ptr = ECS_GET_PTR_NULL ;
7589+ void * ptr = NULL ;
75697590
75707591 do {
75717592 ecs_id_t pair = ids[i ++];
@@ -7580,33 +7601,26 @@ ecs_get_ptr_t flecs_get_base_component(
75807601 const ecs_table_record_t *tr = flecs_component_get_table(cr, table);
75817602 if (!tr) {
75827603 if (cr->flags & EcsIdDontFragment) {
7583- ptr = ECS_GET_PTR(
7584- flecs_component_sparse_get(world, cr, table, base),
7585- cr, NULL, -1);
7604+ ptr = flecs_component_sparse_get(world, cr, table, base);
75867605 }
75877606
7588- if (!ECS_GET_PTR_PTR( ptr) ) {
7589- ptr = flecs_get_base_component(world, table, component, cr,
7607+ if (!ptr) {
7608+ ptr = flecs_get_base_component(world, table, component, cr,
75907609 recur_depth + 1);
75917610 }
75927611 } else {
75937612 if (cr->flags & EcsIdSparse) {
7594- return ECS_GET_PTR(
7595- flecs_component_sparse_get(world, cr, table, base),
7596- cr, NULL, -1);
7613+ return flecs_component_sparse_get(world, cr, table, base);
75977614 } else {
75987615 int32_t row = ECS_RECORD_TO_ROW(r->row);
7599- int16_t column = tr->column;
7600- return ECS_GET_PTR(
7601- flecs_table_get_component(table, column, row).ptr,
7602- NULL, table, column);
7616+ return flecs_table_get_component(table, tr->column, row).ptr;
76037617 }
76047618 }
7605- } while (!ECS_GET_PTR_PTR( ptr) && (i < end));
7619+ } while (!ptr && (i < end));
76067620
76077621 return ptr;
76087622error:
7609- return ECS_GET_PTR_NULL ;
7623+ return NULL ;
76107624}
76117625
76127626ecs_entity_t flecs_new_id(
@@ -9373,6 +9387,61 @@ ecs_entity_t ecs_clone(
93739387 return 0;
93749388}
93759389
9390+ const void* ecs_get_id(
9391+ const ecs_world_t *world,
9392+ ecs_entity_t entity,
9393+ ecs_id_t component)
9394+ {
9395+ ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
9396+ flecs_assert_entity_valid(world, entity, "get");
9397+ ecs_check(ecs_id_is_valid(world, component) || ecs_id_is_wildcard(component),
9398+ ECS_INVALID_PARAMETER, NULL);
9399+
9400+ world = ecs_get_world(world);
9401+
9402+ ecs_record_t *r = flecs_entities_get(world, entity);
9403+ ecs_assert(r != NULL, ECS_INVALID_PARAMETER, NULL);
9404+
9405+ ecs_table_t *table = r->table;
9406+ ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
9407+
9408+ if (component < FLECS_HI_COMPONENT_ID) {
9409+ if (!world->non_trivial_lookup[component]) {
9410+ ecs_get_low_id(table, r, component);
9411+ return NULL;
9412+ }
9413+ }
9414+
9415+ ecs_component_record_t *cr = flecs_components_get(world, component);
9416+ if (!cr) {
9417+ return NULL;
9418+ }
9419+
9420+ if (cr->flags & EcsIdDontFragment) {
9421+ void *ptr = flecs_component_sparse_get(world, cr, table, entity);
9422+ if (ptr) {
9423+ return ptr;
9424+ }
9425+ }
9426+
9427+ const ecs_table_record_t *tr = flecs_component_get_table(cr, table);
9428+ if (!tr) {
9429+ return flecs_get_base_component(world, table, component, cr, 0);
9430+ } else {
9431+ if (cr->flags & EcsIdSparse) {
9432+ return flecs_component_sparse_get(world, cr, table, entity);
9433+ }
9434+ ecs_check(tr->column != -1, ECS_INVALID_PARAMETER,
9435+ "component '%s' passed to get() is a tag/zero sized",
9436+ flecs_errstr(ecs_id_str(world, component)));
9437+ }
9438+
9439+ int32_t row = ECS_RECORD_TO_ROW(r->row);
9440+ return flecs_table_get_component(table, tr->column, row).ptr;
9441+ error:
9442+ return NULL;
9443+ }
9444+
93769445ecs_get_ptr_t flecs_record_get_id(
93779446 const ecs_world_t *world,
93789447 ecs_entity_t entity,
@@ -9382,15 +9451,15 @@ ecs_get_ptr_t flecs_record_get_id(
93829451 ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
93839452 flecs_assert_entity_valid(world, entity, "get");
93849453 ecs_assert(r != NULL, ECS_INVALID_PARAMETER, NULL);
9385- ecs_check(ecs_id_is_valid(world, component) || ecs_id_is_wildcard(component),
9454+ ecs_check(ecs_id_is_valid(world, component) || ecs_id_is_wildcard(component),
93869455 ECS_INVALID_PARAMETER, NULL);
93879456
93889457 ecs_table_t *table = r->table;
93899458 ecs_assert(table != NULL, ECS_INTERNAL_ERROR, NULL);
93909459
93919460 if (component < FLECS_HI_COMPONENT_ID) {
93929461 if (!world->non_trivial_lookup[component]) {
9393- ecs_get_low_id (table, r, component);
9462+ ecs_record_get_low_id (table, r, component);
93949463 return ECS_GET_PTR_NULL;
93959464 }
93969465 }
@@ -9409,7 +9478,11 @@ ecs_get_ptr_t flecs_record_get_id(
94099478
94109479 const ecs_table_record_t *tr = flecs_component_get_table(cr, table);
94119480 if (!tr) {
9412- return flecs_get_base_component(world, table, component, cr, 0);
9481+ void *base_ptr = flecs_get_base_component(world, table, component, cr, 0);
9482+ if (base_ptr) {
9483+ return ECS_GET_PTR(base_ptr, cr, NULL, -1);
9484+ }
9485+ return ECS_GET_PTR_NULL;
94139486 } else {
94149487 if (cr->flags & EcsIdSparse) {
94159488 return ECS_GET_PTR(
@@ -9430,22 +9503,6 @@ ecs_get_ptr_t flecs_record_get_id(
94309503 return ECS_GET_PTR_NULL;
94319504}
94329505
9433- const void* ecs_get_id(
9434- const ecs_world_t *world,
9435- ecs_entity_t entity,
9436- ecs_id_t component)
9437- {
9438- ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
9439-
9440- world = ecs_get_world(world);
9441-
9442- ecs_record_t *r = flecs_entities_get(world, entity);
9443-
9444- return ECS_GET_PTR_PTR(flecs_record_get_id(world, entity, r, component));
9445- error:
9446- return NULL;
9447- }
9448-
94499506#ifdef FLECS_DEBUG
94509507static
94519508bool flecs_component_has_on_replace(
@@ -9454,7 +9511,7 @@ bool flecs_component_has_on_replace(
94549511 const char *funcname)
94559512{
94569513 const ecs_type_info_t *ti = ecs_get_type_info(world, component);
9457- ecs_check(ti != NULL, ECS_INVALID_PARAMETER,
9514+ ecs_check(ti != NULL, ECS_INVALID_PARAMETER,
94589515 "invalid component '%s' for %s(): component cannot be a tag/zero sized",
94599516 flecs_errstr(ecs_id_str(world, component)), funcname);
94609517 return ti->hooks.on_replace != NULL;
@@ -9463,6 +9520,41 @@ bool flecs_component_has_on_replace(
94639520}
94649521#endif
94659522
9523+ void* ecs_get_mut_id(
9524+ const ecs_world_t *world,
9525+ ecs_entity_t entity,
9526+ ecs_id_t component)
9527+ {
9528+ ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
9529+ flecs_assert_entity_valid(world, entity, "get_mut");
9530+ flecs_assert_component_valid(world, entity, component, "get_mut");
9531+ ecs_dbg_assert(!flecs_component_has_on_replace(world, component, "get_mut"),
9532+ ECS_INVALID_PARAMETER,
9533+ "cannot call get_mut() for component '%s' which has an on_replace hook "
9534+ "(use set()/assign())",
9535+ flecs_errstr(ecs_id_str(world, component)));
9536+
9537+ world = ecs_get_world(world);
9538+
9539+ flecs_check_exclusive_world_access_write(world);
9540+
9541+ ecs_record_t *r = flecs_entities_get(world, entity);
9542+ ecs_assert(r != NULL, ECS_INVALID_PARAMETER, NULL);
9543+
9544+ if (component < FLECS_HI_COMPONENT_ID) {
9545+ if (!world->non_trivial_lookup[component]) {
9546+ ecs_get_low_id(r->table, r, component);
9547+ return NULL;
9548+ }
9549+ }
9550+
9551+ ecs_component_record_t *cr = flecs_components_get(world, component);
9552+ int32_t row = ECS_RECORD_TO_ROW(r->row);
9553+ return flecs_get_component_ptr(world, r->table, row, cr).ptr;
9554+ error:
9555+ return NULL;
9556+ }
9557+
94669558ecs_get_ptr_t flecs_record_get_mut_id(
94679559 const ecs_world_t *world,
94689560 const ecs_record_t *r,
@@ -9471,7 +9563,7 @@ ecs_get_ptr_t flecs_record_get_mut_id(
94719563 ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
94729564 flecs_poly_assert(world, ecs_world_t);
94739565 ecs_assert(r != NULL, ECS_INVALID_PARAMETER, NULL);
9474- ecs_dbg_assert(!flecs_component_has_on_replace(world, component, "get_mut"),
9566+ ecs_dbg_assert(!flecs_component_has_on_replace(world, component, "get_mut"),
94759567 ECS_INVALID_PARAMETER,
94769568 "cannot call get_mut() for component '%s' which has an on_replace hook "
94779569 "(use set()/assign())",
@@ -9481,7 +9573,7 @@ ecs_get_ptr_t flecs_record_get_mut_id(
94819573
94829574 if (component < FLECS_HI_COMPONENT_ID) {
94839575 if (!world->non_trivial_lookup[component]) {
9484- ecs_get_low_id (r->table, r, component);
9576+ ecs_record_get_low_id (r->table, r, component);
94859577 return ECS_GET_PTR_NULL;
94869578 }
94879579 }
@@ -9501,25 +9593,6 @@ ecs_get_ptr_t flecs_record_get_mut_id(
95019593 return ECS_GET_PTR_NULL;
95029594}
95039595
9504- void* ecs_get_mut_id(
9505- const ecs_world_t *world,
9506- ecs_entity_t entity,
9507- ecs_id_t component)
9508- {
9509- ecs_check(world != NULL, ECS_INVALID_PARAMETER, NULL);
9510- flecs_assert_entity_valid(world, entity, "get_mut");
9511- flecs_assert_component_valid(world, entity, component, "get_mut");
9512-
9513- world = ecs_get_world(world);
9514-
9515- ecs_record_t *r = flecs_entities_get(world, entity);
9516-
9517- return ECS_GET_PTR_PTR(flecs_record_get_mut_id(world, r, component));
9518-
9519- error:
9520- return NULL;
9521- }
9522-
95239596void* ecs_ensure_id(
95249597 ecs_world_t *world,
95259598 ecs_entity_t entity,
@@ -10110,8 +10183,8 @@ bool ecs_has_id(
1011010183 if (flecs_component_sparse_has(cr, entity)) {
1011110184 return true;
1011210185 } else {
10113- return ECS_GET_PTR_PTR( flecs_get_base_component(
10114- world, table, component, cr, 0)) != NULL;
10186+ return flecs_get_base_component(
10187+ world, table, component, cr, 0) != NULL;
1011510188 }
1011610189 }
1011710190
0 commit comments