Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement world local component ids #1479

Merged
merged 1 commit into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 90 additions & 90 deletions distr/flecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,9 @@ struct ecs_world_t {
ecs_stage_t **stages; /* Stages */
int32_t stage_count; /* Number of stages */

/* -- Component ids -- */
ecs_vec_t component_ids; /* World local component ids */

/* Internal callback for command inspection. Only one callback can be set at
* a time. After assignment the action will become active at the start of
* the next frame, set by ecs_frame_begin, and will be reset by
Expand Down Expand Up @@ -7371,7 +7374,8 @@ int flecs_traverse_add(
const char *sym = ecs_get_symbol(world, result);
if (sym) {
ecs_assert(!ecs_os_strcmp(desc->symbol, sym),
ECS_INCONSISTENT_NAME, desc->symbol);
ECS_INCONSISTENT_NAME, "%s (provided) vs. %s (existing)",
desc->symbol, sym);
} else {
ecs_set_symbol(world, result, desc->symbol);
}
Expand Down Expand Up @@ -19390,6 +19394,7 @@ ecs_world_t *ecs_mini(void) {
flecs_name_index_init(&world->aliases, a);
flecs_name_index_init(&world->symbols, a);
ecs_vec_init_t(a, &world->fini_actions, ecs_action_elem_t, 0);
ecs_vec_init_t(a, &world->component_ids, ecs_id_t, 0);

world->info.time_scale = 1.0;
if (ecs_os_has_time()) {
Expand Down Expand Up @@ -20065,6 +20070,7 @@ int ecs_fini(
flecs_name_index_fini(&world->aliases);
flecs_name_index_fini(&world->symbols);
ecs_set_stage_count(world, 0);
ecs_vec_fini_t(&world->allocator, &world->component_ids, ecs_id_t);
ecs_log_pop_1();

flecs_world_allocators_fini(world);
Expand Down Expand Up @@ -20833,6 +20839,67 @@ ecs_flags32_t ecs_world_get_flags(
}
}

static int32_t flecs_component_ids_last_index = 0;

int32_t flecs_component_ids_index_get(void) {
if (ecs_os_api.ainc_) {
return ecs_os_ainc(&flecs_component_ids_last_index);
} else {
return ++ flecs_component_ids_last_index;
}
}

ecs_entity_t flecs_component_ids_get(
const ecs_world_t *stage_world,
int32_t index)
{
ecs_world_t *world =
ECS_CONST_CAST(ecs_world_t*, ecs_get_world(stage_world));
flecs_poly_assert(world, ecs_world_t);

if (index >= ecs_vec_count(&world->component_ids)) {
return 0;
}

return ecs_vec_get_t(
&world->component_ids, ecs_entity_t, index)[0];
}

ecs_entity_t flecs_component_ids_get_alive(
const ecs_world_t *stage_world,
int32_t index)
{
ecs_world_t *world =
ECS_CONST_CAST(ecs_world_t*, ecs_get_world(stage_world));
flecs_poly_assert(world, ecs_world_t);

if (index >= ecs_vec_count(&world->component_ids)) {
return 0;
}

ecs_entity_t result = ecs_vec_get_t(
&world->component_ids, ecs_entity_t, index)[0];
if (!flecs_entities_is_alive(world, result)) {
return 0;
}

return result;
}

void flecs_component_ids_set(
ecs_world_t *stage_world,
int32_t index,
ecs_entity_t component)
{
ecs_world_t *world =
ECS_CONST_CAST(ecs_world_t*, ecs_get_world(stage_world));
flecs_poly_assert(world, ecs_world_t);

ecs_vec_set_min_count_zeromem_t(
&world->allocator, &world->component_ids, ecs_entity_t, index + 1);
ecs_vec_get_t(&world->component_ids, ecs_entity_t, index)[0] = component;
}

/**
* @file addons/alerts.c
* @brief Alerts addon.
Expand Down Expand Up @@ -22272,94 +22339,31 @@ const char* ecs_cpp_trim_module(
return type_name;
}

// Validate registered component
void ecs_cpp_component_validate(
ecs_entity_t ecs_cpp_component_find(
ecs_world_t *world,
ecs_entity_t id,
const char *name,
const char *symbol,
size_t size,
size_t alignment,
bool implicit_name)
{
/* If entity has a name check if it matches */
if (ecs_is_valid(world, id) && ecs_get_name(world, id) != NULL) {
if (!implicit_name && id >= EcsFirstUserComponentId) {
#ifndef FLECS_NDEBUG
char *path = ecs_get_path_w_sep(
world, 0, id, "::", NULL);
if (ecs_os_strcmp(path, name)) {
ecs_abort(ECS_INCONSISTENT_NAME,
"component '%s' already registered with name '%s'",
name, path);
}
ecs_os_free(path);
#endif
}

if (symbol) {
const char *existing_symbol = ecs_get_symbol(world, id);
if (existing_symbol) {
if (ecs_os_strcmp(symbol, existing_symbol)) {
ecs_abort(ECS_INCONSISTENT_NAME,
"component '%s' with symbol '%s' already registered with symbol '%s'",
name, symbol, existing_symbol);
}
}
}
} else {
/* Ensure that the entity id valid */
if (!ecs_is_alive(world, id)) {
ecs_make_alive(world, id);
}

/* Register name with entity, so that when the entity is created the
* correct id will be resolved from the name. Only do this when the
* entity is empty. */
ecs_add_path_w_sep(world, id, 0, name, "::", "::");
}

/* If a component was already registered with this id but with a
* different size, the ecs_component_init function will fail. */

/* We need to explicitly call ecs_component_init here again. Even though
* the component was already registered, it may have been registered
* with a different world. This ensures that the component is registered
* with the same id for the current world.
* If the component was registered already, nothing will change. */
ecs_entity_t ent = ecs_component_init(world, &(ecs_component_desc_t){
.entity = id,
.type.size = flecs_uto(int32_t, size),
.type.alignment = flecs_uto(int32_t, alignment)
});
(void)ent;
ecs_assert(ent == id, ECS_INTERNAL_ERROR, NULL);
}

ecs_entity_t ecs_cpp_component_register(
ecs_world_t *world,
ecs_entity_t id,
const char *name,
const char *symbol,
ecs_size_t size,
ecs_size_t alignment,
bool implicit_name,
bool *existing_out)
{
(void)size;
(void)alignment;

ecs_assert(existing_out != NULL, ECS_INTERNAL_ERROR, NULL);

/* If the component is not yet registered, ensure no other component
* or entity has been registered with this name. Ensure component is
* looked up from root. */
bool existing = false;
ecs_entity_t prev_scope = ecs_set_scope(world, 0);
ecs_entity_t ent;
if (id) {
ent = id;
} else {
ent = ecs_lookup_path_w_sep(world, 0, name, "::", "::", false);
existing = ent != 0 && ecs_has(world, ent, EcsComponent);
*existing_out = ent != 0 && ecs_has(world, ent, EcsComponent);
}
ecs_set_scope(world, prev_scope);

Expand Down Expand Up @@ -22387,16 +22391,23 @@ ecs_entity_t ecs_cpp_component_register(
* to alias the type, vs. accidentally registering an unrelated
* type with the same size/alignment. */
char *type_path = ecs_get_path(world, ent);
if (ecs_os_strcmp(type_path, symbol) ||
component->size != size ||
component->alignment != alignment)
{
if (ecs_os_strcmp(type_path, symbol)) {
ecs_err(
"component with name '%s' is already registered for"\
" type '%s' (trying to register for type '%s')",
name, sym, symbol);
ecs_abort(ECS_NAME_IN_USE, NULL);
}

if (flecs_itosize(component->size) != size ||
flecs_itosize(component->alignment) != alignment)
{
ecs_err(
"component with name '%s' is already registered with"\
" mismatching size/alignment)", name);
ecs_abort(ECS_INVALID_COMPONENT_SIZE, NULL);
}

ecs_os_free(type_path);
} else if (!sym) {
ecs_set_symbol(world, ent, symbol);
Expand All @@ -22407,17 +22418,14 @@ ecs_entity_t ecs_cpp_component_register(
* registered under a different name. */
} else if (!implicit_name) {
ent = ecs_lookup_symbol(world, symbol, false, false);
ecs_assert(ent == 0 || (ent == id), ECS_INCONSISTENT_COMPONENT_ID, symbol);
}

if (existing_out) {
*existing_out = existing;
ecs_assert(ent == 0 || (ent == id),
ECS_INCONSISTENT_COMPONENT_ID, symbol);
}

return ent;
}

ecs_entity_t ecs_cpp_component_register_explicit(
ecs_entity_t ecs_cpp_component_register(
ecs_world_t *world,
ecs_entity_t s_id,
ecs_entity_t id,
Expand All @@ -22430,7 +22438,8 @@ ecs_entity_t ecs_cpp_component_register_explicit(
bool *existing_out)
{
char *existing_name = NULL;
if (existing_out) *existing_out = false;

ecs_assert(existing_out != NULL, ECS_INTERNAL_ERROR, NULL);

// If an explicit id is provided, it is possible that the symbol and
// name differ from the actual type, as the application may alias
Expand All @@ -22443,7 +22452,7 @@ ecs_entity_t ecs_cpp_component_register_explicit(
if (id) {
existing_name = ecs_get_path_w_sep(world, 0, id, "::", "::");
name = existing_name;
if (existing_out) *existing_out = true;
*existing_out = true;
} else {
// If type is not yet known, derive from type name
name = ecs_cpp_trim_module(world, type_name);
Expand Down Expand Up @@ -22556,16 +22565,6 @@ ecs_entity_t ecs_cpp_enum_constant_register(
return id;
}

static int32_t flecs_reset_count = 0;

int32_t ecs_cpp_reset_count_get(void) {
return flecs_reset_count;
}

int32_t ecs_cpp_reset_count_inc(void) {
return ++flecs_reset_count;
}

#ifdef FLECS_META
const ecs_member_t* ecs_cpp_last_member(
const ecs_world_t *world,
Expand Down Expand Up @@ -51685,6 +51684,7 @@ void flecs_set_custom_type(ecs_iter_t *it) {
if (!comp || !comp->size || !comp->alignment) {
ecs_err("custom type '%s' has no size/alignment, register as component first",
ecs_get_name(world, e));
flecs_dump_backtrace(stdout);
continue;
}

Expand Down
Loading
Loading