-
-
Notifications
You must be signed in to change notification settings - Fork 413
/
flecs.h
2429 lines (2207 loc) · 83.9 KB
/
flecs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#ifndef FLECS_H
#define FLECS_H
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#ifndef __BAKE__
#include <stdint.h>
#endif
/* This file is generated by bake and contains macro's for
* importing/exporting symbols */
#include <flecs/bake_config.h>
/* The API uses the native bool type in C++, or a custom one in C */
#ifndef __cplusplus
#undef bool
#undef true
#undef false
typedef char bool;
#define false 0
#define true !false
#endif
#include <flecs/util/os_api.h>
#include <flecs/util/vector.h>
#include <flecs/util/chunked.h>
#include <flecs/util/map.h>
#include <flecs/util/os_api.h>
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////////////
//// Opaque types
////////////////////////////////////////////////////////////////////////////////
typedef struct ecs_world_t ecs_world_t;
typedef struct ecs_rows_t ecs_rows_t;
typedef struct ecs_reference_t ecs_reference_t;
typedef struct ecs_snapshot_t ecs_snapshot_t;
////////////////////////////////////////////////////////////////////////////////
//// Public types
////////////////////////////////////////////////////////////////////////////////
/* An entity identifier. */
typedef uint64_t ecs_entity_t;
/* A vector containing component identifiers used to describe an entity type. */
typedef const ecs_vector_t* ecs_type_t;
/** System kinds that determine when and how systems are ran */
typedef enum EcsSystemKind {
/* Periodic systems */
EcsOnLoad,
EcsPostLoad,
EcsPreUpdate,
EcsOnUpdate,
EcsOnValidate,
EcsPostUpdate,
EcsPreStore,
EcsOnStore,
/* Manual systems */
EcsManual,
/* Reactive systems */
EcsOnAdd,
EcsOnRemove,
EcsOnSet
} EcsSystemKind;
/** System action callback */
typedef void (*ecs_system_action_t)(
ecs_rows_t *data);
/** Initialization function signature of modules */
typedef void (*ecs_module_init_action_t)(
ecs_world_t *world,
int flags);
/** Types that describe a type filter.
* Filters provide a quick mechanism to query entities or run operations on
* entities of one or more types. Filters contain a components to include and
* components to exclude. Additionally, a filter can specify whether all or any
* of the components need to be matched, or whether it must be an exact match.
*
* When a filter contains only one component, Any and All are equivalent.
*
* Suppose an application has entities with the following types:
* 1. [Position]
* 2. [Position, Velocity]
* 3. [Position, Velocity, Mass]
*
* And the following filters
* A. include = [Position], All/Any
* B. include = [Position], Exact
* C. include = [Position, Velocity], All
* D. include = [Position, Velocity], Any
* E. exclude = [Position], All/Any
* F. exclude = [Position, Velocity], Exact
* G. include = [Position, Velocity], Exact
*
* Then these types would be matched like this:
* 1 2 3
* ---|---|---|---
* A | x | x | x
* B | x | |
* C | | x | x
* D | x | x | x
* E | | |
* F | x | | x
* G | | x |
*
* When the kind is left to EcsMatchDefault, the include_kind will be set to
* EcsMatchAll, while the exclude_kind will be set to EcsMatchAny.
*/
typedef enum ecs_match_kind_t {
EcsMatchDefault = 0,
EcsMatchAll,
EcsMatchAny,
EcsMatchExact
} ecs_match_kind_t;
typedef struct ecs_filter_t {
ecs_type_t include;
ecs_type_t exclude;
ecs_match_kind_t include_kind;
ecs_match_kind_t exclude_kind;
} ecs_filter_t;
/** The ecs_rows_t struct passes data from a system to a system callback. */
struct ecs_rows_t {
ecs_world_t *world; /* Current world */
ecs_entity_t system; /* Handle to current system */
int32_t *columns; /* Indices mapping system params to columns and refs */
uint16_t column_count; /* Number of columns for system */
void *table; /* Opaque structure with reference to table */
void *table_columns; /* Opaque structure with table column data */
void *system_data; /* Opaque strucutre with system internals */
ecs_reference_t *references; /* References to other entities */
ecs_entity_t *components; /* System-table specific list of components */
ecs_entity_t *entities; /* Entity row */
void *param; /* Userdata passed to on-demand system */
float delta_time; /* Time elapsed since last frame */
float world_time; /* Time elapsed since start of simulation */
uint32_t frame_offset; /* Offset relative to frame */
uint32_t table_offset; /* Current active table being processed */
uint32_t offset; /* Offset relative to current table */
uint32_t count; /* Number of rows to process by system */
ecs_entity_t interrupted_by; /* When set, system execution is interrupted */
};
////////////////////////////////////////////////////////////////////////////////
//// Public builtin components
////////////////////////////////////////////////////////////////////////////////
/** Component that contains an entity name */
typedef const char *EcsId;
/** Component that contains metadata about a component */
typedef struct EcsComponent {
uint32_t size;
} EcsComponent;
/** Metadata of an explicitly created type (ECS_TYPE or ecs_new_type) */
typedef struct EcsTypeComponent {
ecs_type_t type; /* Preserved nested types */
ecs_type_t resolved; /* Resolved nested types */
} EcsTypeComponent;
/** Component used to create prefabs and prefab hierarchies */
typedef struct EcsPrefab {
ecs_entity_t parent;
} EcsPrefab;
#include <flecs/util/api_support.h>
////////////////////////////////////////////////////////////////////////////////
//// Public constants
////////////////////////////////////////////////////////////////////////////////
/* Type masks used for marking entities as base or parent */
#define ECS_INSTANCEOF ((ecs_entity_t)1 << 63)
#define ECS_CHILDOF ((ecs_entity_t)1 << 62)
/** Type handles to builtin components */
FLECS_EXPORT
extern ecs_type_t
TEcsComponent,
TEcsTypeComponent,
TEcsPrefab,
TEcsPrefabParent,
TEcsPrefabBuilder,
TEcsRowSystem,
TEcsColSystem,
TEcsId,
TEcsHidden,
TEcsDisabled,
TEcsOnDemand;
/** Handles to builtin components */
#define EEcsComponent (1)
#define EEcsTypeComponent (2)
#define EEcsPrefab (3)
#define EEcsPrefabParent (4)
#define EEcsPrefabBuilder (5)
#define EEcsRowSystem (6)
#define EEcsColSystem (7)
#define EEcsId (8)
#define EEcsHidden (9)
#define EEcsDisabled (10)
#define EEcsOnDemand (11)
/** Builtin entity ids */
#define EcsWorld (13)
#define EcsSingleton (ECS_SINGLETON)
#define EcsInvalid (ECS_INVALID_ENTITY)
/** Value used to quickly check if component is builtin */
#define EcsLastBuiltin (EEcsColSystem)
/** This allows passing 0 as type to functions that accept types */
#define T0 (0)
////////////////////////////////////////////////////////////////////////////////
//// Declarative macro's
////////////////////////////////////////////////////////////////////////////////
#ifndef __BAKE_LEGACY__
/** Declare a named entity.
* This macro will declare a new entity with the provided id and components. The
* components are specified as a comma-separated list of identifiers, optionally
* with type flags. The order in which components are specified does not matter.
*
* Examples:
* ECS_ENTITY(world, MyEntity, Position, Velocity);
* ECS_ENTITY(world, MyEntity 0);
* ECS_ENTITY(world, MyEntity, Position, Velocity, CHILDOF | MyParentEntity);
*/
#define ECS_ENTITY(world, id, ...)\
ecs_entity_t id = ecs_new_entity(world, #id, #__VA_ARGS__);\
ECS_TYPE_VAR(id) = ecs_type_from_entity(world, id);\
(void)id;\
(void)ecs_type(id);
/** Declare a prefab.
* This macro will declare a new prefab with the provided id and components. The
* order in which components are specified does not matter. A prefab is similar
* to an entity except that prefabs are typically used in combination with
* INSTANCEOF to serve as entity templates. Prefabs are by default not matched
* with systems.
*
* Examples:
* ECS_PREFAB(world, MyPrefab, Position, Velocity);
* ECS_PREFAB(world, MyPrefab, 0);
* ECS_PREFAB(world, MyPrefab, Position, Velocity, INSTANCEOF | MyBasePrefab);
*
* Prefabs can be used with ECS_ENTITY:
* ECS_ENTITY(world, MyEntity, Position, Velocity, INSTANCEOF | MyPrefab);
*/
#define ECS_PREFAB(world, id, ...) \
ecs_entity_t id = ecs_new_prefab(world, #id, #__VA_ARGS__);\
ECS_TYPE_VAR(id) = ecs_type_from_entity(world, id);\
(void)id;\
(void)ecs_type(id);\
/** Declare a component.
* This macro declares a new component with the provided type. The type must be
* a valid C type or typedef. A type must first be registered as a component
* before it can be added to entities.
*
* Example:
* ECS_COMPONENT(world, Position);
*
* Components can be used with ECS_ENTITY:
* ECS_ENTITY(world, MyEntity, Position);
*/
#define ECS_COMPONENT(world, id) \
ECS_ENTITY_VAR(id) = ecs_new_component(world, #id, sizeof(id));\
ECS_TYPE_VAR(id) = ecs_type_from_entity(world, ecs_entity(id));\
(void)ecs_entity(id);\
(void)ecs_type(id);\
/** Declare a tag.
* This macro declares a tag with the provided id. Tags are the similar to
* components in that they can be added to an entity, but have no C type
* associated with them.
*
* Example:
* ECS_TAG(world, MyTag);
*
* Components can be used with ECS_ENTITY:
* ECS_ENTITY(world, MyEntity, MyTag);
*/
#define ECS_TAG(world, id) \
ecs_entity_t id = ecs_new_component(world, #id, 0);\
ECS_TYPE_VAR(id) = ecs_type_from_entity(world, id);\
(void)id;\
(void)ecs_type(id);\
/** Declare a type.
* This macro declares a type with the provided id and components. Types are
* similar to components in that they can be added to an entity, but instead of
* adding just one component, a type can add multiple components at once.
*
* The components are specified as a comma-separated list of identifiers,
* optionally with type flags.
*
* Examples:
* ECS_ENTITY(world, MyType, Position, Velocity);
* ECS_ENTITY(world, MyType 0);
* ECS_ENTITY(world, MyType, Position, Velocity, CHILDOF | MyParentEntity);
*
* Types can be used in combination with ECS_ENTITY like this:
*
* ECS_ENTITY(world, MyEntity, Position, MyType);
*/
#define ECS_TYPE(world, id, ...) \
ecs_entity_t id = ecs_new_type(world, #id, #__VA_ARGS__);\
ECS_TYPE_VAR(id) = ecs_type_from_entity(world, id);\
(void)id;\
(void)ecs_type(id);\
/** Declare a systen.
* This macro declares a system with the specified function, kind and signature.
* Systems are matched with entities that match the system signature. The system
* signature is specified as a comma-separated list of column expressions, where
* a column expression can be any of the following:
*
* - A simple component identifier ('Position')
* - An OR expression ('Position | Velocity')
* - An optional expression ('?Position')
* - A NOT expression ('!Position')
* - An OWNED expression ('OWNED.Position')
* - A SHARED expression ('SHARED.Position')
* - A CONTAINER expression ('CONTAINER.Position')
* - A CASCADE expression ('CASCADE.Position')
* - An entity expression ('MyEntity.Position')
* - An empty expression ('.Position')
*
* The systen kind specifies the phase in which the system is ran.
*
* Examples:
* ECS_SYSTEM(world, Move, EcsOnUpdate, Position, Velocity, !AngularVelocity);
* ECS_SYSTEM(world, Transform, EcsPostUpdate, CONTAINER.Transform, Transform);
*
* In these examples, 'Move' and 'Transform' must be valid identifiers to a C
* function of the following signature:
*
* void Move(ecs_rows_t *rows) { ... }
*
* Inside this function the system can access the data from the signature with
* the ECS_COLUMN macro:
*
* ECS_COLUMN(rows, Position, p, 1);
* ECS_COLUMN(rows, Velocity, v, 2);
*
* For more details on system signatures and phases see the Flecs manual.
*/
#define ECS_SYSTEM(world, id, kind, ...) \
ecs_entity_t F##id = ecs_new_system(world, #id, kind, #__VA_ARGS__, id);\
ecs_entity_t id = F##id;\
ECS_TYPE_VAR(id) = ecs_type_from_entity(world, id);\
(void)id;\
(void)ecs_type(id);
#endif
////////////////////////////////////////////////////////////////////////////////
//// World API
////////////////////////////////////////////////////////////////////////////////
/** Create a new world.
* A world manages all the ECS objects. Applications must have at least one
* world. Entities, component and system handles are local to a world and
* cannot be shared between worlds.
*
* @return A new world object
*/
FLECS_EXPORT
ecs_world_t* ecs_init(void);
/** Create a new world with arguments.
* Same as ecs_init, but allows passing in command line arguments. These can be
* used to dynamically enable flecs features to an application, like performance
* monitoring or the web dashboard (if it is installed) without having to modify
* the code of an application.
*
* If the functionality requested by the arguments is not available, an error
* message will be printed to stderr, but the function will not fail. Thus it is
* important that the application code does not rely on any functionality that
* is realized through the arguments.
*
* If the arguments specify a setting that is explicity set as well by the
* application, the application setting will be ignored. For example, if an
* application specifies it will run on 2 threads, but an argument specify it
* will run on 6 threads, the argument will take precedence.
*
* The following options are available:
* --threads [n] Use n worker threads
* --fps [hz] Run at hz FPS
* --admin [port] Enable admin dashboard (requires flecs-systems-admin & flecs-systems-civetweb)
* --console Enables console (requires flecs-systems-console)
* --debug Enables debug tracing
*
* @return A new world object
*/
FLECS_EXPORT
ecs_world_t* ecs_init_w_args(
int argc,
char *argv[]);
/** Delete a world.
* This operation deletes the world, and all entities, components and systems
* within the world.
*
* @param world The world to delete.
*/
FLECS_EXPORT
int ecs_fini(
ecs_world_t *world);
/** Signal exit
* This operation signals that the application should quit. It will cause
* ecs_progress to return false.
*
* @param world The world to quit.
*/
FLECS_EXPORT
void ecs_quit(
ecs_world_t *world);
/** Progress a world.
* This operation progresses the world by running all systems that are both
* enabled and periodic on their matching entities.
*
* An application can pass a delta_time into the function, which is the time
* passed since the last frame. This value is passed to systems so they can
* update entity values proportional to the elapsed time since their last
* invocation.
*
* When an application passes 0 to delta_time, ecs_progress will automatically
* measure the time passed since the last frame. If an application does not uses
* time management, it should pass a non-zero value for delta_time (1.0 is
* recommended). That way, no time will be wasted measuring the time.
*
* @param world The world to progress.
* @param delta_time The time passed since the last frame.
*/
FLECS_EXPORT
bool ecs_progress(
ecs_world_t *world,
float delta_time);
/** Set target frames per second (FPS) for application.
* Setting the target FPS ensures that ecs_progress is not invoked faster than
* the specified FPS. When enabled, ecs_progress tracks the time passed since
* the last invocation, and sleeps the remaining time of the frame (if any).
*
* This feature ensures systems are ran at a consistent interval, as well as
* conserving CPU time by not running systems more often than required.
*
* Note that ecs_progress only sleeps if there is time left in the frame. Both
* time spent in flecs as time spent outside of flecs are taken into
* account.
*
* @param world The world.
* @param fps The target FPS.
*/
FLECS_EXPORT
void ecs_set_target_fps(
ecs_world_t *world,
float fps);
/** Get configured target frames per second.
* This operation returns the FPS set with ecs_set_target_fps.
*
* @param world The world.
* @param return The current target FPS.
*/
FLECS_EXPORT
uint32_t ecs_get_target_fps(
ecs_world_t *world);
/** Get last delta time from world.
* This operation returns the delta_time used in the last frame. If a non-zero
* value was provided to ecs_progress then this value is returned, otherwise the
* time measured by ecs_progress is returned.
*
* @param world The world.
* @return The last used delta_time.
*/
FLECS_EXPORT
float ecs_get_delta_time(
ecs_world_t *world);
/** Set a world context.
* This operation allows an application to register custom data with a world
* that can be accessed anywhere where the application has the world object.
*
* A typical usecase is to register a struct with handles to the application
* entities, components and systems.
*
* @param world The world.
* @param ctx A pointer to a user defined structure.
*/
FLECS_EXPORT
void ecs_set_context(
ecs_world_t *world,
void *ctx);
/** Get the world context.
* This operation retrieves a previously set world context.
*
* @param world The world.
* @return The context set with ecs_set_context. If no context was set, the
* function returns NULL.
*/
FLECS_EXPORT
void* ecs_get_context(
ecs_world_t *world);
/** Get the world tick.
* This operation retrieves the tick count (frame number). The tick count is 0
* when ecs_process is called for the first time, and increases by one for every
* subsequent call.
*
* @param world The world.
* @return The current tick.
*/
FLECS_EXPORT
uint32_t ecs_get_tick(
ecs_world_t *world);
/** Dimension the world for a specified number of entities.
* This operation will preallocate memory in the world for the specified number
* of entities. Specifying a number lower than the current number of entities in
* the world will have no effect.
*
* When using this operation, note that flecs uses entities for storing
* systems, components and builtin components. For an exact calculation of
* entities, do user_entity_count + component_count + system_count + 3. The 3
* stands for the number of builtin components.
*
* Note that this operation does not allocate memory in tables. To preallocate
* memory in a table, use ecs_dim_type. Correctly using these functions
* prevents flecs from doing dynamic memory allocations in the main loop.
*
* @param world The world.
* @param entity_count The number of entities to preallocate.
*/
FLECS_EXPORT
void ecs_dim(
ecs_world_t *world,
uint32_t entity_count);
/** Dimension a type for a specified number of entities.
* This operation will preallocate memory for a type (table) for the
* specified number of entites. Specifying a number lower than the current
* number of entities in the table will have no effect.
*
* If no table exists yet for this type (when no entities have been committed
* for the type) it will be created, even if the entity_count is zero. This
* operation can thus also be used to just preallocate empty tables.
*
* If the specified type is unknown, the behavior of this function is
* unspecified. To ensure that the type exists, use ecs_type_get or
* ECS_TYPE.
*
* @param world The world.
* @param type Handle to the type, as obtained by ecs_type_get.
* @param entity_count The number of entities to preallocate.
*/
FLECS_EXPORT
void _ecs_dim_type(
ecs_world_t *world,
ecs_type_t type,
uint32_t entity_count);
#define ecs_dim_type(world, type, entity_count)\
_ecs_dim_type(world, T##type, entity_count)
/** Set a range for issueing new entity ids.
* This function constrains the entity identifiers returned by ecs_new to the
* specified range. This operation can be used to ensure that multiple processes
* can run in the same simulation without requiring a central service that
* coordinates issueing identifiers.
*
* If id_end is set to 0, the range is infinite. If id_end is set to a non-zero
* value, it has to be larger than id_start. If id_end is set and ecs_new is
* invoked after an id is issued that is equal to id_end, the application will
* abort. Flecs does not automatically recycle ids.
*
* The id_end parameter has to be smaller than the last issued identifier.
*
* @param world The world.
* @param id_start The start of the range.
* @param id_end The end of the range.
*/
FLECS_EXPORT
void ecs_set_entity_range(
ecs_world_t *world,
ecs_entity_t id_start,
ecs_entity_t id_end);
/** Temporarily enable/disable range limits.
* When an application is both a receiver of range-limited entities and a
* producer of range-limited entities, range checking needs to be temporarily
* disabled when receiving entities.
*
* Range checking is disabled on a stage, so setting this value is thread safe.
*/
FLECS_EXPORT
bool ecs_enable_range_check(
ecs_world_t *world,
bool enable);
////////////////////////////////////////////////////////////////////////////////
//// Entity API
////////////////////////////////////////////////////////////////////////////////
/** Create a new entity.
* Entities are light-weight objects that represent "things" in the application.
* Entities themselves do not have any state or logic, but instead are composed
* out of a set of zero or more stateful components.
*
* Entities can be assigned a type at creation time, which specifies zero or
* more components that the entity will be created with. Applications can either
* specify single components (created with ECS_COMPONENT) or types (created with
* ECS_TYPE) to this function.
*
* @param world The world to which to add the entity.
* @param type Zero if no type, or handle to a component, type or prefab.
* @return A handle to the new entity.
*/
FLECS_EXPORT
ecs_entity_t _ecs_new(
ecs_world_t *world,
ecs_type_t type);
#define ecs_new(world, type)\
_ecs_new(world, T##type)
/** Create new entities in a batch.
* This operation creates the number of specified entities with one API call
* which is a more efficient alternative to repeatedly calling ecs_new.
*
* The created entity identifiers will always be a contiguous list of integers.
*
* @param world The world.
* @param type Zero if no type, or handle to a component, type or prefab.
* @param count The number of entities to create.
* @return The first created entity.
*/
FLECS_EXPORT
ecs_entity_t _ecs_new_w_count(
ecs_world_t *world,
ecs_type_t type,
uint32_t count);
#define ecs_new_w_count(world, type, count)\
_ecs_new_w_count(world, T##type, count)
typedef void* ecs_table_columns_t;
typedef struct ecs_table_data_t {
uint32_t row_count;
uint32_t column_count;
ecs_entity_t *entities;
ecs_entity_t *components;
ecs_table_columns_t *columns;
} ecs_table_data_t;
/** Insert data in bulk.
* This operation allows applications to insert data in bulk by providing the
* entity and component data as arrays. The data is passed in using the
* ecs_table_data_t type, which has to be populated with the data that has to be
* inserted.
*
* The application must at least provide the row_count, column_count and
* components fields. The latter is an array of component identifiers that
* identifies the components to be added to the entitiy.
*
* The entities array must be populated with the entity identifiers to set. If
* this field is left NULL, Flecs will create row_count new entities.
*
* The component data must be provided in the columns field. This is an array of
* component arrays. The component arrays must be provided in the same order as
* the components have been provided in the components array. For example, if
* the components array is set to {ecs_entity(Position), ecs_entity(Velocity)},
* the columns must first specify the Position, and then the Velocity array. If
* no component data is provided, the components will be left uninitialized.
*
* Both the entities array and the component data arrays in columns must contain
* exactly row_count elements. The columns array must contain exactly
* column_count elements.
*
* The operation allows for efficient insertion of data for the same set of
* entities, provided that the entities are specified in the same order for
* every invocation of this function. After executing this operation, entities
* will be ordered in the same order specified in the entities array.
*
* If entities already exist in another table, they will be deleted from that
* table and inserted into the new table.
*/
FLECS_EXPORT
ecs_entity_t ecs_set_w_data(
ecs_world_t *world,
ecs_table_data_t *data);
/** Create a new child entity.
* Child entities are equivalent to normal entities, but can additionally be
* created with a container entity. Container entities allow for the creation of
* entity hierarchies.
*
* This function is equivalent to calling ecs_new with a type that combines both
* the type specified in this function and the type id for the container.
*
* @param world The world.
* @param parent The container to which to add the child entity.
* @param type The type with which to create the child entity.
* @return The created entity.
*/
FLECS_EXPORT
ecs_entity_t _ecs_new_child(
ecs_world_t *world,
ecs_entity_t parent,
ecs_type_t type);
#define ecs_new_child(world, parent, type)\
_ecs_new_child(world, parent, T##type)
/* Create new child entities in batch.
* This operation is similar to ecs_new_w_count, with as only difference that
* the parent is added to the type of the new entities.
*
* @param world The world.
* @param parent The parent.
* @param type The type to create the new entities with.
* @param count The number of entities to create.
* @return The first created entity.
*/
FLECS_EXPORT
ecs_entity_t _ecs_new_child_w_count(
ecs_world_t *world,
ecs_entity_t parent,
ecs_type_t type,
uint32_t count);
#define ecs_new_child_w_count(world, parent, type, count)\
_ecs_new_child_w_count(world, parent, T##type, count)
/** Instantiate entity from a base entity.
* This operation returns a new entity that shares components with the provided
* base entity.
*
* @param world The world.
* @param base The base entity.
* @return The created entity.
*/
FLECS_EXPORT
ecs_entity_t _ecs_new_instance(
ecs_world_t *world,
ecs_entity_t base,
ecs_type_t type);
#define ecs_new_instance(world, base, type)\
_ecs_new_instance(world, base, T##type)
/** Instantiate entities from a base entity in batch.
* This operation returns a specified number of new entities that share
* components with the provided base entity.
*
* @param world The world.
* @param base The base entity.
* @param count The number of entities to create.
* @return The first created entity.
*/
FLECS_EXPORT
ecs_entity_t _ecs_new_instance_w_count(
ecs_world_t *world,
ecs_entity_t base,
ecs_type_t type,
uint32_t count);
#define ecs_new_instance_w_count(world, base, type, count)\
_ecs_new_instance_w_count(world, base, T##type, count)
/** Create new entity with same components as specified entity.
* This operation creates a new entity which has the same components as the
* specified entity. This includes prefabs and entity-components (entities to
* which the EcsComponent component has been added manually).
*
* The application can optionally copy the values of the specified entity by
* passing true to copy_value. In that case, the resulting entity will have the
* same value as source specified entity.
*
* @param world The world.
* @param entity The source entity.
* @param copy_value Whether to copy the value from the source entity.
* @return The new entity.
*/
FLECS_EXPORT
ecs_entity_t ecs_clone(
ecs_world_t *world,
ecs_entity_t entity,
bool copy_value);
/** Delete components of an entity.
* This operation will delete all components from the specified entity.
*
* When the delete operation is invoked upon an already deleted entity, the
* operation will have no effect, as it will attempt to delete components from
* an already empty entity.
*
* As a result of a delete operation, EcsOnRemove systems will be invoked if
* applicable for any of the removed components.
*
* @param world The world.
* @param entity The entity to empty.
*/
FLECS_EXPORT
void ecs_delete(
ecs_world_t *world,
ecs_entity_t entity);
/** Delete all entities containing a (set of) component(s).
* This operation provides a more efficient alternative to deleting entities one
* by one by deleting an entire table or set of tables in a single operation.
* The operation will clear all tables that match the specified table.
*
* As a result of a delete operation, EcsOnRemove systems will be invoked if
* applicable for any of the removed components.
*
* @param world The world.
* @param filter Filter that matches zero or more tables.
*/
FLECS_EXPORT
void ecs_delete_w_filter(
ecs_world_t *world,
const ecs_filter_t *filter);
/** Add a type to an entity.
* This operation will add one or more components (as per the specified type) to
* an entity. If the entity already contains a subset of the components in the
* type, only components that are not contained by the entity will be added. If
* the entity already contains all components, this operation has no effect.
*
* As a result of an add operation, EcsOnAdd systems will be invoked if
* applicable for any of the added components.
*
* @param world The world.
* @param entity The entity to which to add the type.
* @param type The type to add to the entity.
*/
FLECS_EXPORT
void _ecs_add(
ecs_world_t *world,
ecs_entity_t entity,
ecs_type_t type);
#define ecs_add(world, entity, type)\
_ecs_add(world, entity, T##type)
/** Add single entity to entity */
FLECS_EXPORT
void ecs_add_entity(
ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t to_add);
/** Remove a type from an entity.
* This operation will remove one or more components (as per the specified type)
* from an entity. If the entity contained a subset of the components in the
* type, only that subset will be removed. If the entity contains none of the
* components in the type, the operation has no effect.
*
* As a result of a remove operation, EcsOnRemove systems will be invoked if
* applicable for any of the removed components.
*
* @param world The world.
* @param entity The entity from which to remove the type.
* @param type The type to remove from the entity.
*/
FLECS_EXPORT
void _ecs_remove(
ecs_world_t *world,
ecs_entity_t entity,
ecs_type_t type);
#define ecs_remove(world, entity, type)\
_ecs_remove(world, entity, T##type)
/** Add single entity to entity */
FLECS_EXPORT
void ecs_remove_entity(
ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t to_remove);
/** Add and remove types from an entity.
* This operation is a combination of ecs_add and ecs_remove. The operation
* behaves as if the specified to_remove type is removed first, and
* subsequently the to_add type is added. This operation is more efficient than
* adding/removing components separately with ecs_add/ecs_remove, as the entity
* is moved between tables at most once.
*
* @param world The world.
* @param entity The entity from which to remove, and to which to add the types.
* @param to_add The type to add to the entity.
* @param to_remove The type to remove from the entity.
*/
FLECS_EXPORT
void _ecs_add_remove(
ecs_world_t *world,
ecs_entity_t entity,
ecs_type_t to_add,
ecs_type_t to_remove);
#define ecs_add_remove(world, entity, to_add, to_remove)\
_ecs_add_remove(world, entity, T##to_add, T##to_remove)
/** Adopt a child entity by a parent.
* This operation adds the specified parent entity to the type of the specified
* entity, which effectively establishes a parent-child relationship. The parent
* entity, when added, behaves like a normal component in that it becomes part
* of the entity type.
*
* If the parent was already added to the entity, this operation will have no
* effect.
*
* This operation is similar to an ecs_add, with as difference that instead of a
* type it accepts any entity handle.
*
* @param world The world.
* @param entity The entity to adopt.
* @param parent The parent entity to add to the entity.
*/
FLECS_EXPORT
void ecs_adopt(
ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t parent);
/** Orphan a child by a parent.
* This operation removes the specified parent entity from the type of the
* specified entity. If the parent was not added to the entity, this operation
* has no effect.
*
* This operation is similar to ecs_remove, with as difference that instead of a
* type it accepts any entity handle.
*
* @param world The world.
* @param entity The entity to orphan.
* @param parent The parent entity to remove from the entity.
*/
FLECS_EXPORT
void ecs_orphan(
ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t parent);
/** Inherit from a base.
* This operation adds a base to an entity, which will cause the entity to
* inherit the components of the base. If the entity already inherited from the
* specified base, this operation does nothing.
*
* @param world The world.
* @param entity The entity to add the base to.
* @param base The base to add to the entity.
*/
FLECS_EXPORT
void ecs_inherit(
ecs_world_t *world,
ecs_entity_t entity,
ecs_entity_t base);
/** Disinherit from a base.
* This operation removes a base from an entity, which will cause the entity to
* no longer inherit the components of the base. If the entity did not inherit
* from the specified base, this operation does nothing.
*
* @param world The world.
* @param entity The entity to remove the base from.