View Source Ecspanse.Query (ECSpanse v0.10.0)
The Ecspanse.Query
module provides a set of functions for querying entities, components and resources.
The queries are read-only operations they do not modify the state of the components or resources.
Queries can be run both from within the Ecspanse systems and from outside of the framework.
Summary
Generic
Returns a single tuple with components for a t/0
query. Returns nil
if no result was found. Raises if more than one entry.
select/2
is the most versatile function for querying entities and components.
On its own, it will return an Ecspanse.Query
struct that holds the query details.
The struct needs to be passed to Ecspanse.Query.stream/1
or Ecspanse.Query.one/1
to get the results.
Returns a stream of components tuples for a t/0
query.
Entities
Checks if an entity exists by its ID, or by the entity struct.
Fetches an Ecspanse.Entity.t/0
by its ID.
Returns a component's entity.
Relationships
Returns true if the entity has at least a child with the given component module.
Returns true if the entity has at least a child with all the given component modules.
Returns true if the entity has at least a parent with the given component module.
Returns true if the entity has at least a parent with all the given component modules.
Returns true
if a given entity is a child of another entity.
Returns true
if a given entity is a parent of another entity.
Returns the list of ancestor entities for the given entity. That means the parents of the entity and their parents and so on.
Returns the list of child entities for the given entity.
Returns the list of descendant entities for the given entity. That means the children of the entity and their children and so on.
Returns the list of parent entities for the given entity.
Components
Fetches the component by its module for a given entity.
Fetches a tuple of components by their modules for a given entity. The entity must have all the components for the query to succeed.
Returns true
if the entity has a component with the given module.
Returns true
if the entity has all the components with the given modules.
Lists all the components for a given entity.
Resources
Fetches a resource by its module.
Generic
Returns a single tuple with components for a t/0
query. Returns nil
if no result was found. Raises if more than one entry.
See the select/2
function for more info.
select/2
is the most versatile function for querying entities and components.
On its own, it will return an Ecspanse.Query
struct that holds the query details.
The struct needs to be passed to Ecspanse.Query.stream/1
or Ecspanse.Query.one/1
to get the results.
Arguments
1. component_modules
The first argument is a tuple of components to be selected. The query will return the components only for the entities that have all the components in the tuple.
The entity can be queried as well by adding Ecspanse.Entity
as the first element in the tuple.
Also, optional components can be queries, by adding the :opt
key.
The optional components should be placed at the end of the tuple.
The results will be returned in the same order as the components in the tuple. This makes it easy to use pattern matching on the result.
2. filters
The filters are optional. They can be used to further narrow down the results.
:with
- a list of components that the entity must have in addition to the ones specified in thecomponent_modules
tuple. But those components will not be returned in the result.:with
filter has one option::without
- a list of components that the entity must not have.:or_with
- similar to:with
. It allows to specify multiple filters for the same query. Multipleor_with
filters can be used in the same query. The results will be returned if the entity components match any of the filters.:for
- a list ofEcspanse.Entity.t/0
that the query should be run for. The components will be returned only for those entities.:not_for
- a list ofEcspanse.Entity.t/0
that the query should not be run for. The components will be returned for all entities except those.:for_children_of
- a list ofEcspanse.Entity.t/0
. The components will be returned only for the children of those entities.:for_descendants_of
- a list ofEcspanse.Entity.t/0
. The components will be returned only for all descendants of those entities.:for_parents_of
- a list ofEcspanse.Entity.t/0
. The components will be returned only for the parents of those entities.:for_ancestors_of
- a list ofEcspanse.Entity.t/0
. The components will be returned only for all ancestors of those entities.
Info
Combining the following filters is not supported:
:for, :not_for, :for_children_of, :for_descendants_of, :for_parents_of, :for_ancestors_of
. Only one of them can be used in a query. Otherwise it will rise an error.
Examples
Ecspanse.Query.select({Ecspanse.Entity, Demo.Components.Health, opt: Demo.Components.Mana},
with: [Demo.Components.Orc],
or_with: [[Demo.Components.Wizard], without: [Demo.Components.WhiteMagic]],
for_descendants_of: [enemy_clan_entity]
)
|> Ecspanse.Query.stream()
|> Enum.to_list()
a potential result may be:
[
{orc_entity, %Demo.Components.Health{value: 100}, nil},
{wizard_entity, %Demo.Components.Health{value: 60}, %Demo.Components.Mana{value: 200}}
]
@spec stream(t()) :: Enumerable.t()
Returns a stream of components tuples for a t/0
query.
See the select/2
function for more info.
Entities
@spec entity_exists?(Ecspanse.Entity.id() | Ecspanse.Entity.t()) :: boolean()
Checks if an entity exists by its ID, or by the entity struct.
@spec fetch_entity(Ecspanse.Entity.id()) :: {:ok, Ecspanse.Entity.t()} | {:error, :not_found}
Fetches an Ecspanse.Entity.t/0
by its ID.
An entity exists only if it has at least one component.
Examples
{:ok, %Ecspanse.Entity{}} = Ecspanse.Query.fetch_entity(hero_entity_id)
@spec get_component_entity(component_state :: struct()) :: Ecspanse.Entity.t()
Returns a component's entity.
Examples
{:ok, %Ecspanse.Entity{}} = Ecspanse.Query.get_component_entity(hero_component)
Relationships
@spec has_children_with_component?(Ecspanse.Entity.t(), module()) :: boolean()
Returns true if the entity has at least a child with the given component module.
Examples
true = Ecspanse.Query.has_children_with_component?(hero_entity, Demo.Components.Boots)
@spec has_children_with_components?(Ecspanse.Entity.t(), [module()]) :: boolean()
Returns true if the entity has at least a child with all the given component modules.
Examples
true = Ecspanse.Query.has_children_with_components?(hero_entity, [Demo.Components.Boots, Demo.Components.Sword])
@spec has_parents_with_component?(Ecspanse.Entity.t(), module()) :: boolean()
Returns true if the entity has at least a parent with the given component module.
Examples
true = Ecspanse.Query.has_parents_with_component?(boots_entity, Demo.Components.Hero)
@spec has_parents_with_components?(Ecspanse.Entity.t(), [module()]) :: boolean()
Returns true if the entity has at least a parent with all the given component modules.
Examples
true = Ecspanse.Query.has_parents_with_components?(boots_entity, [Demo.Components.Hero, Demo.Components.Gold])
@spec is_child_of?(parent: Ecspanse.Entity.t(), child: Ecspanse.Entity.t()) :: boolean()
Returns true
if a given entity is a child of another entity.
Examples
true = Ecspanse.Query.is_child_of?(parent: hero_entity, child: boots_entity)
@spec is_parent_of?(parent: Ecspanse.Entity.t(), child: Ecspanse.Entity.t()) :: boolean()
Returns true
if a given entity is a parent of another entity.
Examples
true = Ecspanse.Query.is_parent_of?(parent: hero_entity, child: boots_entity)
@spec list_ancestors(Ecspanse.Entity.t()) :: [Ecspanse.Entity.t()]
Returns the list of ancestor entities for the given entity. That means the parents of the entity and their parents and so on.
Examples
[hero_entity, level_entity] = Ecspanse.Query.list_ancestors(compass_entity)
@spec list_children(Ecspanse.Entity.t()) :: [Ecspanse.Entity.t()]
Returns the list of child entities for the given entity.
Examples
[sword_item_entity, magic_potion_entity] = Ecspanse.Query.list_children(hero_entity)
@spec list_descendants(Ecspanse.Entity.t()) :: [Ecspanse.Entity.t()]
Returns the list of descendant entities for the given entity. That means the children of the entity and their children and so on.
Examples
[inventory_entity, map_entity] = Ecspanse.Query.list_descendants(hero_entity)
@spec list_parents(Ecspanse.Entity.t()) :: [Ecspanse.Entity.t()]
Returns the list of parent entities for the given entity.
Examples
[hero_entity] = Ecspanse.Query.list_parents(inventory_entity)
Components
@spec fetch_component(Ecspanse.Entity.t(), module()) :: {:ok, component_state :: struct()} | {:error, :not_found}
Fetches the component by its module for a given entity.
Examples
{:ok, gold_component} = Ecspanse.Query.fetch_component(hero_entity, Demo.Components.Gold)
@spec fetch_components(Ecspanse.Entity.t(), component_modules :: tuple()) :: {:ok, components_state :: tuple()} | {:error, :not_found}
Fetches a tuple of components by their modules for a given entity. The entity must have all the components for the query to succeed.
Examples
{:ok, {gold_component, gems_component}} = Ecspanse.Query.fetch_components(hero_entity, {Demo.Components.Gold, Demo.Components.Gems})
@spec has_component?(Ecspanse.Entity.t(), module()) :: boolean()
Returns true
if the entity has a component with the given module.
Examples
true = Ecspanse.Query.has_component?(hero_entity, Demo.Components.Gold)
@spec has_components?(Ecspanse.Entity.t(), [module()]) :: boolean()
Returns true
if the entity has all the components with the given modules.
Examples
true = Ecspanse.Query.has_components?(hero_entity, [Demo.Components.Gold, Demo.Components.Gems])
@spec list_components(Ecspanse.Entity.t()) :: [components_state :: struct()]
Lists all the components for a given entity.
The output is an unordered list of all the entity's components.
Note
The
Ecspanse.Component.Children
andEcspanse.Component.Parents
components are excluded from the output.Use the provided
list_children/1
andlist_parents/1
functions to query the entity's relations.
Examples
[gold_component, gems_component, position_component, energy_component] =
Ecspanse.Query.list_components(hero_entity)
Resources
Types
@type t() :: %Ecspanse.Query{ for_ancestors_of: [Ecspanse.Entity.t()], for_children_of: [Ecspanse.Entity.t()], for_descendants_of: [Ecspanse.Entity.t()], for_entities: [Ecspanse.Entity.t()], for_parents_of: [Ecspanse.Entity.t()], not_for_entities: [Ecspanse.Entity.t()], or: [ [ with_components: [component_module :: module()], without_components: [component_module :: module()] ] ], return_entity: boolean(), select: [component_module :: module()], select_optional: [component_module :: module()] }
The query preparation struct.