Current section
Files
Jump to
Current section
Files
lib/wrap.ex
defmodule Mediasoup.NifWrap do
@moduledoc """
Wrapper for calling GenServer that hosts NIF resource.
"""
# Utilities for wrap Nif
@spec def_handle_call_nif(any) ::
{:__block__, [], [{:@, [...], [...]} | {:def, [...], [...]}, ...]}
defmacro def_handle_call_nif(nif_call_map) do
quote do
@nif_map unquote(nif_call_map)
@nif_keylist Map.keys(@nif_map)
def handle_call(
{function, arg},
_from,
%{reference: reference} = state
)
when function in @nif_keylist do
try do
result = apply(Map.fetch!(@nif_map, function), [reference | arg])
{:reply, result, state}
rescue
e -> {:reply, {:raise_error, e}, state}
end
end
end
end
@spec def_handle_call_async_nif(any) ::
{:__block__, [], [{:@, [...], [...]} | {:def, [...], [...]}, ...]}
defmacro def_handle_call_async_nif(nif_call_map) do
quote do
@nif_map unquote(nif_call_map)
@nif_keylist Map.keys(@nif_map)
def handle_call(
{function, arg},
from,
%{reference: reference} = state
)
when function in @nif_keylist do
try do
result = apply(Map.fetch!(@nif_map, function), [reference | arg] ++ [{function, from}])
{:noreply, state}
rescue
e -> {:reply, {:raise_error, e}, state}
end
end
end
end
defmacro call(pid, args) do
quote do
try do
case GenServer.call(unquote(pid), unquote(args)) do
{:raise_error, e} -> raise e
{:error} -> :error
result -> result
end
catch
:exit, e -> {:error, :terminated}
end
end
end
def handle_create_result(create_result, module, supervisor) do
with {:ok, ref} <- create_result,
{:ok, pid} <-
DynamicSupervisor.start_child(
supervisor,
{module, [reference: ref]}
) do
{:ok, module.struct_from_pid_and_ref(pid, ref)}
else
error -> error
end
end
end