View Source Ecspanse.Command (ECSpanse v0.4.0)
The Ecspanse.Command
module provides a set of functions for managing entities, components and resources in the Ecspanse
engine.
Commands are the only way to change the state of components and resources in Ecspanse
. These commands can only be run from systems, otherwise an error will be thrown.
The Ecspanse.Command
module includes functions for managing relationships between entities, such as adding and removing children and parents.
All entity and component related commands can run for batches (lists) for performance reasons.
All commands raise an error if the command fails.
Entity Relationships
The Ecspanse.Command
module provides functions for managing relationships between entities.
This is aslo a powerful tool to manage different kind of collections.
Ecspanse entities relationships are bidirectional associations
When adding or removing children or parents, they are automatically added or removed from the corresponding parent or children entities. The same applies when despawning entities.
Summary
Entities
Clones the specified entity and returns a new entity with the same components.
Clones the specified entity and all of its descendants and returns the newly cloned entity.
The same as despawn_entity!/1
but despawns multiple entities at once.
It takes a list of entities as argument and returns :ok
. See despawn_entity!/1
for more details.
The same as despawn_entity_and_descendants!/1
but despawns multiple entities and their descendants at once.
It takes a list of entities as argument and returns :ok
.
Despawns the specified entity and removes all of its components. It also removes the despawned entity from its parent and child entities, if any.
The same as despawn_entity!/1
but recursively despawns also all descendant tree of the entity.
The same as spawn_entity!/1
but spawns multiple entities at once.
It takes a list of entity specs as argument and returns a list of Ecspanse.Entity structs.
Spawns a new entity with the given components and relations provided by the Ecspanse.Entity.entity_spec() type.
When creating a new entity, at least one of the components:
, children:
or parents:
must be provided in the entity spec, otherwise the entity cannot be persisted.
Relationships
Adds an entity as child to a parent entity.
The same as add_child!/2
but can perform multiple operations at once.
For example, adding multiple children to multiple parents.
Adds a parent entity to a child entity.
The same as add_parent!/2
but can perform multiple operations at once.
For example, adding multiple parents to multiple children.
Removes a child entity from a parent entity.
The same as remove_child!/2
but can perform multiple operations at once.
For example, removing multiple children from multiple parents.
Removes a parent entity from a child entity.
The same as remove_parent!/2
but can perform multiple operations at once.
For example, removing multiple parents from multiple children.
Components
Adds a new component to the specified entity.
The same as add_component!/2
but adds multiple components to multiple entities at once.
Removes an existing component from its entity. The components is destroyed.
The same as remove_component!/1
but removes multiple components at once.
Updates the state of an existing component.
The same as update_component!/2
but updates multiple components at once.
Resources
Deletes an existing global resource.
Inserts a new global resource.
Updates an existing global resource.
Entities
@spec clone_entity!(Ecspanse.Entity.t()) :: Ecspanse.Entity.t()
Clones the specified entity and returns a new entity with the same components.
Due to the potentially large number of components that may be affected by this operation,
it is recommended to run this function in a synchronous system (such as a frame_start
or frame_end
system)
to avoid the need to lock all involved components.
Note
The entity's
Ecspanse.Component.Children
andEcspanse.Component.Parents
components are not cloned. Usedeep_clone_entity!/1
to clone the entity and all of its descendants.
Examples
%Ecspanse.Entity{} = entity = Ecspanse.Command.clone_entity!(compass_entity)
@spec deep_clone_entity!(Ecspanse.Entity.t()) :: Ecspanse.Entity.t()
Clones the specified entity and all of its descendants and returns the newly cloned entity.
Due to the potentially large number of components that may be affected by this operation,
it is recommended to run this function in a synchronous system (such as a frame_start
or frame_end
system)
to avoid the need to lock all involved components.
Examples
%Ecspanse.Entity{} = entity = Ecspanse.Command.deep_clone_entity!(enemy_entity)
@spec despawn_entities!([Ecspanse.Entity.t()]) :: :ok
The same as despawn_entity!/1
but despawns multiple entities at once.
It takes a list of entities as argument and returns :ok
. See despawn_entity!/1
for more details.
@spec despawn_entities_and_descendants!([Ecspanse.Entity.t()]) :: :ok
The same as despawn_entity_and_descendants!/1
but despawns multiple entities and their descendants at once.
It takes a list of entities as argument and returns :ok
.
@spec despawn_entity!(Ecspanse.Entity.t()) :: :ok
Despawns the specified entity and removes all of its components. It also removes the despawned entity from its parent and child entities, if any.
Due to the potentially large number of components that may be affected by this operation,
it is recommended to run this function in a synchronous system (such as a frame_start
or frame_end
system)
to avoid the need to lock all involved components.
Examples
:ok = Ecspanse.Command.despawn_entity!(hero_entity)
@spec despawn_entity_and_descendants!(Ecspanse.Entity.t()) :: :ok
The same as despawn_entity!/1
but recursively despawns also all descendant tree of the entity.
This means that it will despawn the children of the entity, and their children, and so on.
It is an efficient way to remove an entire entity tree with just one operation. Extra attention required for entities with shared children.
See despawn_entity!/1
for more details.
@spec spawn_entities!([Ecspanse.Entity.entity_spec()]) :: [Ecspanse.Entity.t()]
The same as spawn_entity!/1
but spawns multiple entities at once.
It takes a list of entity specs as argument and returns a list of Ecspanse.Entity structs.
See spawn_entity!/1
for more details.
@spec spawn_entity!(Ecspanse.Entity.entity_spec()) :: Ecspanse.Entity.t()
Spawns a new entity with the given components and relations provided by the Ecspanse.Entity.entity_spec() type.
When creating a new entity, at least one of the components:
, children:
or parents:
must be provided in the entity spec, otherwise the entity cannot be persisted.
Due to the potentially large number of components that may be affected by this operation,
it is recommended to run this function in a synchronous system (such as a frame_start
or frame_end
system)
to avoid the need to lock all involved components.
Examples
%Ecspanse.Entity{} = Ecspanse.Command.spawn_entity!(
{
Ecspanse.Entity,
id: "my_custom_id",
components: [Demo.Components.Hero, {Demo.Components.Position, [x: 5, y: 3], [:hero, :map]}],
children: [potion_entity, sword_entity],
parents: [map_entity]
}
)
Relationships
@spec add_child!(Ecspanse.Entity.t(), child :: Ecspanse.Entity.t()) :: :ok
Adds an entity as child to a parent entity.
Examples
:ok = Ecspanse.Command.add_child!(hero_entity, sword_entity)
@spec add_children!([{Ecspanse.Entity.t(), children :: [Ecspanse.Entity.t()]}]) :: :ok
The same as add_child!/2
but can perform multiple operations at once.
For example, adding multiple children to multiple parents.
It takes a list of two element tuples as argument, where the first element of the tuple is the parent entity and the second element is a list of children entities.
Examples
:ok = Ecspanse.Command.add_children!([
{hero_entity, [sword_entity]},
{market_entity, [map_entity, potion_entity]}
])
@spec add_parent!(Ecspanse.Entity.t(), parent :: Ecspanse.Entity.t()) :: :ok
Adds a parent entity to a child entity.
Examples
:ok = Ecspanse.Command.add_parent!(sowrd_entity, hero_entity)
@spec add_parents!([{Ecspanse.Entity.t(), parents :: [Ecspanse.Entity.t()]}]) :: :ok
The same as add_parent!/2
but can perform multiple operations at once.
For example, adding multiple parents to multiple children.
It takes a list of two element tuples as argument, where the first element of the tuple is the child entity and the second element is a list of parent entities.
Examples
:ok = Ecspanse.Command.add_parents!([
{sword_entity, [hero_entity]},
{map_entity, [market_entity, vendor_entity]}
])
@spec remove_child!(Ecspanse.Entity.t(), child :: Ecspanse.Entity.t()) :: :ok
Removes a child entity from a parent entity.
Examples
:ok = Ecspanse.Command.remove_child!(hero_entity, sword_entity)
@spec remove_children!([{Ecspanse.Entity.t(), children :: [Ecspanse.Entity.t()]}]) :: :ok
The same as remove_child!/2
but can perform multiple operations at once.
For example, removing multiple children from multiple parents.
It takes a list of two element tuples as argument, where the first element of the tuple is the parent entity and the second element is a list of children entities.
Examples
:ok = Ecspanse.Command.remove_children!([
{hero_entity, [sword_entity]},
{market_entity, [map_entity, potion_entity]}
])
@spec remove_parent!(Ecspanse.Entity.t(), parent :: Ecspanse.Entity.t()) :: :ok
Removes a parent entity from a child entity.
Examples
:ok = Ecspanse.Command.remove_parent!(sword_entity, hero_entity)
@spec remove_parents!([{Ecspanse.Entity.t(), parents :: [Ecspanse.Entity.t()]}]) :: :ok
The same as remove_parent!/2
but can perform multiple operations at once.
For example, removing multiple parents from multiple children.
It takes a list of two element tuples as argument, where the first element of the tuple is the child entity and the second element is a list of parent entities.
Examples
:ok = Ecspanse.Command.remove_parents!([
{sword_entity, [hero_entity]},
{map_entity, [market_entity, vendor_entity]}
])
Components
@spec add_component!(Ecspanse.Entity.t(), Ecspanse.Component.component_spec()) :: :ok
Adds a new component to the specified entity.
Info
An entity cannot have multiple components of the same type. If an attempt is made to insert a component that already exists for the entity, an error will be raised.
Examples
:ok = Ecspanse.Command.add_component!(hero_entity, Demo.Components.Gold)
:ok = Ecspanse.Command.add_component!(hero_entity, {Demo.Components.Gold, [amount: 5], [:resource, :available]})
@spec add_components!([{Ecspanse.Entity.t(), [Ecspanse.Component.component_spec()]}]) :: :ok
The same as add_component!/2
but adds multiple components to multiple entities at once.
It takes a list of two element tuples as argument, where the first element of the tuple is the entity and the second element is a list of component specs.
Examples
:ok = Ecspanse.Command.add_components!([
{inventory_item_entity, [Demo.Components.Sword]},
{hero_entity, [Demo.Components.Position, Demo.Components.Hero]}
])
@spec remove_component!(component :: struct()) :: :ok
Removes an existing component from its entity. The components is destroyed.
Examples
:ok = Ecspanse.Command.remove_component!(invisibility_component)
@spec remove_components!([component :: struct()]) :: :ok
The same as remove_component!/1
but removes multiple components at once.
Updates the state of an existing component.
The function takes two arguments: the component struct to update and a keyword list of changes to apply.
Examples
:ok = Ecspanse.Command.update_component!(position_component, x: :12)
The same as update_component!/2
but updates multiple components at once.
It takes a list of two element tuples as argument, where the first element of the tuple is the component struct and the second element is a keyword list of changes to apply.
Examples
:ok = Ecspanse.Command.update_components!([
{position_component, x: 7, y: 9},
{gold_component, amount: 12}
])
Resources
Deletes an existing global resource.
Examples
:ok = Ecspanse.Command.delete_resource!(lobby_resource)
@spec insert_resource!(resource_spec :: Ecspanse.Resource.resource_spec()) :: resource :: struct()
Inserts a new global resource.
Info
An Ecspanse instance can only hold one resource of each type at a time. If an attempt is made to insert a resource that already exists, an error will be raised.
Examples
:ok = Ecspanse.Command.insert_resource!({Demo.Resources.Lobby, player_count: 0})
@spec update_resource!(resource :: struct(), state_changes :: keyword()) :: updated_resource :: struct()
Updates an existing global resource.
Examples
:ok = Ecspanse.Command.update_resource!(lobby_resource, player_count: 1)