View Source Ecspanse.State behaviour (ECSpanse v0.9.0)

The Ecspanse.State module is responsible for creating, storing and manipulating various application states. It provides functions for initializing the state, updating the state, and retrieving information from the state. As well as emitting special Ecspanse.Event.StateTransition events when the state changes.

Attention

Under the hood, the States are just Ecspanse.Resource modules with a few additional constraints. As a result, state transitions may happen only in synchronous systems. set_state!/1 should not be called in async systems, as it will raise an error.

States can be initialized only at startup in the Ecspanse.setup/1 callback. The states can be used for conditionally running systems (such as :run_in_state, or :run_if). See Ecspanse.add_system/3 for more information.

In the context of conditionally running systems, it is important to keep in mind that, aldough the state transition is synchronous and immediate, the run conditions will pick the change only for the next frame. For sensitive systems, a good mitigation is to schedule state transition systems as frame_end, and run them as late in the frame as possible.

Options

  • :states - required - a list of atoms with all the possible states for the state module.
  • :default - required - an atom with the default state for the state module. Must be one of the states from the :states option.

Examples

  defmodule Demo.States.Game do
    use Ecspanse.State, states: [:play, :paused], default: :play
  end

Summary

Implemented Callbacks

Gets the current state for the state module.

Sets the current state for the state module.

Types

A state_spec is the definition required to create a state module.

Implemented Callbacks

@callback get_state!() :: atom()

Gets the current state for the state module.

The module must use Ecspanse.State. Otherwise the function will raise an error.

Implemented Callback

This callback is implemented by the library and can be used as such.

Examples:

    current_state_atom = Demo.States.Game.get_state!()
@callback set_state!(next_state :: atom()) :: :ok

Sets the current state for the state module.

This function can run only in a synchronous system, otherwise it will raise an error. It is advised against calling this function multiple times in the same system for the same state module.

Upon state change, a Ecspanse.Event.StateTransition event is automatically emitted.

Implemented Callback

This callback is implemented by the library and can be used as such.

Examples:

    Demo.States.Game.set_state!(:paused)

Types

@type state_spec() ::
  (state_module :: module())
  | {state_module :: module(), initial_state :: atom()}

A state_spec is the definition required to create a state module.

Examples

  Demo.States.Game
  {Demo.States.Game, :paused}