Skip to content

Commit

Permalink
#680 enforce that type_info is set before component is used
Browse files Browse the repository at this point in the history
  • Loading branch information
SanderMertens committed Mar 18, 2022
1 parent 280bc4e commit e475959
Show file tree
Hide file tree
Showing 15 changed files with 313 additions and 257 deletions.
222 changes: 137 additions & 85 deletions flecs.c

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions flecs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8103,6 +8103,7 @@ int ecs_log_last_error(void);
#define ECS_INCONSISTENT_COMPONENT_ACTION (27)
#define ECS_MODULE_UNDEFINED (28)
#define ECS_MISSING_SYMBOL (29)
#define ECS_ALREADY_IN_USE (30)

#define ECS_COLUMN_ACCESS_VIOLATION (40)
#define ECS_COLUMN_INDEX_OUT_OF_RANGE (41)
Expand Down
1 change: 1 addition & 0 deletions include/flecs/addons/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ int ecs_log_last_error(void);
#define ECS_INCONSISTENT_COMPONENT_ACTION (27)
#define ECS_MODULE_UNDEFINED (28)
#define ECS_MISSING_SYMBOL (29)
#define ECS_ALREADY_IN_USE (30)

#define ECS_COLUMN_ACCESS_VIOLATION (40)
#define ECS_COLUMN_INDEX_OUT_OF_RANGE (41)
Expand Down
1 change: 1 addition & 0 deletions src/addons/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ const char* ecs_strerror(
ECS_ERR_STR(ECS_INVALID_CONVERSION);
ECS_ERR_STR(ECS_MODULE_UNDEFINED);
ECS_ERR_STR(ECS_MISSING_SYMBOL);
ECS_ERR_STR(ECS_ALREADY_IN_USE);
ECS_ERR_STR(ECS_COLUMN_INDEX_OUT_OF_RANGE);
ECS_ERR_STR(ECS_COLUMN_IS_NOT_SHARED);
ECS_ERR_STR(ECS_COLUMN_IS_SHARED);
Expand Down
15 changes: 7 additions & 8 deletions src/addons/meta/meta.c
Original file line number Diff line number Diff line change
Expand Up @@ -938,17 +938,16 @@ void unit_quantity_monitor(ecs_iter_t *it) {
static
void ecs_meta_type_init_default_ctor(ecs_iter_t *it) {
ecs_world_t *world = it->world;
EcsMetaType *type = ecs_term(it, EcsMetaType, 1);

int i;
for (i = 0; i < it->count; i ++) {
ecs_entity_t type = it->entities[i];

/* If component has no component actions (which is typical if a type is
* created with reflection data) make sure its values are always
* initialized with zero. This prevents the injection of invalid data
* through generic APIs after adding a component without setting it. */
if (!ecs_component_has_actions(world, type)) {
ecs_set_component_actions_w_id(world, type,
/* If a component is defined from reflection data, configure it with the
* default constructor. This ensures that a new component value does not
* contain uninitialized memory, which could cause serializers to crash
* when for example inspecting string fields. */
if (!type->existing) {
ecs_set_component_actions_w_id(world, it->entities[i],
&(EcsComponentLifecycle){
.ctor = ecs_default_ctor
});
Expand Down
2 changes: 1 addition & 1 deletion src/addons/snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ ecs_data_t* duplicate_data(

component = ecs_get_typeid(world, component);

const ecs_type_info_t *ti = flecs_get_c_info(world, component);
const ecs_type_info_t *ti = flecs_get_type_info(world, component);
int16_t size = column->size;
int16_t alignment = column->alignment;
ecs_copy_t copy;
Expand Down
39 changes: 24 additions & 15 deletions src/bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,21 +584,16 @@ void flecs_bootstrap(

ecs_set_name_prefix(world, "Ecs");

/* Create table for initial components */
ecs_table_t *table = bootstrap_component_table(world);
assert(table != NULL);

bootstrap_component(world, table, EcsIdentifier);
bootstrap_component(world, table, EcsComponent);
bootstrap_component(world, table, EcsComponentLifecycle);

bootstrap_component(world, table, EcsType);
bootstrap_component(world, table, EcsQuery);
bootstrap_component(world, table, EcsTrigger);
bootstrap_component(world, table, EcsObserver);
bootstrap_component(world, table, EcsIterable);

ecs_set_component_actions(world, EcsComponent, { .ctor = ecs_default_ctor });
/* Bootstrap type info (otherwise initialized by setting EcsComponent) */
flecs_init_type_info_t(world, EcsComponent);
flecs_init_type_info_t(world, EcsIdentifier);
flecs_init_type_info_t(world, EcsTrigger);
flecs_init_type_info_t(world, EcsObserver);

/* Setup component lifecycle actions */
ecs_set_component_actions(world, EcsComponent, {
.ctor = ecs_default_ctor
});

ecs_set_component_actions(world, EcsIdentifier, {
.ctor = ecs_ctor(EcsIdentifier),
Expand All @@ -623,6 +618,20 @@ void flecs_bootstrap(
.move = ecs_move(EcsObserver)
});

/* Create table for initial components */
ecs_table_t *table = bootstrap_component_table(world);
assert(table != NULL);

bootstrap_component(world, table, EcsIdentifier);
bootstrap_component(world, table, EcsComponent);
bootstrap_component(world, table, EcsComponentLifecycle);

bootstrap_component(world, table, EcsType);
bootstrap_component(world, table, EcsQuery);
bootstrap_component(world, table, EcsTrigger);
bootstrap_component(world, table, EcsObserver);
bootstrap_component(world, table, EcsIterable);

world->stats.last_component_id = EcsFirstUserComponentId;
world->stats.last_id = EcsFirstUserEntityId;
world->stats.min_id = 0;
Expand Down
6 changes: 3 additions & 3 deletions src/entity.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const ecs_type_info_t *get_c_info(
{
ecs_entity_t real_id = ecs_get_typeid(world, component);
if (real_id) {
return flecs_get_c_info(world, real_id);
return flecs_get_type_info(world, real_id);
} else {
return NULL;
}
Expand Down Expand Up @@ -500,7 +500,7 @@ bool override_from_base(
void *data_ptr = ECS_OFFSET(data_array, data_size * row);

component = ecs_get_typeid(world, component);
const ecs_type_info_t *ti = flecs_get_c_info(world, component);
const ecs_type_info_t *ti = flecs_get_type_info(world, component);
int32_t index;

ecs_copy_t copy = ti ? ti->lifecycle.copy : NULL;
Expand Down Expand Up @@ -3988,7 +3988,7 @@ void free_value(
int32_t count)
{
ecs_entity_t real_id = ecs_get_typeid(world, id);
const ecs_type_info_t *ti = flecs_get_c_info(world, real_id);
const ecs_type_info_t *ti = flecs_get_type_info(world, real_id);
ecs_xtor_t dtor;

if (ti && (dtor = ti->lifecycle.dtor)) {
Expand Down
17 changes: 15 additions & 2 deletions src/private_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,24 @@ const ecs_stage_t* flecs_stage_from_readonly_world(
const ecs_world_t *world);

/* Get component callbacks */
const ecs_type_info_t *flecs_get_c_info(
const ecs_type_info_t *flecs_get_type_info(
const ecs_world_t *world,
ecs_entity_t component);

/* Get or create component callbacks */
ecs_type_info_t* flecs_get_or_create_c_info(
ecs_type_info_t* flecs_ensure_type_info(
ecs_world_t *world,
ecs_entity_t component);

void flecs_init_type_info(
ecs_world_t *world,
ecs_entity_t component,
ecs_size_t size,
ecs_size_t alignment);

#define flecs_init_type_info_t(world, T)\
flecs_init_type_info(world, ecs_id(T), ECS_SIZEOF(T), ECS_ALIGNOF(T))

void flecs_eval_component_monitors(
ecs_world_t *world);

Expand Down Expand Up @@ -183,6 +192,10 @@ void flecs_clear_id_record(
ecs_id_t id,
ecs_id_record_t *idr);

bool flecs_id_existst(
ecs_world_t *world,
ecs_id_t id);

void flecs_remove_id_record(
ecs_world_t *world,
ecs_id_t id,
Expand Down
2 changes: 1 addition & 1 deletion src/stage.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ bool flecs_defer_set(
const ecs_type_info_t *ti = NULL;
ecs_entity_t real_id = ecs_get_typeid(world, id);
if (real_id) {
ti = flecs_get_c_info(world, real_id);
ti = flecs_get_type_info(world, real_id);
}

if (value) {
Expand Down
2 changes: 1 addition & 1 deletion src/table.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ void notify_component_info(
}
ecs_assert(c != 0, ECS_INTERNAL_ERROR, NULL);

const ecs_type_info_t *c_info = flecs_get_c_info(world, c);
const ecs_type_info_t *c_info = flecs_get_type_info(world, c);
if (c_info) {
ecs_flags32_t flags = get_component_action_flags(c_info);
table->flags |= flags;
Expand Down
Loading

0 comments on commit e475959

Please sign in to comment.