Flecs v4.1
A fast entity component system (ECS) for C & C++
Loading...
Searching...
No Matches
flecs_c.h
Go to the documentation of this file.
1
6#ifndef FLECS_C_
7#define FLECS_C_
8
25#define ECS_DECLARE(id)\
26 ecs_entity_t id, ecs_id(id)
27
29#define ECS_ENTITY_DECLARE ECS_DECLARE
30
39#define ECS_ENTITY_DEFINE(world, id_, ...) \
40 { \
41 ecs_entity_desc_t desc = {0}; \
42 desc.id = id_; \
43 desc.name = #id_; \
44 desc.add_expr = #__VA_ARGS__; \
45 id_ = ecs_entity_init(world, &desc); \
46 ecs_id(id_) = id_; \
47 ecs_assert(id_ != 0, ECS_INVALID_PARAMETER, "failed to create entity %s", #id_); \
48 } \
49 (void)id_; \
50 (void)ecs_id(id_)
51
60#define ECS_ENTITY(world, id, ...) \
61 ecs_entity_t ecs_id(id); \
62 ecs_entity_t id = 0; \
63 ECS_ENTITY_DEFINE(world, id, __VA_ARGS__)
64
66#define ECS_TAG_DECLARE ECS_DECLARE
67
76#define ECS_TAG_DEFINE(world, id) ECS_ENTITY_DEFINE(world, id, 0)
77
86#define ECS_TAG(world, id) ECS_ENTITY(world, id, 0)
87
89#define ECS_PREFAB_DECLARE ECS_DECLARE
90
99#define ECS_PREFAB_DEFINE(world, id, ...) ECS_ENTITY_DEFINE(world, id, Prefab, __VA_ARGS__)
100
109#define ECS_PREFAB(world, id, ...) ECS_ENTITY(world, id, Prefab, __VA_ARGS__)
110
112#define ECS_COMPONENT_DECLARE(id) ecs_entity_t ecs_id(id)
113
122#define ECS_COMPONENT_DEFINE(world, id_) \
123 {\
124 ecs_component_desc_t desc = {0}; \
125 ecs_entity_desc_t edesc = {0}; \
126 edesc.id = ecs_id(id_); \
127 edesc.use_low_id = true; \
128 edesc.name = #id_; \
129 edesc.symbol = #id_; \
130 desc.entity = ecs_entity_init(world, &edesc); \
131 desc.type.size = ECS_SIZEOF(id_); \
132 desc.type.alignment = ECS_ALIGNOF(id_); \
133 ecs_id(id_) = ecs_component_init(world, &desc);\
134 }\
135 ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, "failed to create component %s", #id_)
136
145#define ECS_COMPONENT(world, id)\
146 ecs_entity_t ecs_id(id) = 0;\
147 ECS_COMPONENT_DEFINE(world, id);\
148 (void)ecs_id(id)
149
151#define ECS_OBSERVER_DECLARE(id) ecs_entity_t ecs_id(id)
152
161#define ECS_OBSERVER_DEFINE(world, id_, kind, ...)\
162 {\
163 ecs_observer_desc_t desc = {0};\
164 ecs_entity_desc_t edesc = {0}; \
165 edesc.id = ecs_id(id_); \
166 edesc.name = #id_; \
167 desc.entity = ecs_entity_init(world, &edesc); \
168 desc.callback = id_;\
169 desc.query.expr = #__VA_ARGS__;\
170 desc.events[0] = kind;\
171 ecs_id(id_) = ecs_observer_init(world, &desc);\
172 ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, "failed to create observer %s", #id_);\
173 }
174
183#define ECS_OBSERVER(world, id, kind, ...)\
184 ecs_entity_t ecs_id(id) = 0; \
185 ECS_OBSERVER_DEFINE(world, id, kind, __VA_ARGS__);\
186 ecs_entity_t id = ecs_id(id);\
187 (void)ecs_id(id);\
188 (void)id
189
191#define ECS_QUERY_DECLARE(name) ecs_query_t* name
192
201#define ECS_QUERY_DEFINE(world, name_, ...)\
202 {\
203 ecs_query_desc_t desc = {0};\
204 ecs_entity_desc_t edesc = {0}; \
205 edesc.name = #name_; \
206 desc.entity = ecs_entity_init(world, &edesc); \
207 desc.expr = #__VA_ARGS__;\
208 name_ = ecs_query_init(world, &desc);\
209 ecs_assert(name_ != NULL, ECS_INVALID_PARAMETER, "failed to create query %s", #name_);\
210 }
211
220#define ECS_QUERY(world, name, ...)\
221 ecs_query_t* name = NULL; \
222 ECS_QUERY_DEFINE(world, name, __VA_ARGS__);\
223 (void)name
224
235#define ecs_entity(world, ...)\
236 ecs_entity_init(world, &(ecs_entity_desc_t) __VA_ARGS__ )
237
249#define ecs_component(world, ...)\
250 ecs_component_init(world, &(ecs_component_desc_t) __VA_ARGS__ )
251
262#define ecs_query(world, ...)\
263 ecs_query_init(world, &(ecs_query_desc_t) __VA_ARGS__ )
264
277#define ecs_observer(world, ...)\
278 ecs_observer_init(world, &(ecs_observer_desc_t) __VA_ARGS__ )
279
300#define ecs_new_w(world, T) ecs_new_w_id(world, ecs_id(T))
301
303#define ecs_new_w_pair(world, first, second)\
304 ecs_new_w_id(world, ecs_pair(first, second))
305
307#define ecs_bulk_new(world, component, count)\
308 ecs_bulk_new_w_id(world, ecs_id(component), count)
309
318#define ecs_add(world, entity, T)\
319 ecs_add_id(world, entity, ecs_id(T))
320
322#define ecs_add_pair(world, subject, first, second)\
323 ecs_add_id(world, subject, ecs_pair(first, second))
324
326#define ecs_remove(world, entity, T)\
327 ecs_remove_id(world, entity, ecs_id(T))
328
330#define ecs_remove_pair(world, subject, first, second)\
331 ecs_remove_id(world, subject, ecs_pair(first, second))
332
334#define ecs_auto_override(world, entity, T)\
335 ecs_auto_override_id(world, entity, ecs_id(T))
336
338#define ecs_auto_override_pair(world, subject, first, second)\
339 ecs_auto_override_id(world, subject, ecs_pair(first, second))
340
349#define ecs_insert(world, ...)\
350 ecs_entity(world, { .set = ecs_values(__VA_ARGS__)})
351
353#define ecs_set_ptr(world, entity, component, ptr)\
354 ecs_set_id(world, entity, ecs_id(component), sizeof(component), ptr)
355
357#define ecs_set(world, entity, component, ...)\
358 ecs_set_id(world, entity, ecs_id(component), sizeof(component), &(component)__VA_ARGS__)
359
361#define ecs_set_pair(world, subject, First, second, ...)\
362 ecs_set_id(world, subject,\
363 ecs_pair(ecs_id(First), second),\
364 sizeof(First), &(First)__VA_ARGS__)
365
367#define ecs_set_pair_second(world, subject, first, Second, ...)\
368 ecs_set_id(world, subject,\
369 ecs_pair(first, ecs_id(Second)),\
370 sizeof(Second), &(Second)__VA_ARGS__)
371
373#define ecs_set_override(world, entity, T, ...)\
374 ecs_add_id(world, entity, ECS_AUTO_OVERRIDE | ecs_id(T));\
375 ecs_set(world, entity, T, __VA_ARGS__)
376
378#define ecs_emplace(world, entity, T, is_new)\
379 (ECS_CAST(T*, ecs_emplace_id(world, entity, ecs_id(T), sizeof(T), is_new)))
380
382#define ecs_emplace_pair(world, entity, First, second, is_new)\
383 (ECS_CAST(First*, ecs_emplace_id(world, entity, ecs_pair_t(First, second), sizeof(First), is_new)))
384
386#define ecs_get(world, entity, T)\
387 (ECS_CAST(const T*, ecs_get_id(world, entity, ecs_id(T))))
388
390#define ecs_get_pair(world, subject, First, second)\
391 (ECS_CAST(const First*, ecs_get_id(world, subject,\
392 ecs_pair(ecs_id(First), second))))
393
395#define ecs_get_pair_second(world, subject, first, Second)\
396 (ECS_CAST(const Second*, ecs_get_id(world, subject,\
397 ecs_pair(first, ecs_id(Second)))))
398
400#define ecs_get_mut(world, entity, T)\
401 (ECS_CAST(T*, ecs_get_mut_id(world, entity, ecs_id(T))))
402
404#define ecs_get_mut_pair(world, subject, First, second)\
405 (ECS_CAST(First*, ecs_get_mut_id(world, subject,\
406 ecs_pair(ecs_id(First), second))))
407
409#define ecs_get_mut_pair_second(world, subject, first, Second)\
410 (ECS_CAST(Second*, ecs_get_mut_id(world, subject,\
411 ecs_pair(first, ecs_id(Second)))))
412
414#define ecs_get_mut(world, entity, T)\
415 (ECS_CAST(T*, ecs_get_mut_id(world, entity, ecs_id(T))))
416
418#define ecs_ensure(world, entity, T)\
419 (ECS_CAST(T*, ecs_ensure_id(world, entity, ecs_id(T), sizeof(T))))
420
422#define ecs_ensure_pair(world, subject, First, second)\
423 (ECS_CAST(First*, ecs_ensure_id(world, subject,\
424 ecs_pair(ecs_id(First), second), sizeof(First))))
425
427#define ecs_ensure_pair_second(world, subject, first, Second)\
428 (ECS_CAST(Second*, ecs_ensure_id(world, subject,\
429 ecs_pair(first, ecs_id(Second)), sizeof(Second))))
430
432#define ecs_modified(world, entity, component)\
433 ecs_modified_id(world, entity, ecs_id(component))
434
436#define ecs_modified_pair(world, subject, first, second)\
437 ecs_modified_id(world, subject, ecs_pair(first, second))
438
440#define ecs_record_get(world, record, T)\
441 (ECS_CAST(const T*, ecs_record_get_id(world, record, ecs_id(T))))
442
444#define ecs_record_has(world, record, T)\
445 (ecs_record_has_id(world, record, ecs_id(T)))
446
448#define ecs_record_get_pair(world, record, First, second)\
449 (ECS_CAST(const First*, ecs_record_get_id(world, record, \
450 ecs_pair(ecs_id(First), second))))
451
453#define ecs_record_get_pair_second(world, record, first, Second)\
454 (ECS_CAST(const Second*, ecs_record_get_id(world, record,\
455 ecs_pair(first, ecs_id(Second)))))
456
458#define ecs_record_ensure(world, record, T)\
459 (ECS_CAST(T*, ecs_record_ensure_id(world, record, ecs_id(T))))
460
462#define ecs_record_ensure_pair(world, record, First, second)\
463 (ECS_CAST(First*, ecs_record_ensure_id(world, record, \
464 ecs_pair(ecs_id(First), second))))
465
467#define ecs_record_ensure_pair_second(world, record, first, Second)\
468 (ECS_CAST(Second*, ecs_record_ensure_id(world, record,\
469 ecs_pair(first, ecs_id(Second)))))
470
472#define ecs_ref_init(world, entity, T)\
473 ecs_ref_init_id(world, entity, ecs_id(T))
474
476#define ecs_ref_get(world, ref, T)\
477 (ECS_CAST(T*, ecs_ref_get_id(world, ref, ecs_id(T))))
478
487#define ecs_singleton_add(world, comp)\
488 ecs_add(world, ecs_id(comp), comp)
489
491#define ecs_singleton_remove(world, comp)\
492 ecs_remove(world, ecs_id(comp), comp)
493
495#define ecs_singleton_get(world, comp)\
496 ecs_get(world, ecs_id(comp), comp)
497
499#define ecs_singleton_get_mut(world, comp)\
500 ecs_get_mut(world, ecs_id(comp), comp)
501
503#define ecs_singleton_set_ptr(world, comp, ptr)\
504 ecs_set_ptr(world, ecs_id(comp), comp, ptr)
505
507#define ecs_singleton_set(world, comp, ...)\
508 ecs_set(world, ecs_id(comp), comp, __VA_ARGS__)
509
511#define ecs_singleton_ensure(world, comp)\
512 ecs_ensure(world, ecs_id(comp), comp)
513
515#define ecs_singleton_emplace(world, comp, is_new)\
516 ecs_emplace(world, ecs_id(comp), comp, is_new)
517
519#define ecs_singleton_modified(world, comp)\
520 ecs_modified(world, ecs_id(comp), comp)
521
530#define ecs_has(world, entity, T)\
531 ecs_has_id(world, entity, ecs_id(T))
532
534#define ecs_has_pair(world, entity, first, second)\
535 ecs_has_id(world, entity, ecs_pair(first, second))
536
538#define ecs_owns_pair(world, entity, first, second)\
539 ecs_owns_id(world, entity, ecs_pair(first, second))
540
542#define ecs_owns(world, entity, T)\
543 ecs_owns_id(world, entity, ecs_id(T))
544
546#define ecs_shares_id(world, entity, id)\
547 (ecs_search_relation(world, ecs_get_table(world, entity), 0, ecs_id(id), \
548 EcsIsA, 1, 0, 0, 0, 0) != -1)
549
551#define ecs_shares_pair(world, entity, first, second)\
552 (ecs_shares_id(world, entity, ecs_pair(first, second)))
553
555#define ecs_shares(world, entity, T)\
556 (ecs_shares_id(world, entity, ecs_id(T)))
557
559#define ecs_get_target_for(world, entity, rel, T)\
560 ecs_get_target_for_id(world, entity, rel, ecs_id(T))
561
570#define ecs_enable_component(world, entity, T, enable)\
571 ecs_enable_id(world, entity, ecs_id(T), enable)
572
574#define ecs_is_enabled(world, entity, T)\
575 ecs_is_enabled_id(world, entity, ecs_id(T))
576
578#define ecs_enable_pair(world, entity, First, second, enable)\
579 ecs_enable_id(world, entity, ecs_pair(ecs_id(First), second), enable)
580
582#define ecs_is_enabled_pair(world, entity, First, second)\
583 ecs_is_enabled_id(world, entity, ecs_pair(ecs_id(First), second))
584
593#define ecs_lookup_from(world, parent, path)\
594 ecs_lookup_path_w_sep(world, parent, path, ".", NULL, true)
595
597#define ecs_get_path_from(world, parent, child)\
598 ecs_get_path_w_sep(world, parent, child, ".", NULL)
599
601#define ecs_get_path(world, child)\
602 ecs_get_path_w_sep(world, 0, child, ".", NULL)
603
605#define ecs_get_path_buf(world, child, buf)\
606 ecs_get_path_w_sep_buf(world, 0, child, ".", NULL, buf, false)
607
609#define ecs_new_from_path(world, parent, path)\
610 ecs_new_from_path_w_sep(world, parent, path, ".", NULL)
611
613#define ecs_add_path(world, entity, parent, path)\
614 ecs_add_path_w_sep(world, entity, parent, path, ".", NULL)
615
617#define ecs_add_fullpath(world, entity, path)\
618 ecs_add_path_w_sep(world, entity, 0, path, ".", NULL)
619
630#define ecs_set_hooks(world, T, ...)\
631 ecs_set_hooks_id(world, ecs_id(T), &(ecs_type_hooks_t)__VA_ARGS__)
632
634#define ecs_get_hooks(world, T)\
635 ecs_get_hooks_id(world, ecs_id(T));
636
644#define ECS_CTOR(type, var, ...)\
645 ECS_XTOR_IMPL(type, ctor, var, __VA_ARGS__)
646
654#define ECS_DTOR(type, var, ...)\
655 ECS_XTOR_IMPL(type, dtor, var, __VA_ARGS__)
656
664#define ECS_COPY(type, dst_var, src_var, ...)\
665 ECS_COPY_IMPL(type, dst_var, src_var, __VA_ARGS__)
666
674#define ECS_MOVE(type, dst_var, src_var, ...)\
675 ECS_MOVE_IMPL(type, dst_var, src_var, __VA_ARGS__)
676
684#define ECS_ON_ADD(type, ptr, ...)\
685 ECS_HOOK_IMPL(type, ecs_on_add(type), ptr, __VA_ARGS__)
687#define ECS_ON_REMOVE(type, ptr, ...)\
688 ECS_HOOK_IMPL(type, ecs_on_remove(type), ptr, __VA_ARGS__)
690#define ECS_ON_SET(type, ptr, ...)\
691 ECS_HOOK_IMPL(type, ecs_on_set(type), ptr, __VA_ARGS__)
692
694#define ecs_ctor(type) type##_ctor
696#define ecs_dtor(type) type##_dtor
698#define ecs_copy(type) type##_copy
700#define ecs_move(type) type##_move
702#define ecs_on_set(type) type##_on_set
704#define ecs_on_add(type) type##_on_add
706#define ecs_on_remove(type) type##_on_remove
707
716#define ecs_count(world, type)\
717 ecs_count_id(world, ecs_id(type))
718
727#define ecs_field(it, T, index)\
728 (ECS_CAST(T*, ecs_field_w_size(it, sizeof(T), index)))
729
731#define ecs_field_self(it, T, index)\
732 (ECS_CAST(T*, ecs_field_self_w_size(it, sizeof(T), index)))
733
735#define ecs_field_at(it, T, index, row)\
736 (ECS_CAST(T*, ecs_field_at_w_size(it, sizeof(T), index, row)))
737
746#define ecs_table_get(world, table, T, offset)\
747 (ECS_CAST(T*, ecs_table_get_id(world, table, ecs_id(T), offset)))
748
750#define ecs_table_get_pair(world, table, First, second, offset)\
751 (ECS_CAST(First*, ecs_table_get_id(world, table, ecs_pair(ecs_id(First), second), offset)))
752
754#define ecs_table_get_pair_second(world, table, first, Second, offset)\
755 (ECS_CAST(Second*, ecs_table_get_id(world, table, ecs_pair(first, ecs_id(Second)), offset)))
756
765#define ecs_ids(...) (ecs_id_t[]){ __VA_ARGS__, 0 }
766
768#define ecs_values(...) (ecs_value_t[]){ __VA_ARGS__, {0, 0}}
769
771#define ecs_value_ptr(T, ptr) ((ecs_value_t){ecs_id(T), ptr})
772
774#define ecs_pair_value(R, t, ...) ((ecs_value_t){ecs_pair_t(R, t), &(R)__VA_ARGS__})
775
777#define ecs_pair_value_2nd(r, T, ...) ((ecs_value_t){ecs_pair(r, ecs_id(T)), &(T)__VA_ARGS__})
778
780#define ecs_value_new_t(world, T) ecs_value_new(world, ecs_id(T))
781
783#define ecs_value(T, ...) ((ecs_value_t){ecs_id(T), &(T)__VA_ARGS__})
784
796#define ecs_sort_table(id) ecs_id(id##_sort_table)
797
799#define ecs_compare(id) ecs_id(id##_compare_fn)
800
824#define ECS_SORT_TABLE_WITH_COMPARE(id, op_name, compare_fn, ...) \
825 static int32_t ECS_CONCAT(op_name, _partition)( \
826 ecs_world_t *world, \
827 ecs_table_t *table, \
828 ecs_entity_t *entities, \
829 void *ptr, \
830 int32_t elem_size, \
831 int32_t lo, \
832 int32_t hi, \
833 ecs_order_by_action_t order_by) \
834 { \
835 (void)(order_by); \
836 int32_t p = (hi + lo) / 2; \
837 void *pivot = ECS_ELEM(ptr, elem_size, p); \
838 ecs_entity_t pivot_e = entities[p]; \
839 int32_t i = lo - 1, j = hi + 1; \
840 void *el; \
841 repeat: \
842 { \
843 do { \
844 i ++; \
845 el = ECS_ELEM(ptr, elem_size, i); \
846 } while ( compare_fn(entities[i], el, pivot_e, pivot) < 0); \
847 do { \
848 j --; \
849 el = ECS_ELEM(ptr, elem_size, j); \
850 } while ( compare_fn(entities[j], el, pivot_e, pivot) > 0); \
851 if (i >= j) { \
852 return j; \
853 } \
854 ecs_table_swap_rows(world, table, i, j); \
855 if (p == i) { \
856 pivot = ECS_ELEM(ptr, elem_size, j); \
857 pivot_e = entities[j]; \
858 } else if (p == j) { \
859 pivot = ECS_ELEM(ptr, elem_size, i); \
860 pivot_e = entities[i]; \
861 } \
862 goto repeat; \
863 } \
864 } \
865 __VA_ARGS__ void op_name( \
866 ecs_world_t *world, \
867 ecs_table_t *table, \
868 ecs_entity_t *entities, \
869 void *ptr, \
870 int32_t size, \
871 int32_t lo, \
872 int32_t hi, \
873 ecs_order_by_action_t order_by) \
874 { \
875 if ((hi - lo) < 1) { \
876 return; \
877 } \
878 int32_t p = ECS_CONCAT(op_name, _partition)(world, table, entities, ptr, size, lo, hi, order_by); \
879 op_name(world, table, entities, ptr, size, lo, p, order_by); \
880 op_name(world, table, entities, ptr, size, p + 1, hi, order_by); \
881 }
882
894#define ECS_SORT_TABLE(id, ...) \
895 ECS_SORT_TABLE_WITH_COMPARE(id, ecs_sort_table(id), ecs_compare(id), __VA_ARGS__)
896
907#define ECS_COMPARE(id, ...) \
908 int ecs_compare(id)(ecs_entity_t e1, const void* ptr1, ecs_entity_t e2, const void* ptr2) { \
909 __VA_ARGS__ \
910 }
911
922#define ecs_isa(e) ecs_pair(EcsIsA, e)
924#define ecs_childof(e) ecs_pair(EcsChildOf, e)
926#define ecs_dependson(e) ecs_pair(EcsDependsOn, e)
928#define ecs_with(e) ecs_pair(EcsWith, e)
929
931#define ecs_each(world, id) ecs_each_id(world, ecs_id(id))
933#define ecs_each_pair(world, r, t) ecs_each_id(world, ecs_pair(r, t))
935#define ecs_each_pair_t(world, R, t) ecs_each_id(world, ecs_pair(ecs_id(R), t))
936
941#endif // FLECS_C_