Skip to content
Flecs v4.1
system.h
Go to the documentation of this file.
1/**
2 * @file addons/system.h
3 * @brief System module.
4 *
5 * The system module allows for creating and running systems. A system is a
6 * query in combination with a callback function. In addition, systems have
7 * support for time management and can be monitored by the stats addon.
8 */
9
10#ifdef FLECS_SYSTEM
11
12/**
13 * @defgroup c_addons_system System
14 * @ingroup c_addons
15 * Systems are a query + function that can be run manually or by a pipeline.
16 *
17 * @{
18 */
19
20#ifndef FLECS_MODULE
21#define FLECS_MODULE
22#endif
23
24#ifndef FLECS_SYSTEM_H
25#define FLECS_SYSTEM_H
26
27#ifdef __cplusplus
28extern "C" {
29#endif
30
31/** Component used to provide a tick source to systems. */
32typedef struct EcsTickSource {
33 bool tick; /**< True if providing a tick. */
34 ecs_ftime_t time_elapsed; /**< Time elapsed since the last tick. */
36
37/** Use with ecs_system_init() and ecs_system_update(). */
38typedef struct ecs_system_desc_t {
39 int32_t _canary; /**< Used for validity testing. Do not set. */
40
41 /** Existing entity to associate with the system (optional). */
43
44 /** System query parameters. */
46
47 /** Optional pipeline phase for the system to run in. When set, it will be
48 * added to the system both as a tag and as a (DependsOn, phase) pair. */
50
51 /** Callback that is run for each result returned by the system's query. This
52 * means that this callback can be invoked multiple times per system per
53 * frame, typically once for each matching table. */
55
56 /** Callback that is invoked when a system is run.
57 * When left to NULL, the default system runner is used, which calls the
58 * "callback" action for each result returned from the system's query.
59 *
60 * It should not be assumed that the input iterator can always be iterated
61 * with ecs_query_next(). When a system is multithreaded and/or paged, the
62 * iterator can be either a worker or a paged iterator. The correct function
63 * to use for iteration is ecs_iter_next().
64 *
65 * An implementation can test whether the iterator is a query iterator by
66 * testing whether the it->next value is equal to ecs_query_next(). */
68
69 /** Context to be passed to callback (as ecs_iter_t::param). */
70 void *ctx;
71
72 /** Callback to free ctx. */
74
75 /** Context associated with callback (for language bindings). */
77
78 /** Callback to free callback ctx. */
80
81 /** Context associated with run (for language bindings). */
82 void *run_ctx;
83
84 /** Callback to free run ctx. */
86
87 /** Interval in seconds at which the system should run. */
89
90 /** Rate at which the system should run. */
91 int32_t rate;
92
93 /** External tick source that determines when the system ticks. */
95
96 /** If true, the system will be run on multiple threads. */
98
99 /** If true, the system will have access to the actual world. Cannot be true at the
100 * same time as multi_threaded. */
103
104/** Create a system.
105 * If the descriptor specifies an existing entity, the entity must not already
106 * be associated with a system. To modify an existing system, use
107 * ecs_system_update().
108 *
109 * @param world The world.
110 * @param desc The system descriptor.
111 * @return The system entity.
112 */
113FLECS_API
115 ecs_world_t *world,
116 const ecs_system_desc_t *desc);
117
118/** Update an existing system.
119 * Updates the configuration of a system that was previously created with
120 * ecs_system_init(). Only fields in desc that are set to a non-default value
121 * will be applied; fields left at their default value preserve the existing
122 * configuration of the system.
123 *
124 * The query field of the descriptor is not used by this function; the system
125 * query cannot be modified after creation.
126 *
127 * @param world The world.
128 * @param system The system to update.
129 * @param desc The system descriptor.
130 * @return The system entity, or 0 if the operation failed.
131 */
132FLECS_API
134 ecs_world_t *world,
135 ecs_entity_t system,
136 const ecs_system_desc_t *desc);
137
138/** System type, get with ecs_system_get(). */
139typedef struct ecs_system_t {
140 ecs_header_t hdr; /**< Object header. */
141
142 /** See ecs_system_desc_t. */
144
145 /** See ecs_system_desc_t. */
147
148 /** System query. */
150
151 /** Query group to iterate. */
152 uint64_t group_id;
153
154 /** True if a query group is configured. */
156
157 /** Tick source associated with the system. */
159
160 /** Whether the system is multithreaded. */
162
163 /** Whether the system is run in immediate mode. */
165
166 /** Cached system name (for perf tracing). */
167 const char *name;
168
169 /** Userdata for the system. */
170 void *ctx;
171
172 /** Callback language binding context. */
174
175 /** Run language binding context. */
176 void *run_ctx;
177
178 /** Callback to free ctx. */
180
181 /** Callback to free callback ctx. */
183
184 /** Callback to free run ctx. */
186
187 /** Time spent on running the system. */
189
190 /** Time passed since the last invocation. */
192
193 /** Last frame for which the system was considered. */
194 int64_t last_frame;
195
196 /** Mixin destructor. */
199
200/** Get a system object.
201 * Return the system object. Can be used to access various information about
202 * the system, like the query and context.
203 *
204 * @param world The world.
205 * @param system The system.
206 * @return The system object.
207 */
208FLECS_API
210 const ecs_world_t *world,
211 ecs_entity_t system);
212
213/** Set query group for system.
214 * This operation configures a system created with a grouped query to only
215 * iterate results for the specified group ID. The group filter is applied to
216 * both manual runs and pipeline execution.
217 *
218 * @param world The world.
219 * @param system The system.
220 * @param group_id The query group ID to iterate.
221 */
222FLECS_API
224 ecs_world_t *world,
225 ecs_entity_t system,
226 uint64_t group_id);
227
228#ifndef FLECS_LEGACY
229
230/** Forward declare a system. */
231#define ECS_SYSTEM_DECLARE(id) ecs_entity_t ecs_id(id)
232
233/** Define a forward-declared system.
234 *
235 * Example:
236 *
237 * @code
238 * ECS_SYSTEM_DEFINE(world, Move, EcsOnUpdate, Position, Velocity);
239 * @endcode
240 */
241#define ECS_SYSTEM_DEFINE(world, id_, phase_, ...) \
242 { \
243 ecs_system_desc_t desc = {0}; \
244 ecs_entity_desc_t edesc = {0}; \
245 edesc.id = ecs_id(id_);\
246 edesc.name = #id_;\
247 desc.entity = ecs_entity_init(world, &edesc);\
248 desc.query.expr = #__VA_ARGS__; \
249 desc.phase = phase_; \
250 desc.callback = id_; \
251 ecs_id(id_) = ecs_system_init(world, &desc); \
252 } \
253 ecs_assert(ecs_id(id_) != 0, ECS_INVALID_PARAMETER, "failed to create system %s", #id_)
254
255/** Declare and define a system.
256 *
257 * Example:
258 *
259 * @code
260 * ECS_SYSTEM(world, Move, EcsOnUpdate, Position, Velocity);
261 * @endcode
262 */
263#define ECS_SYSTEM(world, id, phase, ...) \
264 ecs_entity_t ecs_id(id) = 0; ECS_SYSTEM_DEFINE(world, id, phase, __VA_ARGS__);\
265 ecs_entity_t id = ecs_id(id);\
266 (void)ecs_id(id);\
267 (void)id
268
269/** Shorthand for creating a system with ecs_system_init().
270 *
271 * Example:
272 *
273 * @code
274 * ecs_system(world, {
275 * .entity = ecs_entity(world, { .name = "MyEntity" }),
276 * .phase = EcsOnUpdate,
277 * .query.terms = {
278 * { ecs_id(Position) },
279 * { ecs_id(Velocity) }
280 * },
281 * .callback = Move
282 * });
283 * @endcode
284 */
285#define ecs_system(world, ...)\
286 ecs_system_init(world, &(ecs_system_desc_t) __VA_ARGS__ )
287
288#endif
289
290/** Run a specific system manually.
291 * This operation runs a single system manually. It is an efficient way to
292 * invoke logic on a set of entities, as manual systems are only matched to
293 * tables at creation time or after creation time, when a new table is created.
294 *
295 * Manual systems are useful to evaluate lists of pre-matched entities at
296 * application-defined times. Because none of the matching logic is evaluated
297 * before the system is invoked, manual systems are much more efficient than
298 * manually obtaining a list of entities and retrieving their components.
299 *
300 * An application may pass custom data to a system through the param parameter.
301 * This data can be accessed by the system through the param member in the
302 * ecs_iter_t value that is passed to the system callback.
303 *
304 * Any system may interrupt execution by setting the interrupted_by member in
305 * the ecs_iter_t value. This is particularly useful for manual systems, where
306 * the value of interrupted_by is returned by this operation. This, in
307 * combination with the param argument, lets applications use manual systems
308 * to lookup entities: once the entity has been found, its handle is passed to
309 * interrupted_by, which is then subsequently returned.
310 *
311 * @param world The world.
312 * @param system The system to run.
313 * @param delta_time The time passed since the last system invocation.
314 * @param param A user-defined parameter to pass to the system.
315 * @return Handle to the last evaluated entity if the system was interrupted.
316 */
317FLECS_API
319 ecs_world_t *world,
320 ecs_entity_t system,
321 ecs_ftime_t delta_time,
322 void *param);
323
324/** Same as ecs_run(), but subdivides entities across a number of provided stages.
325 *
326 * @param world The world.
327 * @param system The system to run.
328 * @param stage_current The ID of the current stage.
329 * @param stage_count The total number of stages.
330 * @param delta_time The time passed since the last system invocation.
331 * @param param A user-defined parameter to pass to the system.
332 * @return Handle to the last evaluated entity if the system was interrupted.
333 */
334FLECS_API
336 ecs_world_t *world,
337 ecs_entity_t system,
338 int32_t stage_current,
339 int32_t stage_count,
340 ecs_ftime_t delta_time,
341 void *param);
342
343/** System module import function.
344 * Usage:
345 * @code
346 * ECS_IMPORT(world, FlecsSystem)
347 * @endcode
348 *
349 * @param world The world.
350 */
351FLECS_API
353 ecs_world_t *world);
354
355#ifdef __cplusplus
356}
357#endif
358
359#endif
360
361/** @} */
362
363#endif
FLECS_API const ecs_system_t * ecs_system_get(const ecs_world_t *world, ecs_entity_t system)
Get a system object.
FLECS_API void FlecsSystemImport(ecs_world_t *world)
System module import function.
FLECS_API ecs_entity_t ecs_run(ecs_world_t *world, ecs_entity_t system, ecs_ftime_t delta_time, void *param)
Run a specific system manually.
FLECS_API ecs_entity_t ecs_system_init(ecs_world_t *world, const ecs_system_desc_t *desc)
Create a system.
FLECS_API void ecs_system_set_group(ecs_world_t *world, ecs_entity_t system, uint64_t group_id)
Set query group for system.
FLECS_API ecs_entity_t ecs_system_update(ecs_world_t *world, ecs_entity_t system, const ecs_system_desc_t *desc)
Update an existing system.
FLECS_API ecs_entity_t ecs_run_worker(ecs_world_t *world, ecs_entity_t system, int32_t stage_current, int32_t stage_count, ecs_ftime_t delta_time, void *param)
Same as ecs_run(), but subdivides entities across a number of provided stages.
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
void(*) ecs_ctx_free_t(void *ctx)
Function to clean up context data.
Definition flecs.h:660
void(*) ecs_iter_action_t(ecs_iter_t *it)
Function prototype for iterables.
Definition flecs.h:591
void(*) ecs_run_action_t(ecs_iter_t *it)
Function prototype for runnables (systems, observers).
Definition flecs.h:582
void(*) flecs_poly_dtor_t(ecs_poly_t *poly)
Destructor function for poly objects.
Definition flecs.h:713
#define ecs_ftime_t
Customizable precision for scalar time values.
Definition flecs.h:59
Component used to provide a tick source to systems.
Definition system.h:32
ecs_ftime_t time_elapsed
Time elapsed since the last tick.
Definition system.h:34
bool tick
True if providing a tick.
Definition system.h:33
Header for ecs_poly_t objects.
Definition flecs.h:534
Used with ecs_query_init().
Definition flecs.h:1325
Queries are lists of constraints (terms) that match entities.
Definition flecs.h:858
Use with ecs_system_init() and ecs_system_update().
Definition system.h:38
int32_t rate
Rate at which the system should run.
Definition system.h:91
void * ctx
Context to be passed to callback (as ecs_iter_t::param).
Definition system.h:70
ecs_ctx_free_t run_ctx_free
Callback to free run ctx.
Definition system.h:85
ecs_ctx_free_t ctx_free
Callback to free ctx.
Definition system.h:73
ecs_entity_t phase
Optional pipeline phase for the system to run in.
Definition system.h:49
bool multi_threaded
If true, the system will be run on multiple threads.
Definition system.h:97
bool immediate
If true, the system will have access to the actual world.
Definition system.h:101
void * callback_ctx
Context associated with callback (for language bindings).
Definition system.h:76
void * run_ctx
Context associated with run (for language bindings).
Definition system.h:82
ecs_ftime_t interval
Interval in seconds at which the system should run.
Definition system.h:88
int32_t _canary
Used for validity testing.
Definition system.h:39
ecs_iter_action_t callback
Callback that is run for each result returned by the system's query.
Definition system.h:54
ecs_entity_t entity
Existing entity to associate with the system (optional).
Definition system.h:42
ecs_query_desc_t query
System query parameters.
Definition system.h:45
ecs_ctx_free_t callback_ctx_free
Callback to free callback ctx.
Definition system.h:79
ecs_run_action_t run
Callback that is invoked when a system is run.
Definition system.h:67
ecs_entity_t tick_source
External tick source that determines when the system ticks.
Definition system.h:94
System type, get with ecs_system_get().
Definition system.h:139
ecs_iter_action_t action
See ecs_system_desc_t.
Definition system.h:146
ecs_query_t * query
System query.
Definition system.h:149
bool group_id_set
True if a query group is configured.
Definition system.h:155
ecs_header_t hdr
Object header.
Definition system.h:140
ecs_ctx_free_t ctx_free
Callback to free ctx.
Definition system.h:179
void * run_ctx
Run language binding context.
Definition system.h:176
ecs_run_action_t run
See ecs_system_desc_t.
Definition system.h:143
ecs_ftime_t time_passed
Time passed since the last invocation.
Definition system.h:191
int64_t last_frame
Last frame for which the system was considered.
Definition system.h:194
ecs_ftime_t time_spent
Time spent on running the system.
Definition system.h:188
const char * name
Cached system name (for perf tracing).
Definition system.h:167
ecs_ctx_free_t run_ctx_free
Callback to free run ctx.
Definition system.h:185
bool immediate
Whether the system is run in immediate mode.
Definition system.h:164
bool multi_threaded
Whether the system is multithreaded.
Definition system.h:161
void * ctx
Userdata for the system.
Definition system.h:170
ecs_ctx_free_t callback_ctx_free
Callback to free callback ctx.
Definition system.h:182
uint64_t group_id
Query group to iterate.
Definition system.h:152
ecs_entity_t tick_source
Tick source associated with the system.
Definition system.h:158
flecs_poly_dtor_t dtor
Mixin destructor.
Definition system.h:197
void * callback_ctx
Callback language binding context.
Definition system.h:173