Skip to content

Commit

Permalink
Transition static enum types and entities for enum values to use worl…
Browse files Browse the repository at this point in the history
…d-local entities
  • Loading branch information
Naios committed Oct 3, 2023
1 parent a0fa136 commit a3bd866
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 35 deletions.
12 changes: 9 additions & 3 deletions include/flecs/addons/cpp/impl/world.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,17 +254,23 @@ inline flecs::entity world::ensure(flecs::entity_t e) const {

template <typename E>
inline flecs::entity enum_data<E>::entity() const {
return flecs::entity(world_, impl_.id);
return flecs::entity(world_, _::cpp_type<E>::id_explicit(world_));
}

template <typename E>
inline flecs::entity enum_data<E>::entity(int value) const {
return flecs::entity(world_, impl_.constants[value].id);
ecs_component_cache_index_t const index = impl_.constants[value].index;
if (index == 0) {
return flecs::entity();
}

const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world_, index);
return info ? flecs::entity(world_, info->component) : flecs::entity();
}

template <typename E>
inline flecs::entity enum_data<E>::entity(E value) const {
return flecs::entity(world_, impl_.constants[static_cast<int>(value)].id);
return entity(static_cast<int>(value));
}

/** Use provided scope for operations ran on returned world.
Expand Down
83 changes: 56 additions & 27 deletions include/flecs/addons/cpp/utils/enum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,42 +151,72 @@ static const char* enum_constant_to_name() {

/** Enumeration constant data */
struct enum_constant_data {
flecs::entity_t id;
ecs_component_cache_index_t index = 0;
int value;
int next;
char const* name;
};

/** Enumeration type data */
struct enum_data_impl {
flecs::entity_t id;
int min;
int max;
int min = FLECS_ENUM_MAX(int);
int max = 0;
enum_constant_data constants[FLECS_ENUM_MAX_COUNT];
};

template <typename E, typename Value>
struct enum_value {
enum_value() { }

static enum_value<E, Value> const& get() {
static _::enum_value<E, Value> instance;
return instance;
}
};

/** Class that scans an enum for constants, extracts names & creates entities */
template <typename E>
struct enum_type {
static enum_data_impl data;
enum_data_impl data;

static enum_type<E>& get() {
enum_type() {
init_constant< enum_last<E>::value >();
}

static enum_type<E> const& get() {
static _::enum_type<E> instance;
return instance;
}

flecs::entity_t entity(E value) const {
return data.constants[static_cast<int>(value)].id;
flecs::entity_t entity(flecs::world_t* world, E value) const {
const ecs_component_cache_index_t index = data.constants[static_cast<int>(value)].index;

const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world, index);
return info ? info->component : 0;
}

void init(flecs::world_t *world, flecs::entity_t id) {
void init(flecs::world_t *world, flecs::entity_t id) const {
#if !FLECS_CPP_ENUM_REFLECTION_SUPPORT
ecs_abort(ECS_UNSUPPORTED, "enum reflection requires gcc 7.5 or higher")
#endif

ecs_log_push();
ecs_cpp_enum_init(world, id);
data.id = id;
data.min = FLECS_ENUM_MAX(int);
init< enum_last<E>::value >(world);

for (const enum_constant_data& constant : data.constants) {
if (!constant.index) {
continue;
}

ecs_cached_component_info_t* info = ecs_get_or_create_cached_component_info(world, constant.index);
if (ecs_is_cached_component_info_valid(info)) {
// Do nothing if initialized already
continue;
}

info->component = ecs_cpp_enum_constant_register(world, id, constant.name, constant.value);
}

ecs_log_pop();
}

Expand All @@ -207,20 +237,22 @@ struct enum_type {
}

template <E Value, flecs::if_not_t< enum_constant_is_valid<E, Value>() > = 0>
static void init_constant(flecs::world_t*) { }
void init_constant() { }

template <E Value, flecs::if_t< enum_constant_is_valid<E, Value>() > = 0>
static void init_constant(flecs::world_t *world) {
int v = to_int<Value>();
const char *name = enum_constant_to_name<E, Value>();
data.constants[v].next = data.min;
void init_constant() {
int const v = to_int<Value>();

enum_constant_data &constant = data.constants[v];
constant.value = v;
constant.index = ecs_cpp_component_id_storage_add();
constant.next = data.min;
constant.name = enum_constant_to_name<E, Value>();

data.min = v;
if (!data.max) {
data.max = v;
}

data.constants[v].id = ecs_cpp_enum_constant_register(
world, data.id, data.constants[v].id, name, v);
}

template <E Value = FLECS_ENUM_MAX(E) >
Expand All @@ -232,9 +264,6 @@ struct enum_type {
}
};

template <typename E>
enum_data_impl enum_type<E>::data;

template <typename E, if_t< is_enum<E>::value > = 0>
inline static void init_enum(flecs::world_t *world, flecs::entity_t id) {
_::enum_type<E>::get().init(world, id);
Expand All @@ -248,12 +277,12 @@ inline static void init_enum(flecs::world_t*, flecs::entity_t) { }
/** Enumeration type data wrapper with world pointer */
template <typename E>
struct enum_data {
enum_data(flecs::world_t *world, _::enum_data_impl& impl)
enum_data(flecs::world_t *world, _::enum_data_impl const& impl)
: world_(world)
, impl_(impl) { }

bool is_valid(int value) {
return impl_.constants[value].id != 0;
bool is_valid(int value) const {
return impl_.constants[value].index != 0;
}

int first() const {
Expand All @@ -273,7 +302,7 @@ struct enum_data {
flecs::entity entity(E value) const;

flecs::world_t *world_;
_::enum_data_impl& impl_;
_::enum_data_impl const& impl_;
};

/** Convenience function for getting enum reflection data */
Expand Down
1 change: 0 additions & 1 deletion include/flecs/addons/flecs_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ FLECS_API
ecs_entity_t ecs_cpp_enum_constant_register(
ecs_world_t *world,
ecs_entity_t parent,
ecs_entity_t id,
const char *name,
int value);

Expand Down
6 changes: 2 additions & 4 deletions src/addons/flecs_cpp.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ void ecs_cpp_enum_init(
ecs_entity_t ecs_cpp_enum_constant_register(
ecs_world_t *world,
ecs_entity_t parent,
ecs_entity_t id,
const char *name,
int value)
{
Expand All @@ -455,8 +454,7 @@ ecs_entity_t ecs_cpp_enum_constant_register(
}

ecs_entity_t prev = ecs_set_scope(world, parent);
id = ecs_entity(world, {
.id = id,
ecs_entity_t id = ecs_entity(world, {
.name = name
});
ecs_assert(id != 0, ECS_INVALID_OPERATION, name);
Expand Down Expand Up @@ -493,7 +491,7 @@ int32_t ecs_cpp_reset_count_inc(void) {
static ecs_size_t flecs_component_storage_count = 0;

ecs_size_t ecs_cpp_component_id_storage_add(void) {
return flecs_component_storage_count++;
return ++flecs_component_storage_count;
}

#ifdef FLECS_META
Expand Down
3 changes: 3 additions & 0 deletions src/world.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,9 @@ ecs_cached_component_info_t* ecs_get_or_create_cached_component_info(

ecs_poly_assert(world, ecs_world_t);

// Uninitialized index
ecs_assert(component_cache_index != 0, ECS_INTERNAL_ERROR, NULL);

ecs_vec_set_min_count_zeromem_t(
&world->allocator, &world->component_id_cache,
ecs_cached_component_info_t, component_cache_index + 1);
Expand Down

0 comments on commit a3bd866

Please sign in to comment.