Add central reset function.
This commit is contained in:
parent
95a0712041
commit
362826eb2f
1 changed files with 22 additions and 21 deletions
|
@ -2,7 +2,7 @@ defmodule MIDITools.Player do
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
A GenServer for playing a schedule of MIDI commands at certain times.
|
A GenServer for playing a schedule of MIDI commands at predefined times.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Client API
|
# Client API
|
||||||
|
@ -16,18 +16,19 @@ defmodule MIDITools.Player do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Set the current schedule and total duration for the MIDI player.
|
Generate the current schedule defined by the given events.
|
||||||
|
|
||||||
The list of events is internally converted to MIDI commands.
|
The list of events is internally converted to MIDI commands.
|
||||||
If multiple events are scheduled on the same time,
|
If multiple events are scheduled on the same time,
|
||||||
then they are executed in the same order as in the list.
|
then they are executed in the same order as in the list.
|
||||||
The duration makes sure the player plays a (potential) pause after the last
|
The duration makes sure the player plays a (potential) pause after the last
|
||||||
midi command.
|
midi command.
|
||||||
|
|
||||||
|
See `MIDITools.Event` to create events.
|
||||||
"""
|
"""
|
||||||
@spec set_schedule([MIDITools.Event.t()], non_neg_integer()) :: :ok
|
@spec generate_schedule([MIDITools.Event.t()], non_neg_integer()) :: :ok
|
||||||
def set_schedule(events, duration) do
|
def generate_schedule(events, duration) when duration > 0 do
|
||||||
schedule = convert_events(events)
|
GenServer.call(__MODULE__, {:generate_schedule, events, duration})
|
||||||
GenServer.call(__MODULE__, {:set_schedule, schedule, duration})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -90,33 +91,25 @@ defmodule MIDITools.Player do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl GenServer
|
@impl GenServer
|
||||||
def handle_call({:set_schedule, schedule, duration}, _from, state) do
|
def handle_call({:generate_schedule, events, duration}, _from, state) do
|
||||||
|
state = %{state | schedule: convert_events(events)}
|
||||||
{:reply, :ok, %{state | schedule: schedule, schedule_left: schedule, duration: duration}}
|
{:reply, :ok, %{reset(state) | duration: duration}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call(:play, _from, %{timer: timer, schedule: schedule} = state) do
|
def handle_call(:play, _from, %{schedule: schedule} = state) do
|
||||||
if timer != nil do
|
|
||||||
Process.cancel_timer(timer, info: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
start_time = Timex.now()
|
start_time = Timex.now()
|
||||||
timer = start_timer(schedule, start_time)
|
timer = start_timer(schedule, start_time)
|
||||||
|
|
||||||
{:reply, :ok,
|
{:reply, :ok,
|
||||||
%{state | timer: timer, start_time: start_time, schedule_left: schedule, pause_time: nil}}
|
%{reset(state) | timer: timer, start_time: start_time}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call({:set_repeat, repeat}, _from, state) do
|
def handle_call({:set_repeat, repeat}, _from, state) do
|
||||||
{:reply, :ok, %{state | repeat: repeat}}
|
{:reply, :ok, %{state | repeat: repeat}}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call(:stop_playing, _from, %{timer: timer} = state) do
|
def handle_call(:stop_playing, _from, state) do
|
||||||
if timer != nil do
|
{:reply, :ok, reset(state)}
|
||||||
Process.cancel_timer(timer, info: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
{:reply, :ok, %{state | timer: nil, pause_time: nil}}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call(:pause, _from, %{pause_time: pause_time} = state) when pause_time != nil do
|
def handle_call(:pause, _from, %{pause_time: pause_time} = state) when pause_time != nil do
|
||||||
|
@ -223,4 +216,12 @@ defmodule MIDITools.Player do
|
||||||
end)
|
end)
|
||||||
|> Enum.sort()
|
|> Enum.sort()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp reset(%{timer: timer, schedule: schedule} = state) do
|
||||||
|
if timer != nil do
|
||||||
|
Process.cancel_timer(timer, info: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
%{state | timer: nil, pause_time: nil, schedule_left: schedule}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue