Pico Headers
|
A pure and simple ECS written in C99. More...
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Go to the source code of this file.
Macros | |
#define | ECS_NULL ((ecs_id_t)-1) |
NULL/invalid/undefined value. | |
#define | ECS_DT_TYPE double |
Determine delta-time type. | |
Typedefs | |
typedef struct ecs_s | ecs_t |
ECS context. | |
typedef uint32_t | ecs_id_t |
ID used for entity and components. | |
typedef int8_t | ecs_ret_t |
Return code for update callback and calling functions. | |
typedef ECS_DT_TYPE | ecs_dt_t |
typedef void(* | ecs_constructor_fn) (ecs_t *ecs, ecs_id_t entity_id, void *ptr, void *args) |
Called when a component is created (via ecs_add) | |
typedef void(* | ecs_destructor_fn) (ecs_t *ecs, ecs_id_t entity_id, void *ptr) |
Called when a component is destroyed (via ecs_remove or ecs_destroy) | |
typedef ecs_ret_t(* | ecs_system_fn) (ecs_t *ecs, ecs_id_t *entities, int entity_count, ecs_dt_t dt, void *udata) |
System update callback. | |
typedef void(* | ecs_added_fn) (ecs_t *ecs, ecs_id_t entity_id, void *udata) |
Called when an entity is added to a system. | |
typedef void(* | ecs_removed_fn) (ecs_t *ecs, ecs_id_t entity_id, void *udata) |
Called when an entity is removed from a system. | |
Functions | |
ecs_t * | ecs_new (size_t entity_count, void *mem_ctx) |
Creates an ECS instance. | |
void | ecs_free (ecs_t *ecs) |
Destroys an ECS instance. | |
void | ecs_reset (ecs_t *ecs) |
Removes all entities from the ECS, preserving systems and components. | |
ecs_id_t | ecs_register_component (ecs_t *ecs, size_t size, ecs_constructor_fn constructor, ecs_destructor_fn destructor) |
Registers a component. | |
ecs_id_t | ecs_register_system (ecs_t *ecs, ecs_system_fn system_cb, ecs_added_fn add_cb, ecs_removed_fn remove_cb, void *udata) |
Registers a system. | |
void | ecs_require_component (ecs_t *ecs, ecs_id_t sys_id, ecs_id_t comp_id) |
Determines which components are available to the specified system. | |
void | ecs_exclude_component (ecs_t *ecs, ecs_id_t sys_id, ecs_id_t comp_id) |
Excludes entities having the specified component from being added to the target system. | |
void | ecs_enable_system (ecs_t *ecs, ecs_id_t sys_id) |
Enables a system. | |
void | ecs_disable_system (ecs_t *ecs, ecs_id_t sys_id) |
Disables a system. | |
ecs_id_t | ecs_create (ecs_t *ecs) |
Creates an entity. | |
bool | ecs_is_ready (ecs_t *ecs, ecs_id_t entity_id) |
Returns true if the entity is currently active. | |
void | ecs_destroy (ecs_t *ecs, ecs_id_t entity_id) |
Destroys an entity. | |
bool | ecs_has (ecs_t *ecs, ecs_id_t entity_id, ecs_id_t comp_id) |
Test if entity has the specified component. | |
void * | ecs_add (ecs_t *ecs, ecs_id_t entity_id, ecs_id_t comp_id, void *args) |
Adds a component instance to an entity. | |
void * | ecs_get (ecs_t *ecs, ecs_id_t entity_id, ecs_id_t comp_id) |
Gets a component instance associated with an entity. | |
void | ecs_remove (ecs_t *ecs, ecs_id_t entity_id, ecs_id_t comp_id) |
Removes a component instance from an entity. | |
void | ecs_queue_destroy (ecs_t *ecs, ecs_id_t entity_id) |
Queues an entity for destruction at the end of system execution. | |
void | ecs_queue_remove (ecs_t *ecs, ecs_id_t entity_id, ecs_id_t comp_id) |
Queues a component for removable. | |
ecs_ret_t | ecs_update_system (ecs_t *ecs, ecs_id_t sys_id, ecs_dt_t dt) |
Update an individual system. | |
ecs_ret_t | ecs_update_systems (ecs_t *ecs, ecs_dt_t dt) |
Updates all systems. | |
A pure and simple ECS written in C99.
This library implements an ECS (Entity-Component-System). Entities (sometimes called game objects) are defined by their components. For example, an entity might have position, sprite, and physics components. Systems operate on the components of entities that match the system's requirements. Entities are matched to systems based upon which components they have and also the system's matching crieria.
In the above example, a sprite renderer system would match entities having poition and sprite components. The system would send the appropriate geometry and texture ID to the game's graphics API.
Traditional game engines tightly couple state with logic. For example, in C++ a game object typically has its own update method that operates on that state. They also usually rely heavily on inheritance.
If the state specified by the class changes this could ripple through the class, and perhaps subclasses as well. It could well be that the class no longer belongs in the existing class hierarchy forcing even more revisions. It could even be true that a class doesn't neatly fit into the inheritance tree at all.
An ECS solves these problems while also granting more flexibility in general. In an ECS there is a clear separation between data (components) and logic (systems), which makes it possible to build complex simulations with fewer assumptions about how that data will be used. In an ECS it effortless to change functionality, by either adding or removing components from entities, and/or by changing system requirements. Adding new logic is also simple as well, just register a new system!
Please see the examples and unit tests for more details.
To use this library in your project, add the following
#define PICO_ECS_IMPLEMENTATION #include "pico_ecs.h"
to a source file (once), then simply include the header normally.
Must be defined before PICO_ECS_IMPLEMENTATION
#define ECS_NULL ((ecs_id_t)-1) |
NULL/invalid/undefined value.
#define ECS_DT_TYPE double |
Determine delta-time type.
typedef struct ecs_s ecs_t |
ECS context.
typedef uint32_t ecs_id_t |
ID used for entity and components.
typedef int8_t ecs_ret_t |
Return code for update callback and calling functions.
typedef ECS_DT_TYPE ecs_dt_t |
Called when a component is created (via ecs_add)
ecs | The ECS instance |
entity_id | The entity being constructed |
ptr | The pointer to the component |
Called when a component is destroyed (via ecs_remove or ecs_destroy)
ecs | The ECS instance |
entity_id | The entity being destoryed |
ptr | The pointer to the component |
typedef ecs_ret_t(* ecs_system_fn) (ecs_t *ecs, ecs_id_t *entities, int entity_count, ecs_dt_t dt, void *udata) |
System update callback.
Systems implement the core logic of an ECS by manipulating entities and components.
ecs | The ECS instance |
entities | An array of entity IDs managed by the system |
entity_count | The number of entities in the array |
dt | The time delta |
udata | The user data associated with the system |
Called when an entity is added to a system.
ecs | The ECS instance |
entity_id | The enitty being added |
udata | The user data passed to the callback |
Called when an entity is removed from a system.
ecs | The ECS instance |
entity_id | The enitty being removed |
udata | The user data passed to the callback |
ecs_t * ecs_new | ( | size_t | entity_count, |
void * | mem_ctx | ||
) |
Creates an ECS instance.
entity_count | The inital number of pooled entities |
mem_ctx | The Context for a custom allocator |
void ecs_free | ( | ecs_t * | ecs | ) |
Destroys an ECS instance.
ecs | The ECS instance |
void ecs_reset | ( | ecs_t * | ecs | ) |
Removes all entities from the ECS, preserving systems and components.
ecs_id_t ecs_register_component | ( | ecs_t * | ecs, |
size_t | size, | ||
ecs_constructor_fn | constructor, | ||
ecs_destructor_fn | destructor | ||
) |
Registers a component.
Registers a component with the specfied size in bytes. Components define the game state (usually contained within structs) and are manipulated by systems.
ecs | The ECS instance |
size | The number of bytes to allocate for each component instance |
constructor | Called when a component is created (disabled if NULL) |
destructor | Called when a component is destroyed (disabled if NULL) |
udata | Data passed to callbacks (can be NULL) |
ecs_id_t ecs_register_system | ( | ecs_t * | ecs, |
ecs_system_fn | system_cb, | ||
ecs_added_fn | add_cb, | ||
ecs_removed_fn | remove_cb, | ||
void * | udata | ||
) |
Registers a system.
Registers a system with the specified parameters. Systems contain the core logic of a game by manipulating game state as defined by components.
ecs | The ECS instance |
system_cb | Callback that is fired every update |
add_cb | Called when an entity is added to the system (can be NULL) |
remove_cb | Called when an entity is removed from the system (can be NULL) |
udata | The user data passed to the callbacks |
Determines which components are available to the specified system.
ecs | The ECS instance |
sys_id | The target system ID |
comp_id | The component ID |
Excludes entities having the specified component from being added to the target system.
ecs | The ECS instance |
sys_id | The target system ID |
comp_id | The component ID tp exclude |
Enables a system.
ecs | The ECS instance |
sys_id | The specified system ID |
Disables a system.
ecs | The ECS instance |
sys_id | The specified system ID |
Creates an entity.
ecs | The ECS instance |
Returns true if the entity is currently active.
ecs | The ECS instance |
entity_id | The target entity |
Destroys an entity.
Destroys an entity, releasing resources and returning it to the pool.
ecs | The ECS instance |
entity_id | The ID of the entity to destroy |
Test if entity has the specified component.
ecs | The ECS instance |
entity_id | The entity ID |
comp_id | The component ID |
Adds a component instance to an entity.
ecs | The ECS instance |
entity_id | The entity ID |
comp_id | The component ID |
Gets a component instance associated with an entity.
ecs | The ECS instance |
entity_id | The entity ID |
comp_id | The component ID |
Removes a component instance from an entity.
ecs | The ECS instance |
entity_id | The entity ID |
comp_id | The component ID |
Queues an entity for destruction at the end of system execution.
Queued entities are destroyed after the curent iteration.
ecs | The ECS instance |
entity_id | The ID of the entity to destroy |
Queues a component for removable.
Queued entity/component pairs that will be deleted after the current system returns
ecs | The ECS instance |
entity_id | The ID of the entity that has the component |
comp_id | The component to remove |
Update an individual system.
This function should be called once per frame.
ecs | The ECS instance |
sys_id | The system to update |
dt | The time delta |