Skip to content
Flecs v4.1
component.hpp
Go to the documentation of this file.
1/**
2 * @file addons/cpp/component.hpp
3 * @brief Registering/obtaining info from components.
4 */
5
6#pragma once
7
8/**
9 * @defgroup cpp_components Components
10 * @ingroup cpp_core
11 * Registering and working with components.
12 *
13 * @{
14 */
15
16namespace flecs {
17
18namespace _ {
19
20template <typename T>
21inline const char* component_symbol_name() {
22 return nullptr;
24
25template <> inline const char* component_symbol_name<uint8_t>() {
26 return "u8";
27}
28template <> inline const char* component_symbol_name<uint16_t>() {
29 return "u16";
30}
31template <> inline const char* component_symbol_name<uint32_t>() {
32 return "u32";
33}
34template <> inline const char* component_symbol_name<uint64_t>() {
35 return "u64";
36}
37template <> inline const char* component_symbol_name<int8_t>() {
38 return "i8";
40template <> inline const char* component_symbol_name<int16_t>() {
41 return "i16";
42}
43template <> inline const char* component_symbol_name<int32_t>() {
44 return "i32";
45}
46template <> inline const char* component_symbol_name<int64_t>() {
47 return "i64";
48}
49template <> inline const char* component_symbol_name<float>() {
50 return "f32";
51}
52template <> inline const char* component_symbol_name<double>() {
53 return "f64";
54}
55
56// If the type is trivial, don't register lifecycle actions. While the functions
57// that obtain the lifecycle callback do detect whether the callback is required,
58// adding a special case for trivial types eases the burden a bit on the
59// compiler, as it reduces the number of templates to evaluate.
60template<typename T>
61void register_lifecycle_actions(
62 ecs_world_t *world,
63 ecs_entity_t component)
64{
65 (void)world; (void)component;
66 if constexpr (!(std::is_trivially_default_constructible<T>::value &&
67 std::is_trivially_copyable<T>::value))
68 {
69 // If the component is non-trivial, register component lifecycle actions.
70 // Depending on the type, not all callbacks may be available.
72 cl.ctor = xtor<T, false>(cl.flags);
73 cl.dtor = xtor<T, true>(cl.flags);
74
75 cl.copy = transfer<T, false, false>(cl.flags);
76 cl.copy_ctor = transfer<T, false, true>(cl.flags);
77 cl.move = transfer<T, true, false>(cl.flags);
78 cl.move_ctor = transfer<T, true, true>(cl.flags);
79
80 cl.ctor_move_dtor = transfer<T, true, true, true>(cl.flags);
81 cl.move_dtor = transfer<T, true, false, true>(cl.flags);
82
83 cl.flags &= ECS_TYPE_HOOKS_ILLEGAL;
85
86 if (cl.flags & (ECS_TYPE_HOOK_MOVE_ILLEGAL|ECS_TYPE_HOOK_MOVE_CTOR_ILLEGAL))
87 {
88 ecs_add_id(world, component, flecs::Sparse);
89 }
90 }
91}
92
93template <typename T>
94inline ecs_cpp_type_action_t lifecycle_action() {
95 if constexpr (std::is_trivially_default_constructible<T>::value &&
96 std::is_trivially_copyable<T>::value)
97 {
98 return nullptr;
99 } else {
100 return &register_lifecycle_actions<T>;
101 }
102}
103
104#ifdef FLECS_META
105template <typename T, typename = void>
106struct has_cpp_meta_desc : std::false_type {};
107
108template <typename T>
109struct has_cpp_meta_desc<T, decltype(void(
110 flecs_meta_cpp_desc(static_cast<T*>(nullptr))))> : std::true_type {};
111#endif
112
113template <typename T>
114inline ecs_cpp_type_action_t enum_action() {
115#if FLECS_CPP_ENUM_REFLECTION_SUPPORT
116#ifdef FLECS_META
117 if constexpr (has_cpp_meta_desc<T>::value) {
118 return nullptr;
119 } else
120#endif
121 if constexpr (is_enum_v<T>) {
122 return &_::init_enum<T>;
123 } else {
124 return nullptr;
125 }
126#else
127 return nullptr;
128#endif
129}
130
131#ifdef FLECS_META
132
133template <typename T>
134inline void register_cpp_meta(ecs_world_t *world, ecs_entity_t component) {
135 (void)world; (void)component;
136 if constexpr (has_cpp_meta_desc<T>::value) {
137 ecs_type_kind_t kind = flecs_meta_cpp_kind(static_cast<T*>(nullptr));
138 if (kind == EcsStructType && ecs_has_id(world, component,
139 ecs_id(EcsStruct))) {
140 return;
141 }
142 if (kind == EcsEnumType && ecs_has_id(world, component,
143 ecs_id(EcsEnum))) {
144 return;
145 }
146 if (kind == EcsBitmaskType && ecs_has_id(world, component,
147 ecs_id(EcsBitmask))) {
148 return;
149 }
150 ecs_meta_from_desc(world, component, kind,
151 flecs_meta_cpp_desc(static_cast<T*>(nullptr)));
152 }
153}
154#endif
155
156template <typename T>
157struct type_impl {
158 static_assert(is_pointer<T>::value == false,
159 "pointer types are not allowed for components");
160
161 // Initialize the component identifier.
162 static void init(
163 bool allow_tag = true)
164 {
165#ifdef FLECS_MULTI_WORLD
166 index(); // Make sure the global component index is initialized.
167#endif
168
169 s_has_data = !is_empty<T>::value || !allow_tag;
170 }
171
172 static void init_builtin(
175 bool allow_tag = true)
176 {
177 init(allow_tag);
178#ifdef FLECS_MULTI_WORLD
179 flecs_component_ids_set(world, index(), id);
180#else
181 (void)world;
182 s_id = id;
183#endif
184 }
185
186 // Register the component ID.
187 static entity_t register_id(
188 world_t *world, // The world
189 const char *name = nullptr, // User-provided name (overrides typename)
190 bool allow_tag = true, // Register empty types as zero-sized components
191 bool is_component = true, // Add flecs::Component to the result
192 bool explicit_registration = false, // Entered from world.component<T>()?
193 flecs::id_t id = 0) // User-provided component ID
194 {
195 init(allow_tag);
196#ifdef FLECS_MULTI_WORLD
197 ecs_assert(index() != 0, ECS_INTERNAL_ERROR, nullptr);
198#endif
199
201 id,
202#ifdef FLECS_MULTI_WORLD
203 index(),
204#else
205 &s_id,
206#endif
207 name,
208 type_name<T>(),
209 component_symbol_name<T>(),
210 size(),
211 alignment(),
212 lifecycle_action<T>(),
213 enum_action<T>(),
214 is_component,
215 explicit_registration
216 };
217
219
220 ecs_assert(c != 0, ECS_INTERNAL_ERROR, nullptr);
221
222 if constexpr (flecs::sparse<T>::value) {
223 ecs_add_id(world, c, flecs::Sparse);
224 }
225
226 if constexpr (flecs::dont_fragment<T>::value) {
227 ecs_add_id(world, c, flecs::DontFragment);
228 }
229
230 if constexpr (flecs::on_instantiate_trait<T>::declared) {
231 constexpr flecs::on_instantiate policy =
232 flecs::on_instantiate_trait<T>::value;
233#ifdef FLECS_PREFAB
234 if constexpr (policy == flecs::on_instantiate::override) {
235 ecs_add_pair(world, c, flecs::OnInstantiate, flecs::Override);
236 }
237 if constexpr (policy == flecs::on_instantiate::inherit) {
238 ecs_add_pair(world, c, flecs::OnInstantiate, flecs::Inherit);
239 }
240#endif
241 if constexpr (policy == flecs::on_instantiate::dont_inherit) {
242 ecs_add_pair(world, c, flecs::OnInstantiate,
243 flecs::DontInherit);
244 }
245 }
246
247#ifdef FLECS_META
248 register_cpp_meta<T>(world, c);
249#endif
250
251 return c;
252 }
253
254 // Get the type (component) ID.
255 // If the type was not yet registered and automatic registration is allowed,
256 // this function will also register the type.
257 static entity_t id(world_t *world)
258 {
259#ifdef FLECS_CPP_NO_AUTO_REGISTRATION
261 "component '%s' must be registered before use",
262 type_name<T>());
263
264#ifdef FLECS_MULTI_WORLD
265 flecs::entity_t c = flecs_component_ids_get(world, index());
266#else
267 flecs::entity_t c = s_id;
268#endif
269 ecs_assert(c != 0, ECS_INTERNAL_ERROR, nullptr);
271 "component '%s' was deleted, reregister before using",
272 type_name<T>());
273#else
274#ifdef FLECS_MULTI_WORLD
275 flecs::entity_t c = flecs_component_ids_get_alive(world, index());
276#else
277 flecs::entity_t c = s_id;
278 if (c && !ecs_is_alive(world, c)) {
279 c = 0;
280 }
281#endif
282 if (!c) {
283 c = register_id(world);
284 }
285#endif
286 return c;
287 }
288
289 // Return the size of a component.
290 static size_t size() {
291 return s_has_data ? sizeof(T) : 0;
292 }
293
294 // Return the alignment of a component.
295 static size_t alignment() {
296 return s_has_data ? alignof(T) : 0;
297 }
298
299 // Was the component already registered?
300 static bool registered(flecs::world_t *world) {
301 ecs_assert(world != nullptr, ECS_INVALID_PARAMETER, nullptr);
302
303#ifdef FLECS_MULTI_WORLD
304 if (!flecs_component_ids_get(world, index())) {
305#else
306 if (!s_id) {
307#endif
308 return false;
309 }
310
311 return true;
312 }
313
314 // This function is only used to test cross-translation-unit features. No
315 // code other than test cases should invoke this function.
316 static void reset() {
317 s_has_data = false;
318#ifndef FLECS_MULTI_WORLD
319 s_id = 0;
320#endif
321 }
322
323#ifdef FLECS_MULTI_WORLD
324 static int32_t index() {
325 static int32_t index_ = flecs_component_ids_index_get();
326 return index_;
327 }
328#else
329 static entity_t s_id;
330#endif
331
332 static bool s_has_data;
333};
334
335// Global templated variables that hold the component identifier and other info.
336template <typename T> inline bool type_impl<T>::s_has_data;
337#ifndef FLECS_MULTI_WORLD
338template <typename T> inline entity_t type_impl<T>::s_id;
339#endif
340
341// Front-facing class for implicitly registering a component and obtaining
342// static component data.
343
344// Regular type.
345template <typename T>
346struct type<T, if_not_t< is_pair<T>::value >>
347 : type_impl<base_type_t<T>> { };
348
349// Pair type.
350template <typename T>
351struct type<T, if_t< is_pair<T>::value >>
352{
353 // Override the id() method to return the ID of a pair.
354 static id_t id(world_t *world = nullptr) {
355 return ecs_pair(
356 type< pair_first_t<T> >::id(world),
357 type< pair_second_t<T> >::id(world));
358 }
359};
360
361} // namespace _
362
363/** Untyped component class.
364 * Generic base class for flecs::component.
365 *
366 * @ingroup cpp_components
367 */
369 using entity::entity;
370
371 /** Default constructor. */
373
374 /** Construct from world and entity ID.
375 *
376 * @param world The world.
377 * @param id The component entity ID.
378 */
380
381 /** Construct from entity ID.
382 *
383 * @param id The component entity ID.
384 */
386
387 /** Construct from world and name.
388 *
389 * @param world The world.
390 * @param name The component name.
391 */
393 {
394 world_ = world;
395
396 ecs_entity_desc_t desc = {};
397 desc.name = name;
398 desc.sep = "::";
399 desc.root_sep = "::";
400 desc.use_low_id = true;
401 id_ = ecs_entity_init(world, &desc);
402 }
403
404 /** Construct from world, name, and scope separators.
405 *
406 * @param world The world.
407 * @param name The component name.
408 * @param sep The scope separator.
409 * @param root_sep The root scope separator.
410 */
411 explicit untyped_component(world_t *world, const char *name, const char *sep, const char *root_sep)
412 {
413 world_ = world;
414
415 ecs_entity_desc_t desc = {};
416 desc.name = name;
417 desc.sep = sep;
418 desc.root_sep = root_sep;
419 desc.use_low_id = true;
420 id_ = ecs_entity_init(world, &desc);
421 }
422
423protected:
424
425 /** Get the type hooks for this component.
426 *
427 * @return The type hooks, or empty hooks if none are set.
428 */
431 if (h) {
432 return *h;
433 } else {
434 return {};
435 }
436 }
437
438 /** Set the type hooks for this component.
439 *
440 * @param h The type hooks to set.
441 */
443 h.flags &= ECS_TYPE_HOOKS_ILLEGAL;
445 }
446
447public:
448
449/** Register a custom compare hook for this component.
450 *
451 * @param compare_callback The comparison callback function.
452 * @return Reference to self for chaining.
453 */
455 ecs_cmp_t compare_callback)
456{
457 ecs_assert(compare_callback, ECS_INVALID_PARAMETER, nullptr);
459 h.cmp = compare_callback;
460 h.flags &= ~ECS_TYPE_HOOK_CMP_ILLEGAL;
461 if(h.flags & ECS_TYPE_HOOK_EQUALS_ILLEGAL) {
462 h.flags &= ~ECS_TYPE_HOOK_EQUALS_ILLEGAL;
463 h.equals = nullptr;
464 }
465 set_hooks(h);
466 return *this;
467}
468
469/** Register a custom equals hook for this component.
470 *
471 * @param equals_callback The equality callback function.
472 * @return Reference to self for chaining.
473 */
475 ecs_equals_t equals_callback)
476{
477 ecs_assert(equals_callback, ECS_INVALID_PARAMETER, nullptr);
479 h.equals = equals_callback;
480 h.flags &= ~ECS_TYPE_HOOK_EQUALS_ILLEGAL;
481 set_hooks(h);
482 return *this;
483}
484
485# ifdef FLECS_META
487# endif
488# ifdef FLECS_METRICS
490# endif
491};
492
493/** Component class.
494 * Class used to register components and component metadata.
495 *
496 * @ingroup cpp_components
497 */
498template <typename T>
500 /** Register a component.
501 * If the component was already registered, this operation will return a handle
502 * to the existing component.
503 *
504 * @param world The world for which to register the component.
505 * @param name Optional name (overrides typename).
506 * @param allow_tag If true, empty types will be registered with size 0.
507 * @param id Optional component ID to register the component with.
508 */
511 const char *name = nullptr,
512 bool allow_tag = true,
513 flecs::id_t id = 0)
514 {
515 world_ = world;
516 id_ = _::type<T>::register_id(world, name, allow_tag, true, true, id);
517 }
518
519 /** Register on_add hook.
520 *
521 * @param func The callback function.
522 * @return Reference to self for chaining.
523 */
524 template <typename Func>
525 component<T>& on_add(Func&& func) {
526 using Delegate = _::each_delegate<decay_t<Func>, T>;
527 return set_hook<Delegate, &flecs::type_hooks_t::on_add,
528 BindingCtx::OnAdd>(FLECS_FWD(func));
529 }
530
531 /** Register on_remove hook.
532 *
533 * @param func The callback function.
534 * @return Reference to self for chaining.
535 */
536 template <typename Func>
537 component<T>& on_remove(Func&& func) {
538 using Delegate = _::each_delegate<decay_t<Func>, T>;
539 return set_hook<Delegate, &flecs::type_hooks_t::on_remove,
540 BindingCtx::OnRemove>(FLECS_FWD(func));
541 }
542
543 /** Register on_set hook.
544 *
545 * @param func The callback function.
546 * @return Reference to self for chaining.
547 */
548 template <typename Func>
549 component<T>& on_set(Func&& func) {
550 using Delegate = _::each_delegate<decay_t<Func>, T>;
551 return set_hook<Delegate, &flecs::type_hooks_t::on_set,
552 BindingCtx::OnSet>(FLECS_FWD(func));
553 }
554
555 /** Register on_replace hook.
556 *
557 * @param func The callback function.
558 * @return Reference to self for chaining.
559 */
560 template <typename Func>
561 component<T>& on_replace(Func&& func) {
562 using Delegate = _::each_delegate<decay_t<Func>, T, T>;
563 return set_hook<Delegate, &flecs::type_hooks_t::on_replace,
564 BindingCtx::OnReplace>(FLECS_FWD(func));
565 }
566
567 /** Register on_validate hook.
568 * The hook is invoked with signature bool(flecs::entity, T&) before the
569 * on_set hook and OnSet observers are invoked. When the hook returns
570 * false, the on_set hook and OnSet observers are not invoked for the
571 * entity.
572 *
573 * @param func The callback function.
574 * @return Reference to self for chaining.
575 */
576 template <typename Func>
577 component<T>& on_validate(Func&& func) {
578 using Delegate = _::validate_delegate<decay_t<Func>, T>;
579 return set_hook<Delegate, &flecs::type_hooks_t::on_validate,
580 BindingCtx::OnValidate>(FLECS_FWD(func));
581 }
582
584
585 /** Register an operator compare hook using type T's comparison operators.
586 *
587 * @return Reference to self for chaining.
588 */
590 ecs_cmp_t handler = _::compare<T>();
591 ecs_assert(handler != nullptr, ECS_INVALID_OPERATION,
592 "Type does not have operator> or operator< const or is inaccessible");
593 on_compare(handler);
594 return *this;
595 }
596
597 using cmp_hook = int(*)(const T* a, const T* b, const ecs_type_info_t *ti);
598
599 /** Type-safe variant of the compare op function.
600 *
601 * @param callback The comparison callback function.
602 * @return Reference to self for chaining.
603 */
604 component<T>& on_compare(cmp_hook callback) {
605 on_compare(reinterpret_cast<ecs_cmp_t>(callback));
606 return *this;
607 }
608
610
611 /** Register an operator equals hook using type T's equality operator.
612 *
613 * @return Reference to self for chaining.
614 */
616 ecs_equals_t handler = _::equals<T>();
617 ecs_assert(handler != nullptr, ECS_INVALID_OPERATION,
618 "Type does not have operator== const or is inaccessible");
619 on_equals(handler);
620 return *this;
621 }
622
623 using equals_hook = bool(*)(const T* a, const T* b, const ecs_type_info_t *ti);
624
625 /** Type-safe variant of the equals op function.
626 *
627 * @param callback The equality callback function.
628 * @return Reference to self for chaining.
629 */
630 component<T>& on_equals(equals_hook callback) {
631 on_equals(reinterpret_cast<ecs_equals_t>(callback));
632 return *this;
633 }
634
635# ifdef FLECS_META
637# endif
638
639private:
640 using BindingCtx = _::component_binding_ctx;
641
642 template <typename Delegate, auto Hook, BindingCtx::Hook Slot, typename Func>
643 component<T>& set_hook(Func&& func) {
644 flecs::type_hooks_t h = get_hooks();
645 ecs_assert(h.*Hook == nullptr, ECS_INVALID_OPERATION,
646 "component hook is already set");
647 if constexpr (std::is_same_v<Delegate,
649 {
650 h.*Hook = Delegate::run;
651 } else {
652 h.*Hook = Delegate::template run_hook<Slot>;
653 }
654 BindingCtx *ctx = get_binding_ctx(h);
655 ctx->callbacks[Slot] = FLECS_NEW(Delegate)(FLECS_FWD(func));
656 ctx->free[Slot] = _::free_obj<Delegate>;
657 set_hooks(h);
658 return *this;
659 }
660
661 BindingCtx* get_binding_ctx(flecs::type_hooks_t& h){
662 BindingCtx *result = static_cast<BindingCtx*>(h.binding_ctx);
663 if (!result) {
664 result = FLECS_NEW(BindingCtx);
665 h.binding_ctx = result;
666 h.binding_ctx_free = _::free_obj<BindingCtx>;
667 }
668 return result;
669 }
670};
671
672}
673
674/** @} */
Meta component mixin.
FLECS_API ecs_entity_t ecs_cpp_component_register(ecs_world_t *world, const ecs_cpp_component_desc_t *desc)
Register a C++ component.
void ecs_add_id(ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Add a (component) ID to an entity.
FLECS_API const ecs_entity_t ecs_id(EcsDocDescription)
Component ID for EcsDocDescription.
#define ecs_assert(condition, error_code,...)
Assert.
Definition log.h:473
#define ECS_INVALID_OPERATION
Invalid operation error code.
Definition log.h:669
#define ECS_INVALID_PARAMETER
Invalid parameter error code.
Definition log.h:671
#define ECS_INTERNAL_ERROR
Internal error code.
Definition log.h:681
FLECS_API int ecs_meta_from_desc(ecs_world_t *world, ecs_entity_t component, ecs_type_kind_t kind, const char *desc)
Populate meta information from type descriptor.
ecs_type_kind_t
Type kinds supported by meta addon.
Definition meta.h:156
const ecs_type_hooks_t * ecs_get_hooks_id(const ecs_world_t *world, ecs_entity_t component)
Get hooks for a component.
void ecs_set_hooks_id(ecs_world_t *world, ecs_entity_t component, const ecs_type_hooks_t *hooks)
Register hooks for a component.
ecs_id_t ecs_entity_t
An entity identifier.
Definition flecs.h:395
struct ecs_world_t ecs_world_t
A world is the container for all ECS data and supporting features.
Definition flecs.h:439
ecs_type_hooks_t type_hooks_t
Type hooks type.
Definition c_types.hpp:34
ecs_id_t id_t
ID type.
Definition c_types.hpp:20
ecs_entity_t entity_t
Entity type.
Definition c_types.hpp:21
ecs_world_t world_t
World type.
Definition c_types.hpp:18
transcribe_cv_t< remove_reference_t< P >, typename raw_type_t< P >::second > pair_second_t
Get pair::second from a pair while preserving cv qualifiers.
Definition pair.hpp:112
transcribe_cv_t< remove_reference_t< P >, typename raw_type_t< P >::first > pair_first_t
Get pair::first from a pair while preserving cv qualifiers.
Definition pair.hpp:108
ecs_entity_t ecs_entity_init(ecs_world_t *world, const ecs_entity_desc_t *desc)
Find or create an entity.
bool ecs_has_id(const ecs_world_t *world, ecs_entity_t entity, ecs_id_t component)
Test if an entity has a component.
#define ecs_add_pair(world, subject, first, second)
Add a pair to an entity.
Definition flecs_c.h:275
bool(*) ecs_equals_t(const void *a_ptr, const void *b_ptr, const ecs_type_info_t *type_info)
Equals operator hook.
Definition flecs.h:699
int(*) ecs_cmp_t(const void *a_ptr, const void *b_ptr, const ecs_type_info_t *type_info)
Compare hook to compare component instances.
Definition flecs.h:693
bool ecs_is_alive(const ecs_world_t *world, ecs_entity_t e)
Test whether an entity is alive.
Meta component mixin.
Metrics component mixin.
Int to enum.
Definition component.hpp:18
Component added to bitmask type entities.
Definition meta.h:312
Component added to enum type entities.
Definition meta.h:292
Component added to struct type entities.
Definition meta.h:271
Used with ecs_entity_init().
Definition flecs.h:1077
const char * sep
Optional custom separator for hierarchical names.
Definition flecs.h:1089
const char * root_sep
Optional, used for identifiers relative to the root.
Definition flecs.h:1093
const char * name
Name of the entity.
Definition flecs.h:1084
bool use_low_id
When set to true, a low id (typically reserved for components) will be used to create the entity,...
Definition flecs.h:1105
ecs_copy_t copy_ctor
Ctor + copy.
Definition flecs.h:985
ecs_iter_action_t on_remove
Callback that is invoked when an instance of the component is removed.
Definition flecs.h:1026
void * binding_ctx
Language binding context.
Definition flecs.h:1040
ecs_move_t move_dtor
Move + dtor.
Definition flecs.h:1000
ecs_flags32_t flags
Hook flags.
Definition flecs.h:1012
ecs_cmp_t cmp
Compare hook.
Definition flecs.h:1003
ecs_copy_t copy
copy assignment.
Definition flecs.h:981
ecs_on_validate_t on_validate
Callback that is invoked before the on_set/OnSet hooks and observers are invoked.
Definition flecs.h:1037
ecs_iter_action_t on_set
Callback that is invoked when an instance of the component is set.
Definition flecs.h:1021
ecs_move_t move
move assignment.
Definition flecs.h:982
ecs_xtor_t ctor
ctor.
Definition flecs.h:979
ecs_iter_action_t on_replace
Callback that is invoked with the existing and new value before the value is assigned.
Definition flecs.h:1032
ecs_iter_action_t on_add
Callback that is invoked when an instance of a component is added.
Definition flecs.h:1016
ecs_ctx_free_t binding_ctx_free
Callback to free binding_ctx.
Definition flecs.h:1044
ecs_move_t move_ctor
Ctor + move.
Definition flecs.h:988
ecs_equals_t equals
Equals hook.
Definition flecs.h:1006
ecs_move_t ctor_move_dtor
Ctor + move + dtor (or move_ctor + dtor).
Definition flecs.h:994
ecs_xtor_t dtor
dtor.
Definition flecs.h:980
Type that contains component information (passed to ctors/dtors/...).
Definition flecs.h:1052
Component class.
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_replace(Func &&func)
Register on_replace hook.
component< T > & on_compare(cmp_hook callback)
Type-safe variant of the compare op function.
component< T > & on_add(Func &&func)
Register on_add hook.
component< T > & on_equals()
Register an operator equals hook using type T's equality operator.
component< T > & on_set(Func &&func)
Register on_set hook.
component< T > & on_validate(Func &&func)
Register on_validate hook.
component< T > & on_equals(equals_hook callback)
Type-safe variant of the equals op function.
component< T > & on_compare()
Register an operator compare hook using type T's comparison operators.
Trait that marks a component as DontFragment at compile time.
Definition utils.hpp:178
flecs::string_view name() const
Return the entity name.
entity()
Default constructor.
Definition entity.hpp:32
Class that wraps around a flecs::id_t.
Definition decl.hpp:27
flecs::id_t id_
The raw ID value.
Definition decl.hpp:154
flecs::world_t * world_
World is optional, but guarantees that entity identifiers extracted from the ID are valid.
Definition decl.hpp:152
Test if a type is a pair.
Definition pair.hpp:98
Trait that marks a component as Sparse at compile time.
Definition utils.hpp:187
untyped_component(flecs::world_t *world, flecs::entity_t id)
Construct from world and entity ID.
untyped_component(world_t *world, const char *name, const char *sep, const char *root_sep)
Construct from world, name, and scope separators.
untyped_component & on_compare(ecs_cmp_t compare_callback)
Register a custom compare hook for this component.
flecs::type_hooks_t get_hooks() const
Get the type hooks for this component.
untyped_component()
Default constructor.
untyped_component(flecs::entity_t id)
Construct from entity ID.
void set_hooks(flecs::type_hooks_t &h)
Set the type hooks for this component.
untyped_component(flecs::world_t *world, const char *name)
Construct from world and name.
entity()
Default constructor.
Definition entity.hpp:32
untyped_component & on_equals(ecs_equals_t equals_callback)
Register a custom equals hook for this component.
The world.
Definition world.hpp:129
enable_if_t< false==V, int > if_not_t
Convenience enable_if alias for negated conditions.
Definition utils.hpp:172
enable_if_t< V, int > if_t
Convenience enable_if alias using int as default type.
Definition utils.hpp:168
on_instantiate
OnInstantiate policies that can be assigned to a component at compile time with the flecs::on_instant...
Definition utils.hpp:194