Genesis.Aspect behaviour (genesis v0.7.0)

View Source

Provides common behavior and callbacks for aspects. Aspects are modular pieces of state or behavior that can be attached to objects.

Summary

Callbacks

Returns all aspects of the given type. Returns a list of tuples containing the object and the aspect struct.

Returns all aspects that have the given property with a value greater than or equal to the given minimum.

Returns all aspects that have the given property with a value less than or equal to the given maximum.

Attaches an aspect to an object. Returns :ok if the aspect was successfully attached, :noop if an aspect with the same props is already attached, or :error if the same aspect with different props is already attached.

Returns all aspects that have the given property with a value between the given minimum and maximum (inclusive).

Casts the given properties into a map of permitted values. This function normalizes input that can be used to create an aspect.

Returns true if the aspect is attached to the given object.

Retrieves the aspect attached to an object. Returns the aspect struct if present or nil.

Same as get/1, but returns a default value if the aspect is not present.

Handles events dispatched to this aspect via its parent object. Receives the event name, the object and a map of arguments for the event.

Initializes the aspect ETS table. Should return an atom with the name of the table and a list of events.

Returns all aspects that match the given properties.

Creates a new aspect by casting the given properties. The given properties are passed to the cast/1 function.

Called when an aspect is attached, removed, replaced, or updated on an object. Receives the hook name, the object, and the aspect struct that triggered the hook.

Removes an aspect from an object. Returns :noop if the aspect is not present.

Replaces an aspect attached to an object. Will return :noop if the aspect is not present.

Updates a specific property of an aspect attached to the object. Will return :noop if the aspect is not present or :error if the property does not exist.

Types

event()

@type event() :: Genesis.Event.t()

object()

@type object() :: integer() | atom() | binary()

props()

@type props() :: keyword() | map()

Callbacks

all()

@callback all() :: [{object(), struct()}]

Returns all aspects of the given type. Returns a list of tuples containing the object and the aspect struct.

Examples

iex> Health.all()
[{1, %Health{current: 100}}, {2, %Health{current: 50}}]

at_least(atom, integer)

@callback at_least(atom(), integer()) :: [{object(), struct()}]

Returns all aspects that have the given property with a value greater than or equal to the given minimum.

Examples

iex> Health.at_least(:current, 50)
[{1, %Health{current: 75}}]

at_most(atom, integer)

@callback at_most(atom(), integer()) :: [{object(), struct()}]

Returns all aspects that have the given property with a value less than or equal to the given maximum.

Examples

iex> Health.at_most(:current, 50)
[{1, %Health{current: 25}}]

attach(object, props)

@callback attach(object(), props()) :: :ok | :noop | :error

Attaches an aspect to an object. Returns :ok if the aspect was successfully attached, :noop if an aspect with the same props is already attached, or :error if the same aspect with different props is already attached.

between(atom, integer, integer)

@callback between(atom(), integer(), integer()) :: [{object(), struct()}]

Returns all aspects that have the given property with a value between the given minimum and maximum (inclusive).

Examples

iex> Health.between(:current, 50, 100)
[{1, %Health{current: 75}}]

cast(props)

@callback cast(props()) :: map()

Casts the given properties into a map of permitted values. This function normalizes input that can be used to create an aspect.

exists?(object)

@callback exists?(object()) :: boolean()

Returns true if the aspect is attached to the given object.

get(object)

@callback get(object()) :: struct() | nil

Retrieves the aspect attached to an object. Returns the aspect struct if present or nil.

Examples

iex> Health.get(1)
%Health{current: 100}

get(object, any)

@callback get(object(), any()) :: struct() | any()

Same as get/1, but returns a default value if the aspect is not present.

handle_event(event)

(optional)
@callback handle_event(event()) :: {:cont, event()} | {:halt, event()}

Handles events dispatched to this aspect via its parent object. Receives the event name, the object and a map of arguments for the event.

Given that the same event is dispatched to all aspects within an object, this function should return a tuple with :cont or :halt to either keep processing the event or stop propagating the event to the remaining aspects in the pipeline.

init()

@callback init() :: {:ets.tid(), [atom()]}

Initializes the aspect ETS table. Should return an atom with the name of the table and a list of events.

match(props)

@callback match(props()) :: [{object(), struct()}]

Returns all aspects that match the given properties.

Examples

iex> Moniker.match(name: "Tripida")
[{1, %Moniker{name: "Tripida"}}]

new(props)

@callback new(props()) :: struct()

Creates a new aspect by casting the given properties. The given properties are passed to the cast/1 function.

on_hook(atom, object, struct)

@callback on_hook(atom(), object(), struct()) :: any()

Called when an aspect is attached, removed, replaced, or updated on an object. Receives the hook name, the object, and the aspect struct that triggered the hook.

remove(object)

@callback remove(object()) :: :ok | :noop

Removes an aspect from an object. Returns :noop if the aspect is not present.

replace(object, props)

@callback replace(object(), props()) :: :ok | :noop

Replaces an aspect attached to an object. Will return :noop if the aspect is not present.

update(object, atom, fun)

@callback update(object(), atom(), fun()) :: :ok | :noop | :error

Updates a specific property of an aspect attached to the object. Will return :noop if the aspect is not present or :error if the property does not exist.