Packages

Idiomatic Elixir SDK for Rockbox — pipe-friendly, builder-friendly, with real-time event subscriptions and a plugin system.

Current section

Files

Jump to
rockbox_ex lib rockbox plugin.ex
Raw

lib/rockbox/plugin.ex

defmodule Rockbox.Plugin do
@moduledoc """
Behaviour for Rockbox plugins. A plugin is a regular module implementing
`install/1` (and optionally `uninstall/1`).
defmodule MyApp.LastFmScrobbler do
@behaviour Rockbox.Plugin
@impl true
def name, do: "lastfm-scrobbler"
@impl true
def version, do: "1.0.0"
@impl true
def description, do: "Scrobble played tracks to Last.fm"
@impl true
def install(ctx) do
# Subscribe like any other process — events arrive as messages.
Rockbox.Events.subscribe(:track_changed)
{:ok, %{client: ctx.client, started_at: System.monotonic_time(:millisecond)}}
end
@impl true
def uninstall(_state), do: :ok
end
Install with `Rockbox.use_plugin(client, MyApp.LastFmScrobbler)`. Plugins
receive a `t:context/0` map containing the client they were installed with.
Heavy plugins (those that need their own process) should spawn it inside
`install/1` and store its pid in their state — `uninstall/1` will be called
with that state and can shut the process down.
"""
@type context :: %{client: Rockbox.Client.t()}
@type state :: term()
@callback name() :: String.t()
@callback version() :: String.t()
@callback description() :: String.t()
@callback install(context()) :: {:ok, state()} | :ok | {:error, term()}
@callback uninstall(state()) :: :ok | {:error, term()}
@optional_callbacks description: 0, uninstall: 1
@doc false
def description(plugin) do
if function_exported?(plugin, :description, 0), do: plugin.description(), else: nil
end
@doc false
def uninstall(plugin, state) do
if function_exported?(plugin, :uninstall, 1), do: plugin.uninstall(state), else: :ok
end
end