Current section
Files
Jump to
Current section
Files
lib/gen_timer/manager.ex
defmodule GenTimer.Manager do
use GenServer
require Logger
alias GenTimer.{Timer, Messenger}
def child_spec({duration, topic}) do
%{
id: {__MODULE__, topic},
start: {__MODULE__, :start_link, [{duration, topic}]},
restart: :temporary
}
end
def start_link({duration, topic}) do
GenServer.start_link(
__MODULE__,
{duration, topic},
name: via(topic)
)
end
def initialize(duration, topic) do
DynamicSupervisor.start_child(
GenTimer.Supervisor.Manager,
{__MODULE__, {duration, topic}}
)
end
def start(topic) do
GenServer.cast(via(topic), :start)
end
def get_timer(topic) do
GenServer.call(via(topic), :get_timer)
end
def pause(topic) do
GenServer.cast(via(topic), :pause)
end
def reset(topic) do
GenServer.cast(via(topic), :reset)
end
@impl true
def init({duration, topic}) do
new_timer =
duration
|> Timer.new()
|> Messenger.broadcast(topic)
{:ok, {new_timer, topic}}
end
@impl true
def handle_call(:get_timer, _from, {timer, _topic} = state) do
{:reply, timer, state}
end
@impl true
def handle_cast(:start, {timer, topic}) do
started_timer =
timer
|> Timer.start()
|> Messenger.tick()
|> Messenger.broadcast(topic)
{:noreply, {started_timer, topic}}
end
def handle_cast(:pause, {timer, topic}) do
paused_timer =
timer
|> Timer.pause()
|> Messenger.broadcast(topic)
{:noreply, {paused_timer, topic}}
end
def handle_cast(:reset, {timer, topic}) do
reset_timer =
timer
|> Timer.reset()
|> Messenger.broadcast(topic)
{:noreply, {reset_timer, topic}}
end
@impl true
def handle_info(:tick, {timer, topic}) do
ticking_timer =
timer
|> Timer.increment()
|> Messenger.tick()
|> Messenger.broadcast(topic)
if ticking_timer.state == :finished do
{:stop, :shutdown, {ticking_timer, topic}}
else
{:noreply, {ticking_timer, topic}}
end
end
def handle_info(_msg, {timer, topic}) do
{:noreply, {timer, topic}}
end
def via(name) do
{
:via,
Registry,
{GenTimer.Registry.Manager, name}
}
end
end