I’ve created a custom GenServer macro, to abstract the logic from the user of a project I’m working on, Cadex. It’s used for modelling and simulating basic differential equation based models and eventually complex systems.
I’ve been experimenting with different ways I can create state update functions like below, and make it a bit cleaner - so the user only has to implement the core logic. Essentially I want to take the handle_call function and insert code before and after, adapt the function interface, but I’m struggling to get my head around it. You can see my WIP here: cadex/lib/cadex at robots-marbles-7 · BenSchZA/cadex · GitHub in decorators.ex and model.ex.
def handle_call(
{:update, var},
_from,
state = %Cadex.Types.State{current: current, delta: delta}
)
when var == :box_A do
increment =
&(&1 +
cond do
current[var] > current[:box_B] -> -1
current[var] < current[:box_B] -> 1
true -> 0
end)
delta_ = %{var => increment}
state_ =
state
|> Map.put(:delta, Map.merge(delta, delta_))
{
:reply,
state_,
state_
}
end
Rather something cleaner like this:
@state_update(:box_A)
def update_box_A(
{:update, var},
state = %Cadex.Types.State{current: current, delta: delta}
) do
increment =
&(&1 +
cond do
current[var] > current[:box_B] -> -1
current[var] < current[:box_B] -> 1
true -> 0
end)
{var: increment}
end
In the GenServer macro, I’d then like to insert the rest of the code, and make sure the handle_call behaviour(?) is still implemented correctly and returns the right result. Is this possible?
I think I’ve messed around enough trying to implement a solution, and maybe some feedback would help me on my way! Appreciate any guidance ![]()






















