View Source Rephex.Selector behaviour (rephex v0.2.0)
Rephex.Selector is a module that functions similarly to a view in a database.
It manages display data derived from actual data, keeping the presentation
layer in sync with changes to the underlying data.
Selectors automatically update their values whenever the associated real data changes, effectively decoupling the logic for updating display data from the logic for updating real data.
By using args/1 callback, you can specify the dependencies of the selector and avoid unnecessary updates.
Example
defmodule RephexPg.StateWithSelector do
alias RephexPg.StateWithSelector.SelectDoubleV
alias Rephex.Selector
@initial_state %{
v: 1,
double_v: Selector.new(SelectDoubleV)
}
use Rephex.State, initial_state: @initial_state
# mutators --------------------------------
def set_v(socket, v) do
put_state_in(socket, [:v], v)
end
# selectors --------------------------------
defmodule SelectDoubleV do
@behaviour Rephex.Selector
@impl true
def args(state), do: {state.v}
@impl true
def eval({v}), do: v * 2
# if state.v is not changed, eval/1 will not be called.
end
end
socket = RephexPg.StateWithSelector.set_v(socket, 2)
# socket.assigns.rpx.v = 2
# socket.assigns.rpx.double_v.value == 4Selector dependent on other selectors
If a selector depends on other selectors, you can specify the dependencies.
Example
defmodule RephexPg.StateWithSelector do
alias RephexPg.StateWithSelector.{SelectDoubleV, SelectQuadV}
alias Rephex.Selector
@initial_state %{
v: 1,
double_v: Selector.new(SelectDoubleV),
quad_v: Selector.new(SelectQuadV)
}
use Rephex.State, initial_state: @initial_state
def set_v(socket, v) do
put_state_in(socket, [:v], v)
end
defmodule SelectDoubleV do
# ...
end
defmodule SelectQuadV do
@behaviour Rephex.Selector
@impl true
def deps(), do: [SelectDoubleV]
@impl true
def args(state), do: {state.double_v.value}
@impl true
def eval({dv}), do: dv * 2
end
end
socket = RephexPg.StateWithSelector.set_v(socket, 2)
# socket.assigns.rpx.v = 2
# socket.assigns.rpx.double_v.value == 4
# socket.assigns.rpx.quad_v.value == 8
Summary
Functions
Create a new selector. Selector should be in root of the state.