aboutsummaryrefslogtreecommitdiff
path: root/lib/audio/server.ex
blob: 0ec901f50ee8814e30d73721f27bb5d327612359 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
alias Nostrum.Struct
alias Nostrum.Snowflake

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