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_