View Source ECSx.Component behaviour (ECSx v0.5.1)

A Component labels an entity as having a certain attribute, and holds any data needed to model that attribute.

For example, if Entities in your application should have a "color" value, you will create a Component type called Color. This allows you to add a color component to an Entity with add/2, look up the color value for a given Entity with get_one/1, get all Entities' color values with get_all/1, remove the color value from an Entity altogether with remove/1, or test whether an entity has a color with exists?/1.

Under the hood, we use ETS to store the Components in memory for quick retrieval via Entity ID.

usage

Usage

Each Component type should have its own module, where it can be optionally configured.

defmodule MyApp.Components.Color do
  use ECSx.Component,
    value: :binary
end

options

Options

  • :value - The type of value which will be stored in this component type. Valid types are: :atom, :binary, :datetime, :float, :integer
  • :index - When true, the search/1 function will be much more efficient, at the cost of slightly higher write times. Defaults to false
  • :log_edits - When true, log messages will be emitted for each component added, updated, or removed. Defaults to false
  • :read_concurrency - When true, enables read concurrency for this component table. Only set this if you know what you're doing. Defaults to false

Link to this section Summary

Callbacks

Creates a new component.

Look up all components where the value is greater than or equal to min.

Look up all components where the value is less than or equal to max.

Look up all components where the value is greater than or equal to min and less than or equal to max.

Checks if an entity has a component of this type.

Look up a component and return its value.

Look up all components of this type.

Removes this component type from an entity.

Look up all IDs for entities which have a component of this type with a given value.

Updates an existing component's value.

Link to this section Types

@type id() :: any()
@type value() :: any()

Link to this section Callbacks

Link to this callback

add(entity, value, opts)

View Source
@callback add(entity :: id(), value :: value(), opts :: Keyword.t()) :: :ok

Creates a new component.

options

Options

  • :persist - When true, this component will persist across app reboots. Defaults to false

example

Example

# Add an ArmorRating component to entity `123` with value `10`
# If the app shuts down, this component will be removed
ArmorRating.add(123, 10)

# This ArmorRating component will be persisted after app shutdown,
# and automatically re-added to entity `123` upon next startup
ArmorRating.add(123, 10, persist: true)
Link to this callback

at_least(min)

View Source (optional)
@callback at_least(min :: number()) :: [{id(), number()}]

Look up all components where the value is greater than or equal to min.

This function only works for numerical component types (:value set to either :integer or :float). Other value types will raise UndefinedFunctionError.

example

Example

# Get all PlayerExperience components where value >= 2500
PlayerExperience.at_least(2500)
@callback at_most(max :: number()) :: [{id(), number()}]

Look up all components where the value is less than or equal to max.

This function only works for numerical component types (:value set to either :integer or :float). Other value types will raise UndefinedFunctionError.

example

Example

# Get all PlayerHealth components where value <= 10
PlayerHealth.at_most(10)
Link to this callback

between(min, max)

View Source (optional)
@callback between(min :: number(), max :: number()) :: [{id(), number()}]

Look up all components where the value is greater than or equal to min and less than or equal to max.

This function only works for numerical component types (:value set to either :integer or :float). Other value types will raise UndefinedFunctionError.

example

Example

# Get all RespawnCount components where 51 <= value <= 100
RespawnCount.between(51, 100)
@callback exists?(entity :: id()) :: boolean()

Checks if an entity has a component of this type.

@callback get(entity :: id(), default :: value()) :: value()

Look up a component and return its value.

If a default value is provided, that value will be returned if no result is found.

If default is not provided, this function will raise an ECSx.NoResultsError if no result is found.

example

Example

# Get the Velocity for entity `123`, which is known to already exist
Velocity.get(123)

# Get the Velocity for entity `123` if it exists, otherwise return `nil`
Velocity.get(123, nil)
@callback get_all() :: [{id(), value()}]

Look up all components of this type.

example

Example

# Get all velocity components
Velocity.get_all()
@callback remove(entity :: id()) :: :ok

Removes this component type from an entity.

@callback search(value :: value()) :: [id()]

Look up all IDs for entities which have a component of this type with a given value.

This function is significantly optimized by the :index option. For component types which are regularly searched, it is highly recommended to set this option to true.

example

Example

# Get all entities with a velocity of `60`
Velocity.search(60)
@callback update(entity :: id(), value :: value()) :: :ok

Updates an existing component's value.

The component's :persist option will remain unchanged. (see add/3)

example

Example

ArmorRating.add(123, 10)
# Increase the ArmorRating value from `10` to `15`
ArmorRating.update(123, 15)