31#if defined(__GNUC__) || defined(_WIN32)
33inline static const char* type_name() {
34 static const size_t len = ECS_FUNC_TYPE_LEN(
const char*, type_name, ECS_FUNC_NAME);
35 static char result[len + 1] = {};
36 static const size_t front_len = ECS_FUNC_NAME_FRONT(
const char*, type_name);
37 return ecs_cpp_get_type_name(result, ECS_FUNC_NAME, len, front_len);
40#error "implicit component registration not supported"
46inline static const char* symbol_name() {
47 static const size_t len = ECS_FUNC_TYPE_LEN(
const char*, symbol_name, ECS_FUNC_NAME);
48 static char result[len + 1] = {};
49 return ecs_cpp_get_symbol_name(result, type_name<T>(), len);
52template <>
inline const char* symbol_name<uint8_t>() {
55template <>
inline const char* symbol_name<uint16_t>() {
58template <>
inline const char* symbol_name<uint32_t>() {
61template <>
inline const char* symbol_name<uint64_t>() {
64template <>
inline const char* symbol_name<int8_t>() {
67template <>
inline const char* symbol_name<int16_t>() {
70template <>
inline const char* symbol_name<int32_t>() {
73template <>
inline const char* symbol_name<int64_t>() {
76template <>
inline const char* symbol_name<float>() {
79template <>
inline const char* symbol_name<double>() {
87template<
typename T, enable_if_t<
88 std::is_trivial<T>::value ==
true
94template<
typename T, enable_if_t<
95 std::is_trivial<T>::value ==
false
97void register_lifecycle_actions(
106 cl.copy_ctor = copy_ctor<T>();
108 cl.move_ctor = move_ctor<T>();
110 cl.ctor_move_dtor = ctor_move_dtor<T>();
111 cl.move_dtor = move_dtor<T>();
131 bool allow_tag =
true)
133 if (s_reset_count != ecs_cpp_reset_count_get()) {
141 ecs_assert(allow_tag == s_allow_tag, ECS_INVALID_PARAMETER, NULL);
151 s_allow_tag = allow_tag;
153 s_alignment =
alignof(T);
154 if (is_empty<T>::value && allow_tag) {
159 s_reset_count = ecs_cpp_reset_count_get();
163 static entity_t id_explicit(world_t *
world =
nullptr,
164 const char *name =
nullptr,
bool allow_tag =
true, flecs::id_t
id = 0,
165 bool is_component =
true,
bool *existing =
nullptr)
171 ecs_assert(!
id || s_id ==
id, ECS_INCONSISTENT_COMPONENT_ID, NULL);
179 init(s_id ? s_id :
id, allow_tag);
181 ecs_assert(!
id || s_id ==
id, ECS_INTERNAL_ERROR, NULL);
183 const char *symbol =
nullptr;
188 symbol = symbol_name<T>();
191 entity_t
entity = ecs_cpp_component_register_explicit(
192 world, s_id,
id, name, type_name<T>(), symbol,
193 s_size, s_alignment, is_component, existing);
198 #if FLECS_CPP_ENUM_REFLECTION_SUPPORT
205 ECS_INTERNAL_ERROR, NULL);
216 static id_t
id(world_t *
world =
nullptr,
const char *name =
nullptr,
217 bool allow_tag =
true)
220 if (!registered(
world)) {
232 id_explicit(
world, name, allow_tag, 0,
true, &existing);
237 if (size() && !existing) {
238 register_lifecycle_actions<T>(
world, s_id);
250 ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL);
256 static size_t size() {
257 ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL);
262 static size_t alignment() {
263 ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL);
268 static bool registered(flecs::world_t *
world) {
269 if (s_reset_count != ecs_cpp_reset_count_get()) {
283 static void reset() {
290 static entity_t s_id;
291 static size_t s_size;
292 static size_t s_alignment;
293 static bool s_allow_tag;
294 static int32_t s_reset_count;
317 static id_t
id(world_t *
world =
nullptr) {
332 using entity::entity;
338# include "mixins/metrics/untyped_component.inl"
359 flecs::world_t *
world,
360 const char *
name =
nullptr,
361 bool allow_tag =
true,
364 const char *n =
name;
365 bool implicit_name =
false;
367 n = _::type_name<T>();
375 implicit_name =
true;
383 ecs_cpp_component_validate(
world,
id, n, _::symbol_name<T>(),
393 const char *
start = strchr(n,
'<'), *last_elem = NULL;
395 const char *ptr =
start;
396 while (ptr[0] && (ptr[0] !=
':') && (ptr > n)) {
403 last_elem = strrchr(n,
':');
406 name = last_elem + 1;
412 id = ecs_cpp_component_register(
world,
id, n, _::symbol_name<T>(),
413 ECS_SIZEOF(T), ECS_ALIGNOF(T), implicit_name, &existing);
420 _::register_lifecycle_actions<T>(
world,
id);
429 template <
typename Func>
432 typename std::decay<Func>::type, T>;
435 "on_add hook is already set");
437 h.
on_add = Invoker::run_add;
438 ctx->on_add = FLECS_NEW(Invoker)(FLECS_FWD(func));
440 _::free_obj<Invoker>);
446 template <
typename Func>
449 typename std::decay<Func>::type, T>;
452 "on_remove hook is already set");
455 ctx->on_remove = FLECS_NEW(Invoker)(FLECS_FWD(func));
457 _::free_obj<Invoker>);
463 template <
typename Func>
466 typename std::decay<Func>::type, T>;
469 "on_set hook is already set");
471 h.
on_set = Invoker::run_set;
472 ctx->on_set = FLECS_NEW(Invoker)(FLECS_FWD(func));
474 _::free_obj<Invoker>);
480# include "mixins/meta/component.inl"
487 BindingCtx *result =
static_cast<BindingCtx*
>(h.
binding_ctx);
489 result = FLECS_NEW(BindingCtx);
492 _::free_obj<BindingCtx>);
541 ecs_cpp_reset_count_inc();
flecs::entity_t type_id()
Get id currently assigned to component.
ecs_entity_t ecs_set_with(ecs_world_t *world, ecs_id_t id)
Set current with id.
#define ecs_assert(condition, error_code,...)
Assert.
const ecs_type_hooks_t * ecs_get_hooks_id(ecs_world_t *world, ecs_entity_t id)
Get hooks for component.
void ecs_set_hooks_id(ecs_world_t *world, ecs_entity_t id, const ecs_type_hooks_t *hooks)
Register hooks for component.
ecs_id_t ecs_entity_t
An entity identifier.
struct ecs_world_t ecs_world_t
A world is the container for all ECS data and supporting features.
uint64_t ecs_id_t
Ids are the things that can be added to an entity.
void reset()
Reset static component ids.
transcribe_cv_t< remove_reference_t< P >, typename remove_reference_t< P >::second > pair_second_t
Get pair::second from pair while preserving cv qualifiers.
transcribe_cv_t< remove_reference_t< P >, typename remove_reference_t< P >::first > pair_first_t
Get pair::first from pair while preserving cv qualifiers.
void(* ecs_ctx_free_t)(void *ctx)
Function to cleanup context data.
bool ecs_exists(const ecs_world_t *world, ecs_entity_t entity)
Test whether an entity exists.
ecs_entity_t ecs_get_scope(const ecs_world_t *world)
Get the current scope.
const char * ecs_get_symbol(const ecs_world_t *world, ecs_entity_t entity)
Get the symbol of an entity.
ecs_entity_t ecs_set_scope(ecs_world_t *world, ecs_entity_t scope)
Set the current scope.
Type that contains component lifecycle callbacks.
ecs_iter_action_t on_remove
Callback that is invoked when an instance of the component is removed.
void * binding_ctx
Language binding context.
ecs_iter_action_t on_set
Callback that is invoked when an instance of the component is set.
ecs_iter_action_t on_add
Callback that is invoked when an instance of a component is added.
ecs_ctx_free_t binding_ctx_free
Callback to free binding_ctx.
component< T > & on_remove(Func &&func)
Register on_remove hook.
component(flecs::world_t *world, const char *name=nullptr, bool allow_tag=true, flecs::id_t id=0)
Register a component.
component< T > & on_add(Func &&func)
Register on_add hook.
component< T > & on_set(Func &&func)
Register on_set hook.
flecs::string_view name() const
Return the entity name.
Class that wraps around a flecs::id_t.