In my latest project, I set up my GenServers with an Options struct that defines what arguments can be given in the supervisor child list. Example:
defmodule ExSpeedGame.Game.ButtonInput do
use GenServer
defmodule Options do
@type t :: %__MODULE__{
pins: Types.pins(),
debounce_delay: integer(),
name: GenServer.name()
}
@enforce_keys [:pins, :debounce_delay, :name]
defstruct [:pins, :debounce_delay, :name]
end
This is then used in the start_link
function that splits the data to the correct GenServer.start_link
arguments.
@spec start_link(Options.t()) :: :ignore | {:error, any} | {:ok, pid}
def start_link(%Options{} = opts) do
GenServer.start_link(
__MODULE__,
%{pins: opts.pins, debounce_delay: opts.debounce_delay},
name: opts.name
)
end
I do this so that in the supervisor I can list the child like this:
{ButtonInput, %ButtonInput.Options{pins: pins, debounce_delay: debounce_delay, name: ButtonInput}},
What do you think of this style? It’s quite verbose because I don’t have the quick struct macro in use that would reduce typing. What do you use for this case?
Here is the actual code if you want to see the full context (I tried to only take the relevant parts for the post): https://gitlab.com/Nicd/ex_speed_game/-/blob/master/lib/game/button_input.ex