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_TAG_DECLARE ECS_DECLARE
30
39#define ECS_TAG_DEFINE(world, id_) \
40 { \
41 ecs_entity_desc_t desc = {0}; \
42 desc.id = id_; \
43 desc.name = #id_; \
44 id_ = ecs_entity_init(world, &desc); \
45 ecs_id(id_) = id_; \
46 ecs_assert(id_ != 0, ECS_INVALID_PARAMETER, "failed to create tag %s", #id_); \
47 } \
48 (void)id_; \
49 (void)ecs_id(id_)
50
59#define ECS_TAG(world, id) \
60 ecs_entity_t ecs_id(id); \
61 ecs_entity_t id = 0; \
62 ECS_TAG_DEFINE(world, id)
63
65#define ECS_COMPONENT_DECLARE(id) ecs_entity_t ecs_id(id)
66
75#define ECS_COMPONENT_DEFINE(world, id_) \
76 {\
77 ecs_component_desc_t desc = {0}; \
78 ecs_entity_desc_t edesc = {0}; \
79 edesc.id = ecs_id(id_); \
80 edesc.use_low_id = true; \
81 edesc.name = #id_; \
82 edesc.symbol = #id_; \
83 desc.entity = ecs_entity_init(world, &edesc); \
84 desc.type.size = ECS_SIZEOF(id_); \
85 desc.type.alignment = ECS_ALIGNOF(id_); \
86 ecs_id(id_) = ecs_component_init(world, &desc);\
87 }\
88 ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, "failed to create component %s", #id_)
89
98#define ECS_COMPONENT(world, id)\
99 ecs_entity_t ecs_id(id) = 0;\
100 ECS_COMPONENT_DEFINE(world, id);\
101 (void)ecs_id(id)
102
104#define ECS_OBSERVER_DECLARE(id) ecs_entity_t ecs_id(id)
105
114#define ECS_OBSERVER_DEFINE(world, id_, kind, ...)\
115 {\
116 ecs_observer_desc_t desc = {0};\
117 ecs_entity_desc_t edesc = {0}; \
118 edesc.id = ecs_id(id_); \
119 edesc.name = #id_; \
120 desc.entity = ecs_entity_init(world, &edesc); \
121 desc.callback = id_;\
122 desc.query.expr = #__VA_ARGS__;\
123 desc.events[0] = kind;\
124 ecs_id(id_) = ecs_observer_init(world, &desc);\
125 ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, "failed to create observer %s", #id_);\
126 }
127
136#define ECS_OBSERVER(world, id, kind, ...)\
137 ecs_entity_t ecs_id(id) = 0; \
138 ECS_OBSERVER_DEFINE(world, id, kind, __VA_ARGS__);\
139 ecs_entity_t id = ecs_id(id);\
140 (void)ecs_id(id);\
141 (void)id
142
144#define ECS_QUERY_DECLARE(name) ecs_query_t* name
145
154#define ECS_QUERY_DEFINE(world, name_, ...)\
155 {\
156 ecs_query_desc_t desc = {0};\
157 ecs_entity_desc_t edesc = {0}; \
158 edesc.name = #name_; \
159 desc.entity = ecs_entity_init(world, &edesc); \
160 desc.expr = #__VA_ARGS__;\
161 name_ = ecs_query_init(world, &desc);\
162 ecs_assert(name_ != NULL, ECS_INVALID_PARAMETER, "failed to create query %s", #name_);\
163 }
164
173#define ECS_QUERY(world, name, ...)\
174 ecs_query_t* name = NULL; \
175 ECS_QUERY_DEFINE(world, name, __VA_ARGS__);\
176 (void)name
177
188#define ecs_entity(world, ...)\
189 ecs_entity_init(world, &(ecs_entity_desc_t) __VA_ARGS__ )
190
202#define ecs_component(world, ...)\
203 ecs_component_init(world, &(ecs_component_desc_t) __VA_ARGS__ )
204
215#define ecs_query(world, ...)\
216 ecs_query_init(world, &(ecs_query_desc_t) __VA_ARGS__ )
217
230#define ecs_observer(world, ...)\
231 ecs_observer_init(world, &(ecs_observer_desc_t) __VA_ARGS__ )
232
253#define ecs_new_w(world, T) ecs_new_w_id(world, ecs_id(T))
254
256#define ecs_new_w_pair(world, first, second)\
257 ecs_new_w_id(world, ecs_pair(first, second))
258
260#define ecs_bulk_new(world, component, count)\
261 ecs_bulk_new_w_id(world, ecs_id(component), count)
262
271#define ecs_add(world, entity, T)\
272 ecs_add_id(world, entity, ecs_id(T))
273
275#define ecs_add_pair(world, subject, first, second)\
276 ecs_add_id(world, subject, ecs_pair(first, second))
277
279#define ecs_remove(world, entity, T)\
280 ecs_remove_id(world, entity, ecs_id(T))
281
283#define ecs_remove_pair(world, subject, first, second)\
284 ecs_remove_id(world, subject, ecs_pair(first, second))
285
287#define ecs_auto_override(world, entity, T)\
288 ecs_auto_override_id(world, entity, ecs_id(T))
289
291#define ecs_auto_override_pair(world, subject, first, second)\
292 ecs_auto_override_id(world, subject, ecs_pair(first, second))
293
302#define ecs_insert(world, ...)\
303 ecs_insert_w_values(world, ecs_values(__VA_ARGS__))
304
306#define ecs_set_ptr(world, entity, component, ptr)\
307 ecs_set_id(world, entity, ecs_id(component), sizeof(component), ptr)
308
310#define ecs_set(world, entity, component, ...)\
311 ecs_set_id(world, entity, ecs_id(component), sizeof(component), &(component)__VA_ARGS__)
312
314#define ecs_set_pair(world, subject, First, second, ...)\
315 ecs_set_id(world, subject,\
316 ecs_pair(ecs_id(First), second),\
317 sizeof(First), &(First)__VA_ARGS__)
318
320#define ecs_set_pair_second(world, subject, first, Second, ...)\
321 ecs_set_id(world, subject,\
322 ecs_pair(first, ecs_id(Second)),\
323 sizeof(Second), &(Second)__VA_ARGS__)
324
326#define ecs_set_override(world, entity, T, ...)\
327 ecs_add_id(world, entity, ECS_AUTO_OVERRIDE | ecs_id(T));\
328 ecs_set(world, entity, T, __VA_ARGS__)
329
331#define ecs_emplace(world, entity, T, is_new)\
332 (ECS_CAST(T*, ecs_emplace_id(world, entity, ecs_id(T), sizeof(T), is_new)))
333
335#define ecs_emplace_pair(world, entity, First, second, is_new)\
336 (ECS_CAST(First*, ecs_emplace_id(world, entity, ecs_pair_t(First, second), sizeof(First), is_new)))
337
339#define ecs_get(world, entity, T)\
340 (ECS_CAST(const T*, ecs_get_id(world, entity, ecs_id(T))))
341
343#define ecs_get_pair(world, subject, First, second)\
344 (ECS_CAST(const First*, ecs_get_id(world, subject,\
345 ecs_pair(ecs_id(First), second))))
346
348#define ecs_get_pair_second(world, subject, first, Second)\
349 (ECS_CAST(const Second*, ecs_get_id(world, subject,\
350 ecs_pair(first, ecs_id(Second)))))
351
353#define ecs_get_mut(world, entity, T)\
354 (ECS_CAST(T*, ecs_get_mut_id(world, entity, ecs_id(T))))
355
357#define ecs_get_mut_pair(world, subject, First, second)\
358 (ECS_CAST(First*, ecs_get_mut_id(world, subject,\
359 ecs_pair(ecs_id(First), second))))
360
362#define ecs_get_mut_pair_second(world, subject, first, Second)\
363 (ECS_CAST(Second*, ecs_get_mut_id(world, subject,\
364 ecs_pair(first, ecs_id(Second)))))
365
367#define ecs_get_mut(world, entity, T)\
368 (ECS_CAST(T*, ecs_get_mut_id(world, entity, ecs_id(T))))
369
371#define ecs_ensure(world, entity, T)\
372 (ECS_CAST(T*, ecs_ensure_id(world, entity, ecs_id(T), sizeof(T))))
373
375#define ecs_ensure_pair(world, subject, First, second)\
376 (ECS_CAST(First*, ecs_ensure_id(world, subject,\
377 ecs_pair(ecs_id(First), second), sizeof(First))))
378
380#define ecs_ensure_pair_second(world, subject, first, Second)\
381 (ECS_CAST(Second*, ecs_ensure_id(world, subject,\
382 ecs_pair(first, ecs_id(Second)), sizeof(Second))))
383
385#define ecs_modified(world, entity, component)\
386 ecs_modified_id(world, entity, ecs_id(component))
387
389#define ecs_modified_pair(world, subject, first, second)\
390 ecs_modified_id(world, subject, ecs_pair(first, second))
391
393#define ecs_record_get(world, record, T)\
394 (ECS_CAST(const T*, ecs_record_get_id(world, record, ecs_id(T))))
395
397#define ecs_record_has(world, record, T)\
398 (ecs_record_has_id(world, record, ecs_id(T)))
399
401#define ecs_record_get_pair(world, record, First, second)\
402 (ECS_CAST(const First*, ecs_record_get_id(world, record, \
403 ecs_pair(ecs_id(First), second))))
404
406#define ecs_record_get_pair_second(world, record, first, Second)\
407 (ECS_CAST(const Second*, ecs_record_get_id(world, record,\
408 ecs_pair(first, ecs_id(Second)))))
409
411#define ecs_record_ensure(world, record, T)\
412 (ECS_CAST(T*, ecs_record_ensure_id(world, record, ecs_id(T))))
413
415#define ecs_record_ensure_pair(world, record, First, second)\
416 (ECS_CAST(First*, ecs_record_ensure_id(world, record, \
417 ecs_pair(ecs_id(First), second))))
418
420#define ecs_record_ensure_pair_second(world, record, first, Second)\
421 (ECS_CAST(Second*, ecs_record_ensure_id(world, record,\
422 ecs_pair(first, ecs_id(Second)))))
423
425#define ecs_ref_init(world, entity, T)\
426 ecs_ref_init_id(world, entity, ecs_id(T))
427
429#define ecs_ref_get(world, ref, T)\
430 (ECS_CAST(T*, ecs_ref_get_id(world, ref, ecs_id(T))))
431
440#define ecs_singleton_add(world, comp)\
441 ecs_add(world, ecs_id(comp), comp)
442
444#define ecs_singleton_remove(world, comp)\
445 ecs_remove(world, ecs_id(comp), comp)
446
448#define ecs_singleton_get(world, comp)\
449 ecs_get(world, ecs_id(comp), comp)
450
452#define ecs_singleton_get_mut(world, comp)\
453 ecs_get_mut(world, ecs_id(comp), comp)
454
456#define ecs_singleton_set_ptr(world, comp, ptr)\
457 ecs_set_ptr(world, ecs_id(comp), comp, ptr)
458
460#define ecs_singleton_set(world, comp, ...)\
461 ecs_set(world, ecs_id(comp), comp, __VA_ARGS__)
462
464#define ecs_singleton_ensure(world, comp)\
465 ecs_ensure(world, ecs_id(comp), comp)
466
468#define ecs_singleton_emplace(world, comp, is_new)\
469 ecs_emplace(world, ecs_id(comp), comp, is_new)
470
472#define ecs_singleton_modified(world, comp)\
473 ecs_modified(world, ecs_id(comp), comp)
474
483#define ecs_has(world, entity, T)\
484 ecs_has_id(world, entity, ecs_id(T))
485
487#define ecs_has_pair(world, entity, first, second)\
488 ecs_has_id(world, entity, ecs_pair(first, second))
489
491#define ecs_owns_pair(world, entity, first, second)\
492 ecs_owns_id(world, entity, ecs_pair(first, second))
493
495#define ecs_owns(world, entity, T)\
496 ecs_owns_id(world, entity, ecs_id(T))
497
499#define ecs_shares_id(world, entity, id)\
500 (ecs_search_relation(world, ecs_get_table(world, entity), 0, ecs_id(id), \
501 EcsIsA, 1, 0, 0, 0, 0) != -1)
502
504#define ecs_shares_pair(world, entity, first, second)\
505 (ecs_shares_id(world, entity, ecs_pair(first, second)))
506
508#define ecs_shares(world, entity, T)\
509 (ecs_shares_id(world, entity, ecs_id(T)))
510
512#define ecs_get_target_for(world, entity, rel, T)\
513 ecs_get_target_for_id(world, entity, rel, ecs_id(T))
514
523#define ecs_enable_component(world, entity, T, enable)\
524 ecs_enable_id(world, entity, ecs_id(T), enable)
525
527#define ecs_is_enabled(world, entity, T)\
528 ecs_is_enabled_id(world, entity, ecs_id(T))
529
531#define ecs_enable_pair(world, entity, First, second, enable)\
532 ecs_enable_id(world, entity, ecs_pair(ecs_id(First), second), enable)
533
535#define ecs_is_enabled_pair(world, entity, First, second)\
536 ecs_is_enabled_id(world, entity, ecs_pair(ecs_id(First), second))
537
546#define ecs_lookup_from(world, parent, path)\
547 ecs_lookup_path_w_sep(world, parent, path, ".", NULL, true)
548
550#define ecs_get_path_from(world, parent, child)\
551 ecs_get_path_w_sep(world, parent, child, ".", NULL)
552
554#define ecs_get_path(world, child)\
555 ecs_get_path_w_sep(world, 0, child, ".", NULL)
556
558#define ecs_get_path_buf(world, child, buf)\
559 ecs_get_path_w_sep_buf(world, 0, child, ".", NULL, buf, false)
560
562#define ecs_new_from_path(world, parent, path)\
563 ecs_new_from_path_w_sep(world, parent, path, ".", NULL)
564
566#define ecs_add_path(world, entity, parent, path)\
567 ecs_add_path_w_sep(world, entity, parent, path, ".", NULL)
568
570#define ecs_add_fullpath(world, entity, path)\
571 ecs_add_path_w_sep(world, entity, 0, path, ".", NULL)
572
583#define ecs_set_hooks(world, T, ...)\
584 ecs_set_hooks_id(world, ecs_id(T), &(ecs_type_hooks_t)__VA_ARGS__)
585
587#define ecs_get_hooks(world, T)\
588 ecs_get_hooks_id(world, ecs_id(T));
589
597#define ECS_CTOR(type, var, ...)\
598 ECS_XTOR_IMPL(type, ctor, var, __VA_ARGS__)
599
607#define ECS_DTOR(type, var, ...)\
608 ECS_XTOR_IMPL(type, dtor, var, __VA_ARGS__)
609
617#define ECS_COPY(type, dst_var, src_var, ...)\
618 ECS_COPY_IMPL(type, dst_var, src_var, __VA_ARGS__)
619
627#define ECS_MOVE(type, dst_var, src_var, ...)\
628 ECS_MOVE_IMPL(type, dst_var, src_var, __VA_ARGS__)
629
637#define ECS_ON_ADD(type, ptr, ...)\
638 ECS_HOOK_IMPL(type, ecs_on_add(type), ptr, __VA_ARGS__)
640#define ECS_ON_REMOVE(type, ptr, ...)\
641 ECS_HOOK_IMPL(type, ecs_on_remove(type), ptr, __VA_ARGS__)
643#define ECS_ON_SET(type, ptr, ...)\
644 ECS_HOOK_IMPL(type, ecs_on_set(type), ptr, __VA_ARGS__)
645
647#define ecs_ctor(type) type##_ctor
649#define ecs_dtor(type) type##_dtor
651#define ecs_copy(type) type##_copy
653#define ecs_move(type) type##_move
655#define ecs_on_set(type) type##_on_set
657#define ecs_on_add(type) type##_on_add
659#define ecs_on_remove(type) type##_on_remove
660
669#define ecs_count(world, type)\
670 ecs_count_id(world, ecs_id(type))
671
680#define ecs_field(it, T, index)\
681 (ECS_CAST(T*, ecs_field_w_size(it, sizeof(T), index)))
682
684#define ecs_field_self(it, T, index)\
685 (ECS_CAST(T*, ecs_field_self_w_size(it, sizeof(T), index)))
686
688#define ecs_field_at(it, T, index, row)\
689 (ECS_CAST(T*, ecs_field_at_w_size(it, sizeof(T), index, row)))
690
699#define ecs_table_get(world, table, T, offset)\
700 (ECS_CAST(T*, ecs_table_get_id(world, table, ecs_id(T), offset)))
701
703#define ecs_table_get_pair(world, table, First, second, offset)\
704 (ECS_CAST(First*, ecs_table_get_id(world, table, ecs_pair(ecs_id(First), second), offset)))
705
707#define ecs_table_get_pair_second(world, table, first, Second, offset)\
708 (ECS_CAST(Second*, ecs_table_get_id(world, table, ecs_pair(first, ecs_id(Second)), offset)))
709
718#define ecs_ids(...) (ecs_id_t[]){ __VA_ARGS__, 0 }
719
721#define ecs_values(...) (ecs_value_t[]){ __VA_ARGS__, {0, 0}}
722
724#define ecs_value_ptr(T, ptr) ((ecs_value_t){ecs_id(T), ptr})
725
727#define ecs_pair_value(R, t, ...) ((ecs_value_t){ecs_pair_t(R, t), &(R)__VA_ARGS__})
728
730#define ecs_pair_value_2nd(r, T, ...) ((ecs_value_t){ecs_pair(r, ecs_id(T)), &(T)__VA_ARGS__})
731
733#define ecs_ptr_new_t(world, T) ecs_ptr_new(world, ecs_id(T))
734
736#define ecs_value(T, ...) ((ecs_value_t){ecs_id(T), &(T)__VA_ARGS__})
737
749#define ecs_sort_table(id) ecs_id(id##_sort_table)
750
752#define ecs_compare(id) ecs_id(id##_compare_fn)
753
777#define ECS_SORT_TABLE_WITH_COMPARE(id, op_name, compare_fn, ...) \
778 static int32_t ECS_CONCAT(op_name, _partition)( \
779 ecs_world_t *world, \
780 ecs_table_t *table, \
781 ecs_entity_t *entities, \
782 void *ptr, \
783 int32_t elem_size, \
784 int32_t lo, \
785 int32_t hi, \
786 ecs_order_by_action_t order_by) \
787 { \
788 (void)(order_by); \
789 int32_t p = (hi + lo) / 2; \
790 void *pivot = ECS_ELEM(ptr, elem_size, p); \
791 ecs_entity_t pivot_e = entities[p]; \
792 int32_t i = lo - 1, j = hi + 1; \
793 void *el; \
794 repeat: \
795 { \
796 do { \
797 i ++; \
798 el = ECS_ELEM(ptr, elem_size, i); \
799 } while ( compare_fn(entities[i], el, pivot_e, pivot) < 0); \
800 do { \
801 j --; \
802 el = ECS_ELEM(ptr, elem_size, j); \
803 } while ( compare_fn(entities[j], el, pivot_e, pivot) > 0); \
804 if (i >= j) { \
805 return j; \
806 } \
807 ecs_table_swap_rows(world, table, i, j); \
808 if (p == i) { \
809 pivot = ECS_ELEM(ptr, elem_size, j); \
810 pivot_e = entities[j]; \
811 } else if (p == j) { \
812 pivot = ECS_ELEM(ptr, elem_size, i); \
813 pivot_e = entities[i]; \
814 } \
815 goto repeat; \
816 } \
817 } \
818 __VA_ARGS__ void op_name( \
819 ecs_world_t *world, \
820 ecs_table_t *table, \
821 ecs_entity_t *entities, \
822 void *ptr, \
823 int32_t size, \
824 int32_t lo, \
825 int32_t hi, \
826 ecs_order_by_action_t order_by) \
827 { \
828 if ((hi - lo) < 1) { \
829 return; \
830 } \
831 int32_t p = ECS_CONCAT(op_name, _partition)(world, table, entities, ptr, size, lo, hi, order_by); \
832 op_name(world, table, entities, ptr, size, lo, p, order_by); \
833 op_name(world, table, entities, ptr, size, p + 1, hi, order_by); \
834 }
835
847#define ECS_SORT_TABLE(id, ...) \
848 ECS_SORT_TABLE_WITH_COMPARE(id, ecs_sort_table(id), ecs_compare(id), __VA_ARGS__)
849
860#define ECS_COMPARE(id, ...) \
861 int ecs_compare(id)(ecs_entity_t e1, const void* ptr1, ecs_entity_t e2, const void* ptr2) { \
862 __VA_ARGS__ \
863 }
864
875#define ecs_isa(e) ecs_pair(EcsIsA, e)
877#define ecs_childof(e) ecs_pair(EcsChildOf, e)
879#define ecs_dependson(e) ecs_pair(EcsDependsOn, e)
881#define ecs_with(e) ecs_pair(EcsWith, e)
882
884#define ecs_each(world, id) ecs_each_id(world, ecs_id(id))
886#define ecs_each_pair(world, r, t) ecs_each_id(world, ecs_pair(r, t))
888#define ecs_each_pair_t(world, R, t) ecs_each_id(world, ecs_pair(ecs_id(R), t))
889
894#endif // FLECS_C_