Packages
mob
0.3.3
0.7.20
0.7.19
0.7.18
0.7.17
0.7.16
0.7.15
0.7.14
0.7.13
0.7.12
0.7.11
0.7.10
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.26
0.6.25
0.6.24
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.2
0.6.1
0.6.0
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.11
0.5.10
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
BEAM-on-device mobile framework for Elixir
Current section
Files
Jump to
Current section
Files
lib/mob/nav/registry.ex
defmodule Mob.Nav.Registry do
@moduledoc """
ETS-backed registry mapping screen name atoms to their modules.
Populated at startup by walking an `Mob.App` module's `navigation/1`
declarations for both platforms. Hot-code-reload safe — the mapping stores
module atoms, not captured references.
`register/2` is available for runtime additions: A/B testing, library screens,
or dynamic feature flags.
"""
use GenServer
@table __MODULE__
@doc """
Start the registry, seeding it from the given App module.
Normally started by `Mob.Nav.Registry.start_link/1` in your application
supervisor. In tests, start it directly.
"""
@spec start_link(module()) :: GenServer.on_start()
def start_link(app_module) when is_atom(app_module) do
GenServer.start_link(__MODULE__, app_module, name: __MODULE__)
end
@doc """
Look up the module registered under `name`.
Returns `{:ok, module}` or `{:error, :not_found}`.
"""
@spec lookup(atom()) :: {:ok, module()} | {:error, :not_found}
def lookup(name) when is_atom(name) do
case :ets.lookup(@table, name) do
[{^name, module}] -> {:ok, module}
[] -> {:error, :not_found}
end
end
@doc """
Register a `name → module` mapping at runtime.
Overwrites any existing entry for `name`.
"""
@spec register(atom(), module()) :: :ok
def register(name, module) when is_atom(name) and is_atom(module) do
:ets.insert(@table, {name, module})
:ok
end
# ── GenServer ──────────────────────────────────────────────────────────────
@impl GenServer
def init(app_module) do
:ets.new(@table, [:named_table, :public, read_concurrency: true])
populate(app_module)
{:ok, app_module}
end
defp populate(app_module) do
for platform <- [:android, :ios] do
nav = app_module.navigation(platform)
register_nav(nav)
end
:ok
end
defp register_nav(%{type: :stack, name: name, root: root}) do
:ets.insert(@table, {name, root})
end
defp register_nav(%{type: type, branches: branches})
when type in [:tab_bar, :drawer] do
Enum.each(branches, ®ister_nav/1)
end
defp register_nav(_), do: :ok
end