Flecs: Queries
Description: A fast entity component system (ECS) for C & C++

| Flecs v4.0 A fast entity component system (ECS) for C & C++

Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Functions
Queries
C API » Core

Functions for working with `ecs_term_t` and `ecs_query_t`. More...

Collaboration diagram for Queries:

## 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.
const ecs_query_t * | ecs_query_get (const ecs_world_t *world, ecs_entity_t query)
| Get query object.
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.

## Detailed Description

Functions for working with `ecs_term_t` and `ecs_query_t`.

Functions for working with `ecs_query_t`.

## Macro Definition Documentation

## ◆ EcsCascade

#define EcsCascade (1llu << 60)

Sort results breadth first.

Can be combined with other term flags on the ecs_term_ref_t::id field.

Definition at line 735 of file flecs.h.

## ◆ EcsDesc

#define EcsDesc (1llu << 59)

Iterate groups in descending order.

Can be combined with other term flags on the ecs_term_ref_t::id field.

Definition at line 741 of file flecs.h.

## ◆ EcsIsEntity

#define EcsIsEntity (1llu << 57)

Term id is an entity.

Can be combined with other term flags on the ecs_term_ref_t::id field.

Definition at line 753 of file flecs.h.

## ◆ EcsIsName

#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.

Definition at line 759 of file flecs.h.

## ◆ EcsIsVariable

#define EcsIsVariable (1llu << 58)

Term id is a variable.

Can be combined with other term flags on the ecs_term_ref_t::id field.

Definition at line 747 of file flecs.h.

## ◆ EcsQueryAllowUnresolvedByName

#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.

Definition at line 1223 of file flecs.h.

## ◆ EcsQueryMatchDisabled

#define EcsQueryMatchDisabled (1u << 2u)

Query must match disabled entities.

Can be combined with other query flags on the ecs_query_desc_t::flags field.

Definition at line 1211 of file flecs.h.

## ◆ EcsQueryMatchEmptyTables

#define EcsQueryMatchEmptyTables (1u << 3u)

Query must match empty tables.

Can be combined with other query flags on the ecs_query_desc_t::flags field.

Definition at line 1217 of file flecs.h.

## ◆ EcsQueryMatchPrefab

#define EcsQueryMatchPrefab (1u << 1u)

Query must match prefabs.

Can be combined with other query flags on the ecs_query_desc_t::flags field.

Definition at line 1205 of file flecs.h.

## ◆ EcsQueryTableOnly

#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.

Definition at line 1229 of file flecs.h.

## ◆ EcsSelf

#define EcsSelf (1llu << 63)

Match on self.

Can be combined with other term flags on the ecs_term_t::flags_ field.

Definition at line 717 of file flecs.h.

## ◆ EcsTermRefFlags

#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.

Definition at line 771 of file flecs.h.

## ◆ EcsTrav

#define EcsTrav (1llu << 61)

Traverse relationship transitively.

Can be combined with other term flags on the ecs_term_ref_t::id field.

Definition at line 729 of file flecs.h.

## ◆ EcsTraverseFlags

#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.

Definition at line 765 of file flecs.h.

## ◆ EcsUp

#define EcsUp (1llu << 62)

Match by traversing upwards.

Can be combined with other term flags on the ecs_term_ref_t::id field.

Definition at line 723 of file flecs.h.

## Function Documentation

## ◆ ecs_iter_set_group()

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().

Parameters

  it | The query iterator.
  group_id | The group to iterate.

## ◆ ecs_iter_skip()

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.

Parameters

  it | The iterator result to skip.

## ◆ ecs_query_args_parse()

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:

var_a: value, var_b: value

The key-value list may optionally be enclosed in parenthesis.

This function uses the script addon.

Parameters

  query | The query.
  it | The iterator for which to set the variables.
  expr | The key-value expression.

Returns
  Pointer to the next character after the last parsed one.

## ◆ ecs_query_changed()

bool ecs_query_changed | ( | ecs_query_t * | query | ) |

Returns whether the query data changed since the last iteration.

The operation will return true after:

- new entities have been matched with
- new tables have been matched/unmatched with
- matched entities were deleted
- matched components were changed

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:

- The iterator is a query iterator (created with ecs_query_iter())
- The iterator must be valid (ecs_query_next() must have returned true)

Parameters

  query | The query (optional if 'it' is provided).

Returns
  true if entities changed, otherwise false.

## ◆ ecs_query_count()

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.

Parameters

  query | The query.

Returns
  The number of matched entities.

## ◆ ecs_query_find_var()

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().

Parameters

  query | The query.
  name | The variable name.

Returns
  The variable index.

## ◆ ecs_query_fini()

void ecs_query_fini | ( | ecs_query_t * | query | ) |

Delete a query.

Parameters

  query | The query.

## ◆ ecs_query_get()

const ecs_query_t * ecs_query_get | ( | const ecs_world_t * | world,
|  | ecs_entity_t | query )

Get query object.

Returns the query object. Can be used to access various information about the query.

Parameters

  world | The world.
  query | The query.

Returns
  The query object.

## ◆ ecs_query_get_cache_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().

Parameters

  query | The query.

Returns
  The query used to populate the cache, NULL if query is not cached.

## ◆ ecs_query_get_group_ctx()

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.

Parameters

  query | The query.
  group_id | The group for which to obtain the context.

Returns
  The group context, NULL if the group doesn't exist.

## ◆ ecs_query_get_group_info()

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.

Parameters

  query | The query.
  group_id | The group for which to obtain the group info.

Returns
  The group info, NULL if the group doesn't exist.

## ◆ ecs_query_has()

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:

ecs_iter_t it;
if (ecs_query_has(q, e, &it)) {
ecs_iter_fini(&it);
}
ecs_iter_fini
void ecs_iter_fini(ecs_iter_t *it)
Cleanup iterator resources.
ecs_query_has
bool ecs_query_has(ecs_query_t *query, ecs_entity_t entity, ecs_iter_t *it)
Match entity with query.
ecs_iter_t
Iterator.
Definition flecs.h:1136

Parameters

  query | The query.
  entity | The entity to match
  it | The iterator with matched data.

Returns
  True if entity matches the query, false if not.

## ◆ ecs_query_has_range()

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:

ecs_table_range_t range = {
.table = table,
.offset = 1,
.count = 2
};
ecs_iter_t it;
if (ecs_query_has_range(q, &range, &it)) {
ecs_iter_fini(&it);
}
ecs_query_has_range
bool ecs_query_has_range(ecs_query_t *query, ecs_table_range_t *range, ecs_iter_t *it)
Match range with query.

Parameters

  query | The query.
  range | The range to match
  it | The iterator with matched data.

Returns
  True if range matches the query, false if not.

## ◆ ecs_query_has_table()

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:

ecs_iter_t it;
if (ecs_query_has_table(q, t, &it)) {
ecs_iter_fini(&it);
}
ecs_query_has_table
bool ecs_query_has_table(ecs_query_t *query, ecs_table_t *table, ecs_iter_t *it)
Match table with query.

Parameters

  query | The query.
  table | The table to match
  it | The iterator with matched data.

Returns
  True if table matches the query, false if not.

## ◆ ecs_query_init()

ecs_query_t * ecs_query_init | ( | ecs_world_t * | world,
|  | const ecs_query_desc_t * | desc )

Create a query.

Parameters

  world | The world.
  desc | The descriptor (see ecs_query_desc_t)

Returns
  The query.

## ◆ ecs_query_is_true()

bool ecs_query_is_true | ( | const ecs_query_t * | query | ) |

Does query return one or more results.

Parameters

  query | The query.

Returns
  True if query matches anything, false if not.

## ◆ ecs_query_iter()

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:

ecs_iter_t it = ecs_query_iter(world, q);
while (ecs_query_next(&it)) {
Position *p = ecs_field(&it, Position, 0);
Velocity *v = ecs_field(&it, Velocity, 1);
for (int i = 0; i < it.count; i ++) {
p[i].x += v[i].x;
p[i].y += v[i].y;
}
}
ecs_query_next
bool ecs_query_next(ecs_iter_t *it)
Progress query iterator.
ecs_query_iter
ecs_iter_t ecs_query_iter(const ecs_world_t *world, const ecs_query_t *query)
Create a query iterator.
ecs_iter_t::count
int32_t count
Number of entities to iterate.
Definition flecs.h:1186

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:

void MySystem(ecs_iter_t *it) {
ecs_query_t *q = it->ctx; // Query passed as system context
// Create query iterator from system stage
ecs_iter_t qit = ecs_query_iter(it->world, q);
while (ecs_query_next(&qit)) {
// Iterate as usual
}
}
ecs_iter_t::ctx
void * ctx
System context.
Definition flecs.h:1174
ecs_iter_t::world
ecs_world_t * world
The world.
Definition flecs.h:1138
ecs_query_t
Queries are lists of constraints (terms) that match entities.
Definition flecs.h:813

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:

ecs_iter_t it = ecs_query_iter(world, q);
while (ecs_query_next(&it)) {
if (!ecs_field_is_set(&it, 0)) {
ecs_iter_fini(&it); // Free iterator resources
break;
}
for (int i = 0; i < it.count; i ++) {
// ...
}
}
ecs_field_is_set
bool ecs_field_is_set(const ecs_iter_t *it, int8_t index)
Test whether field is set.

Parameters

  world | The world.
  query | The query.

Returns
  An iterator.

See also
  ecs_query_next()

## ◆ ecs_query_match_count()

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.

Parameters

  query | The query.

Returns
  The number of match events happened.

## ◆ ecs_query_next()

bool ecs_query_next | ( | ecs_iter_t * | it | ) |

Progress query iterator.

Parameters

  it | The iterator.

Returns
  True if the iterator has more results, false if not.

See also
  ecs_query_iter()

## ◆ ecs_query_plan()

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().

Parameters

  query | The query.

Returns
  The query plan.

## ◆ ecs_query_plan_w_profile()

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:

it.flags |= EcsIterProfile

The returned string must be freed with ecs_os_free().

Parameters

  query | The query.
  it | The iterator with profile data.

Returns
  The query plan with profile data.

## ◆ ecs_query_str()

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.

Parameters

  query | The query.

Returns
  The query converted to a string.

## ◆ ecs_query_var_is_entity()

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.

Parameters

  query | The query.
  var_id | The variable id.

Returns
  Whether the variable is an entity variable.

## ◆ ecs_query_var_name()

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.

Parameters

  query | The query.
  var_id | The variable index.

Returns
  The variable name.

## ◆ ecs_term_is_initialized()

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.

Parameters

  term | The term.

Returns
  True when set, false when not set.

## ◆ ecs_term_match_0()

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:

- ecs_term_t::src::id is 0
- ecs_term_t::src::flags has EcsIsEntity set

Parameters

  term | The term.

Returns
  True if term has 0 source, false if not.

## ◆ ecs_term_match_this()

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:

- ecs_term_t::src::id is EcsThis
- ecs_term_t::src::flags is EcsIsVariable

If ecs_term_t::src is not populated, it will be automatically initialized to the $this source for the created query.

Parameters

  term | The term.

Returns
  True if term matches $this, false if not.

## ◆ ecs_term_ref_is_set()

bool ecs_term_ref_is_set | ( | const ecs_term_ref_t * | id | ) |

Test whether term id is set.

Parameters

  id | The term id.

Returns
  True when set, false when not set.

## ◆ ecs_term_str()

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.

Parameters

  world | The world.
  term | The term.

Returns
  The term converted to a string.