alias Nostrum.Struct defmodule Audio.Server do use GenServer @type which :: String.t() @type audio_ref :: {} def start_link(arg) do {:ok, _} = DynamicSupervisor.start_link(__MODULE__, arg, name: __MODULE__.Supervisor) {:ok, _} = Registry.start_link(keys: :unique, name: __MODULE__.Registry) end @spec play_now(Struct.Guild.id(), audio_ref) :: which def play_now(guild, audio_ref) do {:ok, which} = GenServer.call(__MODULE__, {:now, guild, audio_ref}) which end @spec enqueue(Struct.Guild.id(), audio_ref) :: which def enqueue(_guild, _audio_ref) do GenServer.call(__MODULE__, {:enqueue}) end @spec cancel(which) :: GenServer.call() def cancel(which) do GenServer.call(__MODULE__, {:cancel, which}) end @impl true def init(guild) do {:ok, {guild, :queue.new()}} end @impl true def handle_call({:now, {type, ref, opts}}, _from, {guild, q}) do if Nostrum.Voice.playing?(guild) do :ok = Nostrum.Voice.stop(guild) end id = UUID.uuid4() Nostrum.Voice.play(guild, ref, type, opts) q = :queue.in_r({id, ref}, q) {:reply, :ok, {guild, q}} end @impl true def handle_call({:enqueue, audio_ref}, _from, {_guild, q}) do id = UUID.uuid4() q = :queue.in({id, audio_ref}, q) {:reply, {:ok, id}, {id, q}} end @impl true def handle_call({:cancel, _audio_ref}, _from, {guild, q}) do q = :queue.delete_with(fn _elem -> false end, q) {:reply, :ok, {guild, q}} end end