Packages

Generic Timer that broadcasts :tick to subscribers

Current section

Files

Jump to
vt_gen_timer lib gen_timer timer.ex
Raw

lib/gen_timer/timer.ex

defmodule GenTimer.Timer do
@type t :: %__MODULE__{
duration: non_neg_integer(),
state: :initial | :paused | :active | :finished,
time_passed: non_neg_integer()
}
@enforce_keys [:duration]
defstruct [:duration, state: :initial, time_passed: 0]
@spec new(non_neg_integer()) :: t()
def new(duration) do
struct!(__MODULE__, duration: duration)
end
@spec start(t()) :: t()
def start(timer) do
change_state(timer, :active)
end
@spec increment(t()) :: t()
def increment(%__MODULE__{state: state} = timer) when state !== :active, do: timer
def increment(%__MODULE__{time_passed: time_passed, duration: duration} = timer)
when time_passed == duration - 1 do
timer
|> increment_time_passed()
|> change_state(:finished)
end
def increment(timer) do
increment_time_passed(timer)
end
@spec pause(t()) :: t()
def pause(timer) do
change_state(timer, :paused)
end
@spec reset(t()) :: t()
def reset(timer) do
timer
|> reset_counter()
|> change_state(:initial)
end
defp change_state(timer, next_state) do
Map.replace(timer, :state, next_state)
end
defp reset_counter(timer) do
Map.replace(timer, :time_passed, 0)
end
defp increment_time_passed(timer) do
Map.update!(timer, :time_passed, &(&1 + 1))
end
end