Function pod_component
Synopsis
#include <include/flecs/cpp/component.hpp>
template <typename T>
flecs::entity pod_component(const flecs::world &world, const char *name=nullptr, bool allow_tag=true)
Description
Plain old datatype, no lifecycle actions are registered
Source
Lines 606-694 in include/flecs/cpp/component.hpp.
template <typename T>
flecs::entity pod_component(const flecs::world& world, const char *name = nullptr, bool allow_tag = true) {
bool implicit_name = false;
if (!name) {
name = _::name_helper<T>::name();
/* Keep track of whether name was explicitly set. If not, and the
* component was already registered, just use the registered name.
*
* The registered name may differ from the typename as the registered
* name includes the flecs scope. This can in theory be different from
* the C++ namespace though it is good practice to keep them the same */
implicit_name = true;
}
world_t *world_ptr = world.c_ptr();
entity_t id = 0;
if (_::cpp_type<T>::registered()) {
/* Obtain component id. Because the component is already registered,
* this operation does nothing besides returning the existing id */
id = _::cpp_type<T>::id_no_lifecycle(world_ptr, name, allow_tag);
/* If entity is not empty check if the name matches */
if (ecs_get_type(world_ptr, id) != nullptr) {
if (!implicit_name && id >= EcsFirstUserComponentId) {
char *path = ecs_get_path_w_sep(
world_ptr, 0, id, 0, "::", nullptr);
ecs_assert(!strcmp(path, name),
ECS_INCONSISTENT_COMPONENT_NAME, name);
ecs_os_free(path);
}
} else {
/* 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_ptr, id, 0, name, "::", "::");
}
/* If a component was already registered with this id but with a
* different size, the ecs_new_component function will fail. */
/* We need to explicitly call ecs_new_component 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 entity = ecs_new_component(
world.c_ptr(), id, nullptr,
_::cpp_type<T>::size(),
_::cpp_type<T>::alignment());
(void)entity;
ecs_assert(entity == id, ECS_INTERNAL_ERROR, NULL);
/* This functionality could have been put in id_no_lifecycle, but since
* this code happens when a component is registered, and the entire API
* calls id_no_lifecycle, this would add a lot of overhead to each call.
* This is why when using multiple worlds, components should be
* registered explicitly. */
} else {
/* If the component is not yet registered, ensure no other component
* or entity has been registered with this name */
ecs_entity_t entity = ecs_lookup_fullpath(world_ptr, name);
/* If entity exists, compare symbol name to ensure that the component
* we are trying to register under this name is the same */
if (entity) {
const EcsName *name_comp = static_cast<EcsName*>(ecs_get_mut_w_id(
world.c_ptr(), entity, ecs_id(EcsName), NULL));
ecs_assert(name_comp != NULL, ECS_INTERNAL_ERROR, NULL);
ecs_assert(name_comp->symbol != NULL, ECS_INTERNAL_ERROR, NULL);
const char *symbol = _::name_helper<T>::name();
ecs_assert(!strcmp(name_comp->symbol, symbol),
ECS_COMPONENT_NAME_IN_USE, name);
(void)name_comp;
(void)symbol;
}
/* Register id as usual */
id = _::cpp_type<T>::id_no_lifecycle(world_ptr, name, allow_tag);
}
return world.entity(id);
}