Files
PixelDefense/engine/libs/flecs/include/flecs/addons/pipeline.h

229 lines
6.9 KiB
C

/**
* @file addons/pipeline.h
* @brief Pipeline module.
*
* The pipeline module provides support for running systems automatically and
* on multiple threads. A pipeline is a collection of tags that can be added to
* systems. When ran, a pipeline will query for all systems that have the tags
* that belong to a pipeline, and run them.
*
* The module defines a number of builtin tags (EcsPreUpdate, EcsOnUpdate,
* EcsPostUpdate etc.) that are registered with the builtin pipeline. The
* builtin pipeline is ran by default when calling ecs_progress(). An
* application can set a custom pipeline with the ecs_set_pipeline function.
*/
#ifdef FLECS_PIPELINE
/**
* @defgroup c_addons_pipeline Pipeline
* @brief Pipelines order and schedule systems for execution.
*
* \ingroup c_addons
* @{
*/
#ifndef FLECS_MODULE
#define FLECS_MODULE
#endif
#ifndef FLECS_SYSTEM
#define FLECS_SYSTEM
#endif
#if !defined(FLECS_OS_API_IMPL) && !defined(FLECS_NO_OS_API_IMPL)
#define FLECS_OS_API_IMPL
#endif
#ifndef FLECS_PIPELINE_H
#define FLECS_PIPELINE_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FLECS_LEGACY
#define ECS_PIPELINE_DEFINE(world, id_, ...) \
{ \
ecs_pipeline_desc_t desc = {0}; \
ecs_entity_desc_t edesc = {0}; \
edesc.id = id_;\
edesc.name = #id_;\
desc.entity = ecs_entity_init(world, &edesc);\
desc.query.filter.expr = #__VA_ARGS__; \
id_ = ecs_pipeline_init(world, &desc); \
ecs_id(id_) = id_;\
} \
ecs_assert(id_ != 0, ECS_INVALID_PARAMETER, NULL);
#define ECS_PIPELINE(world, id, ...) \
ecs_entity_t id = 0, ecs_id(id) = 0; ECS_PIPELINE_DEFINE(world, id, __VA_ARGS__);\
(void)id;\
(void)ecs_id(id);
#define ecs_pipeline(world, ...)\
ecs_pipeline_init(world, &(ecs_pipeline_desc_t) __VA_ARGS__ )
#endif
/* Pipeline descriptor (used with ecs_pipeline_init) */
typedef struct ecs_pipeline_desc_t {
/* Existing entity to associate with pipeline (optional) */
ecs_entity_t entity;
/* Query descriptor. The first term of the query must match the EcsSystem
* component. */
ecs_query_desc_t query;
} ecs_pipeline_desc_t;
/** Create a custom pipeline.
*/
FLECS_API
ecs_entity_t ecs_pipeline_init(
ecs_world_t *world,
const ecs_pipeline_desc_t *desc);
/** Set a custom pipeline.
* This operation sets the pipeline to run when ecs_progress is invoked.
*
* @param world The world.
* @param pipeline The pipeline to set.
*/
FLECS_API
void ecs_set_pipeline(
ecs_world_t *world,
ecs_entity_t pipeline);
/** Get the current pipeline.
* This operation gets the current pipeline.
*
* @param world The world.
* @return The current pipeline.
*/
FLECS_API
ecs_entity_t ecs_get_pipeline(
const 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.
* @return false if ecs_quit has been called, true otherwise.
*/
FLECS_API
bool ecs_progress(
ecs_world_t *world,
ecs_ftime_t delta_time);
/** Set time scale.
* Increase or decrease simulation speed by the provided multiplier.
*
* @param world The world.
* @param scale The scale to apply (default = 1).
*/
FLECS_API
void ecs_set_time_scale(
ecs_world_t *world,
ecs_ftime_t scale);
/** Reset world clock.
* Reset the clock that keeps track of the total time passed in the simulation.
*
* @param world The world.
*/
FLECS_API
void ecs_reset_clock(
ecs_world_t *world);
/** Run pipeline.
* This will run all systems in the provided pipeline. This operation may be
* invoked from multiple threads, and only when staging is disabled, as the
* pipeline manages staging and, if necessary, synchronization between threads.
*
* If 0 is provided for the pipeline id, the default pipeline will be ran (this
* is either the builtin pipeline or the pipeline set with set_pipeline()).
*
* When using progress() this operation will be invoked automatically for the
* default pipeline (either the builtin pipeline or the pipeline set with
* set_pipeline()). An application may run additional pipelines.
*
* @param world The world.
* @param pipeline The pipeline to run.
*/
FLECS_API
void ecs_run_pipeline(
ecs_world_t *world,
ecs_entity_t pipeline,
ecs_ftime_t delta_time);
////////////////////////////////////////////////////////////////////////////////
//// Threading
////////////////////////////////////////////////////////////////////////////////
/** Set number of worker threads.
* Setting this value to a value higher than 1 will start as many threads and
* will cause systems to evenly distribute matched entities across threads. The
* operation may be called multiple times to reconfigure the number of threads
* used, but never while running a system / pipeline.
* Calling ecs_set_threads will also end the use of task threads setup with
* ecs_set_task_threads and vice-versa */
FLECS_API
void ecs_set_threads(
ecs_world_t *world,
int32_t threads);
/** Set number of worker task threads.
* ecs_set_task_threads is similar to ecs_set_threads, except threads are treated
* as short-lived tasks and will be created and joined around each update of the world.
* Creation and joining of these tasks will use the os_api_t tasks APIs rather than the
* the standard thread API functions, although they may be the same if desired.
* This function is useful for multithreading world updates using an external
* asynchronous job system rather than long running threads by providing the APIs
* to create tasks for your job system and then wait on their conclusion.
* The operation may be called multiple times to reconfigure the number of task threads
* used, but never while running a system / pipeline.
* Calling ecs_set_task_threads will also end the use of threads setup with
* ecs_set_threads and vice-versa */
FLECS_API
void ecs_set_task_threads(
ecs_world_t *world,
int32_t task_threads);
/** Returns true if task thread use have been requested. */
FLECS_API
bool ecs_using_task_threads(
ecs_world_t *world);
////////////////////////////////////////////////////////////////////////////////
//// Module
////////////////////////////////////////////////////////////////////////////////
FLECS_API
void FlecsPipelineImport(
ecs_world_t *world);
#ifdef __cplusplus
}
#endif
#endif
/** @} */
#endif