Flecs v4.0
A fast entity component system (ECS) for C & C++
|
Classes | |
struct | ecs_iter_t |
Iterator. More... | |
struct | ecs_query_desc_t |
Used with ecs_query_init(). More... | |
struct | ecs_query_count_t |
Struct returned by ecs_query_count(). More... | |
Macros | |
#define | EcsSelf (1llu << 63) |
Match on self. | |
#define | EcsUp (1llu << 62) |
Match by traversing upwards. | |
#define | EcsTrav (1llu << 61) |
Traverse relationship transitively. | |
#define | EcsCascade (1llu << 60) |
Sort results breadth first. | |
#define | EcsDesc (1llu << 59) |
Iterate groups in descending order. | |
#define | EcsIsVariable (1llu << 58) |
Term id is a variable. | |
#define | EcsIsEntity (1llu << 57) |
Term id is an entity. | |
#define | EcsIsName (1llu << 56) |
Term id is a name (don't attempt to lookup as entity). | |
#define | EcsTraverseFlags (EcsSelf|EcsUp|EcsTrav|EcsCascade|EcsDesc) |
All term traversal flags. | |
#define | EcsTermRefFlags (EcsTraverseFlags|EcsIsVariable|EcsIsEntity|EcsIsName) |
All term reference kind flags. | |
#define | EcsQueryMatchPrefab (1u << 1u) |
Query must match prefabs. | |
#define | EcsQueryMatchDisabled (1u << 2u) |
Query must match disabled entities. | |
#define | EcsQueryMatchEmptyTables (1u << 3u) |
Query must match empty tables. | |
#define | EcsQueryAllowUnresolvedByName (1u << 6u) |
Query may have unresolved entity identifiers. | |
#define | EcsQueryTableOnly (1u << 7u) |
Query only returns whole tables (ignores toggle/member fields). | |
Typedefs | |
typedef struct ecs_query_desc_t | ecs_query_desc_t |
Used with ecs_query_init(). | |
typedef struct ecs_query_count_t | ecs_query_count_t |
Struct returned by ecs_query_count(). | |
Functions | |
bool | ecs_term_ref_is_set (const ecs_term_ref_t *id) |
Test whether term id is set. | |
bool | ecs_term_is_initialized (const ecs_term_t *term) |
Test whether a term is set. | |
bool | ecs_term_match_this (const ecs_term_t *term) |
Is term matched on $this variable. | |
bool | ecs_term_match_0 (const ecs_term_t *term) |
Is term matched on 0 source. | |
char * | ecs_term_str (const ecs_world_t *world, const ecs_term_t *term) |
Convert term to string expression. | |
char * | ecs_query_str (const ecs_query_t *query) |
Convert query to string expression. | |
ecs_query_t * | ecs_query_init (ecs_world_t *world, const ecs_query_desc_t *desc) |
Create a query. | |
void | ecs_query_fini (ecs_query_t *query) |
Delete a query. | |
int32_t | ecs_query_find_var (const ecs_query_t *query, const char *name) |
Find variable index. | |
const char * | ecs_query_var_name (const ecs_query_t *query, int32_t var_id) |
Get variable name. | |
bool | ecs_query_var_is_entity (const ecs_query_t *query, int32_t var_id) |
Test if variable is an entity. | |
ecs_iter_t | ecs_query_iter (const ecs_world_t *world, const ecs_query_t *query) |
Create a query iterator. | |
bool | ecs_query_next (ecs_iter_t *it) |
Progress query iterator. | |
bool | ecs_query_has (ecs_query_t *query, ecs_entity_t entity, ecs_iter_t *it) |
Match entity with query. | |
bool | ecs_query_has_table (ecs_query_t *query, ecs_table_t *table, ecs_iter_t *it) |
Match table with query. | |
bool | ecs_query_has_range (ecs_query_t *query, ecs_table_range_t *range, ecs_iter_t *it) |
Match range with query. | |
int32_t | ecs_query_match_count (const ecs_query_t *query) |
Returns how often a match event happened for a cached query. | |
char * | ecs_query_plan (const ecs_query_t *query) |
Convert query to a string. | |
char * | ecs_query_plan_w_profile (const ecs_query_t *query, const ecs_iter_t *it) |
Convert query to string with profile. | |
const char * | ecs_query_args_parse (ecs_query_t *query, ecs_iter_t *it, const char *expr) |
Populate variables from key-value string. | |
bool | ecs_query_changed (ecs_query_t *query) |
Returns whether the query data changed since the last iteration. | |
void | ecs_iter_skip (ecs_iter_t *it) |
Skip a table while iterating. | |
void | ecs_iter_set_group (ecs_iter_t *it, uint64_t group_id) |
Set group to iterate for query iterator. | |
void * | ecs_query_get_group_ctx (const ecs_query_t *query, uint64_t group_id) |
Get context of query group. | |
const ecs_query_group_info_t * | ecs_query_get_group_info (const ecs_query_t *query, uint64_t group_id) |
Get information about query group. | |
ecs_query_count_t | ecs_query_count (const ecs_query_t *query) |
Returns number of entities and results the query matches with. | |
bool | ecs_query_is_true (const ecs_query_t *query) |
Does query return one or more results. | |
const ecs_query_t * | ecs_query_get_cache_query (const ecs_query_t *query) |
Get query used to populate cache. | |
Functions for working with ecs_query_t
.
Functions for working with ecs_term_t
and ecs_query_t
.
#define EcsCascade (1llu << 60) |
Sort results breadth first.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsDesc (1llu << 59) |
Iterate groups in descending order.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsIsEntity (1llu << 57) |
Term id is an entity.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsIsName (1llu << 56) |
Term id is a name (don't attempt to lookup as entity).
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsIsVariable (1llu << 58) |
Term id is a variable.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsQueryAllowUnresolvedByName (1u << 6u) |
Query may have unresolved entity identifiers.
Can be combined with other query flags on the ecs_query_desc_t::flags field.
#define EcsQueryMatchDisabled (1u << 2u) |
Query must match disabled entities.
Can be combined with other query flags on the ecs_query_desc_t::flags field.
#define EcsQueryMatchEmptyTables (1u << 3u) |
Query must match empty tables.
Can be combined with other query flags on the ecs_query_desc_t::flags field.
#define EcsQueryMatchPrefab (1u << 1u) |
Query must match prefabs.
Can be combined with other query flags on the ecs_query_desc_t::flags field.
#define EcsQueryTableOnly (1u << 7u) |
Query only returns whole tables (ignores toggle/member fields).
Can be combined with other query flags on the ecs_query_desc_t::flags field.
#define EcsSelf (1llu << 63) |
Match on self.
Can be combined with other term flags on the ecs_term_t::flags_ field.
#define EcsTermRefFlags (EcsTraverseFlags|EcsIsVariable|EcsIsEntity|EcsIsName) |
All term reference kind flags.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsTrav (1llu << 61) |
Traverse relationship transitively.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsTraverseFlags (EcsSelf|EcsUp|EcsTrav|EcsCascade|EcsDesc) |
All term traversal flags.
Can be combined with other term flags on the ecs_term_ref_t::id field.
#define EcsUp (1llu << 62) |
Match by traversing upwards.
Can be combined with other term flags on the ecs_term_ref_t::id field.
void ecs_iter_set_group | ( | ecs_iter_t * | it, |
uint64_t | group_id ) |
Set group to iterate for query iterator.
This operation limits the results returned by the query to only the selected group id. The query must have a group_by function, and the iterator must be a query iterator.
Groups are sets of tables that are stored together in the query cache based on a group id, which is calculated per table by the group_by function. To iterate a group, an iterator only needs to know the first and last cache node for that group, which can both be found in a fast O(1) operation.
As a result, group iteration is one of the most efficient mechanisms to filter out large numbers of entities, even if those entities are distributed across many tables. This makes it a good fit for things like dividing up a world into cells, and only iterating cells close to a player.
The group to iterate must be set before the first call to ecs_query_next(). No operations that can add/remove components should be invoked between calling ecs_iter_set_group() and ecs_query_next().
it | The query iterator. |
group_id | The group to iterate. |
void ecs_iter_skip | ( | ecs_iter_t * | it | ) |
Skip a table while iterating.
This operation lets the query iterator know that a table was skipped while iterating. A skipped table will not reset its changed state, and the query will not update the dirty flags of the table for its out columns.
Only valid iterators must be provided (next has to be called at least once & return true) and the iterator must be a query iterator.
it | The iterator result to skip. |
const char * ecs_query_args_parse | ( | ecs_query_t * | query, |
ecs_iter_t * | it, | ||
const char * | expr ) |
Populate variables from key-value string.
Convenience function to set query variables from a key-value string separated by comma's. The string must have the following format:
The key-value list may optionally be enclosed in parenthesis.
This function uses the script addon.
query | The query. |
it | The iterator for which to set the variables. |
expr | The key-value expression. |
bool ecs_query_changed | ( | ecs_query_t * | query | ) |
Returns whether the query data changed since the last iteration.
The operation will return true after:
The operation will not return true after a write-only (EcsOut) or filter (EcsInOutNone) term has changed, when a term is not matched with the current table (This subject) or for tag terms.
The changed state of a table is reset after it is iterated. If an iterator was not iterated until completion, tables may still be marked as changed.
If no iterator is provided the operation will return the changed state of the all matched tables of the query.
If an iterator is provided, the operation will return the changed state of the currently returned iterator result. The following preconditions must be met before using an iterator with change detection:
query | The query (optional if 'it' is provided). |
ecs_query_count_t ecs_query_count | ( | const ecs_query_t * | query | ) |
Returns number of entities and results the query matches with.
Only entities matching the $this variable as source are counted.
query | The query. |
int32_t ecs_query_find_var | ( | const ecs_query_t * | query, |
const char * | name ) |
Find variable index.
This operation looks up the index of a variable in the query. This index can be used in operations like ecs_iter_set_var() and ecs_iter_get_var().
query | The query. |
name | The variable name. |
void ecs_query_fini | ( | ecs_query_t * | query | ) |
Delete a query.
query | The query. |
const ecs_query_t * ecs_query_get_cache_query | ( | const ecs_query_t * | query | ) |
Get query used to populate cache.
This operation returns the query that is used to populate the query cache. For queries that are can be entirely cached, the returned query will be equivalent to the query passed to ecs_query_get_cache_query().
query | The query. |
void * ecs_query_get_group_ctx | ( | const ecs_query_t * | query, |
uint64_t | group_id ) |
Get context of query group.
This operation returns the context of a query group as returned by the on_group_create callback.
query | The query. |
group_id | The group for which to obtain the context. |
const ecs_query_group_info_t * ecs_query_get_group_info | ( | const ecs_query_t * | query, |
uint64_t | group_id ) |
Get information about query group.
This operation returns information about a query group, including the group context returned by the on_group_create callback.
query | The query. |
group_id | The group for which to obtain the group info. |
bool ecs_query_has | ( | ecs_query_t * | query, |
ecs_entity_t | entity, | ||
ecs_iter_t * | it ) |
Match entity with query.
This operation matches an entity with a query and returns the result of the match in the "it" out parameter. An application should free the iterator resources with ecs_iter_fini() if this function returns true.
Usage:
query | The query. |
entity | The entity to match |
it | The iterator with matched data. |
bool ecs_query_has_range | ( | ecs_query_t * | query, |
ecs_table_range_t * | range, | ||
ecs_iter_t * | it ) |
Match range with query.
This operation matches a range with a query and returns the result of the match in the "it" out parameter. An application should free the iterator resources with ecs_iter_fini() if this function returns true.
The entire range must match the query for the operation to return true.
Usage:
query | The query. |
range | The range to match |
it | The iterator with matched data. |
bool ecs_query_has_table | ( | ecs_query_t * | query, |
ecs_table_t * | table, | ||
ecs_iter_t * | it ) |
Match table with query.
This operation matches a table with a query and returns the result of the match in the "it" out parameter. An application should free the iterator resources with ecs_iter_fini() if this function returns true.
Usage:
query | The query. |
table | The table to match |
it | The iterator with matched data. |
ecs_query_t * ecs_query_init | ( | ecs_world_t * | world, |
const ecs_query_desc_t * | desc ) |
Create a query.
world | The world. |
desc | The descriptor (see ecs_query_desc_t) |
bool ecs_query_is_true | ( | const ecs_query_t * | query | ) |
Does query return one or more results.
query | The query. |
ecs_iter_t ecs_query_iter | ( | const ecs_world_t * | world, |
const ecs_query_t * | query ) |
Create a query iterator.
Use an iterator to iterate through the entities that match an entity. Queries can return multiple results, and have to be iterated by repeatedly calling ecs_query_next() until the operation returns false.
Depending on the query, a single result can contain an entire table, a range of entities in a table, or a single entity. Iteration code has an inner and an outer loop. The outer loop loops through the query results, and typically corresponds with a table. The inner loop loops entities in the result.
Example:
The world passed into the operation must be either the actual world or the current stage, when iterating from a system. The stage is accessible through the it.world member.
Example:
If query iteration is stopped without the last call to ecs_query_next() returning false, iterator resources need to be cleaned up explicitly with ecs_iter_fini().
Example:
world | The world. |
query | The query. |
int32_t ecs_query_match_count | ( | const ecs_query_t * | query | ) |
Returns how often a match event happened for a cached query.
This operation can be used to determine whether the query cache has been updated with new tables.
query | The query. |
bool ecs_query_next | ( | ecs_iter_t * | it | ) |
Progress query iterator.
it | The iterator. |
char * ecs_query_plan | ( | const ecs_query_t * | query | ) |
Convert query to a string.
This will convert the query program to a string which can aid in debugging the behavior of a query.
The returned string must be freed with ecs_os_free().
query | The query. |
char * ecs_query_plan_w_profile | ( | const ecs_query_t * | query, |
const ecs_iter_t * | it ) |
Convert query to string with profile.
To use this you must set the EcsIterProfile flag on an iterator before starting iteration:
The returned string must be freed with ecs_os_free().
query | The query. |
it | The iterator with profile data. |
char * ecs_query_str | ( | const ecs_query_t * | query | ) |
Convert query to string expression.
Convert query to a string expression. The resulting expression can be parsed to create the same query.
query | The query. |
bool ecs_query_var_is_entity | ( | const ecs_query_t * | query, |
int32_t | var_id ) |
Test if variable is an entity.
Internally the query engine has entity variables and table variables. When iterating through query variables (by using ecs_query_variable_count()) only the values for entity variables are accessible. This operation enables an application to check if a variable is an entity variable.
query | The query. |
var_id | The variable id. |
const char * ecs_query_var_name | ( | const ecs_query_t * | query, |
int32_t | var_id ) |
Get variable name.
This operation returns the variable name for an index.
query | The query. |
var_id | The variable index. |
bool ecs_term_is_initialized | ( | const ecs_term_t * | term | ) |
Test whether a term is set.
This operation can be used to test whether a term has been initialized with values or whether it is empty.
An application generally does not need to invoke this operation. It is useful when initializing a 0-initialized array of terms (like in ecs_term_desc_t) as this operation can be used to find the last initialized element.
term | The term. |
bool ecs_term_match_0 | ( | const ecs_term_t * | term | ) |
Is term matched on 0 source.
This operation checks whether a term is matched on a 0 source. A 0 source is a term that isn't matched against anything, and can be used just to pass (component) ids to a query iterator.
A term has a 0 source when:
term | The term. |
bool ecs_term_match_this | ( | const ecs_term_t * | term | ) |
Is term matched on $this variable.
This operation checks whether a term is matched on the $this variable, which is the default source for queries.
A term has a $this source when:
If ecs_term_t::src is not populated, it will be automatically initialized to the $this source for the created query.
term | The term. |
bool ecs_term_ref_is_set | ( | const ecs_term_ref_t * | id | ) |
Test whether term id is set.
id | The term id. |
char * ecs_term_str | ( | const ecs_world_t * | world, |
const ecs_term_t * | term ) |
Convert term to string expression.
Convert term to a string expression. The resulting expression is equivalent to the same term, with the exception of And & Or operators.
world | The world. |
term | The term. |