Expand description
Write a Nobble addon.
An addon is whatever knows how to make another application do something —
skip a track, switch an OBS scene, start a Fusion 360 command. You implement
Addon, hand it to run, and the daemon does the rest.
use nobble_addon_sdk::{Addon, AddonAction, AddonError, Availability, Invocation, Trigger, run};
struct Hello;
const ACTIONS: &[AddonAction] = &[AddonAction {
id: "wave",
name: "Wave",
description: "Says hello.",
trigger: Trigger::Momentary,
params: &[],
// Everything this action does not need. Finishing a declaration with
// `..BASE` is how a later field costs you nothing.
..AddonAction::BASE
}];
impl Addon for Hello {
fn id(&self) -> &'static str { "hello" }
fn name(&self) -> &'static str { "Hello" }
fn description(&self) -> &'static str { "An addon that waves." }
fn actions(&self) -> &'static [AddonAction] { ACTIONS }
fn availability(&self) -> Availability { Availability::Ready }
fn perform(&mut self, action: &str, _i: &Invocation<'_>) -> Result<(), AddonError> {
match action {
"wave" => Ok(()),
other => Err(AddonError::NoSuchAction(other.to_owned())),
}
}
}
fn main() { run(Hello); }§Why this is a separate process
ADR-0016. An addon
runs as a child of the daemon and speaks the protocol in protocol over
its stdin and stdout. That is what makes FR-045 true — a crash, a hang or a
leak in your addon cannot reach input, MIDI, or anybody else’s addon — and
it is what lets Credentials be scoped to you rather than handed out as a
key to everyone’s.
You do not write any of that. run owns the loop and the framing; you
write the trait.
§What is deliberately not here
No device, input, layout or module types. An addon contributes actions,
signals, settings and configuration UI (FR-047) and has no business knowing
what an InputId is. If you find yourself needing one, that is a gap in
this SDK to be reported rather than routed around — FR-050 says official
addons get no private interfaces either, so the gap is real for everyone.
Modules§
- protocol
- What crosses the pipe between the daemon and an addon.
Structs§
- Addon
Action - One thing an addon can be asked to do.
- Addon
Choice - One option a user can pick.
- Addon
Choices - A named list of options an addon offers, which a parameter can draw from.
- Addon
Param - One thing an action needs to know, declared so an interface can ask for it.
- Addon
Setting - One thing an addon needs configuring once, rather than per key.
- Addon
Signal - A named boolean fact an addon publishes about its target.
- Choice
- One option from a live source.
- Device
Action - One thing an addon names and the device does, with no addon running.
- Invocation
- What an action was given when it ran.
Enums§
- Addon
Error - Why performing an action failed.
- Availability
- Whether an addon can act at the moment.
- Device
Keystroke - One keystroke, exactly as the device will send it.
- Param
Kind - What a parameter holds, so an interface can offer the right editor.
- Param
Value - What one parameter holds: a value, or several.
- Permission
- Something an addon needs to be allowed to do (FR-046).
- Reading
- What an addon’s signals read at one moment.
- Trigger
- What kind of input an action expects.
Constants§
- FADER_
MAX - Full scale for a 14-bit fader value.
Traits§
- Addon
- Something that can act on another application’s behalf.
- Credentials
- Where an addon keeps its own credentials (ADR-0013, FR-046).
- Store
- Somewhere to remember things that are not secrets (ADR-0027).
Functions§
- app_
matches - Whether something the platform named is the application a binding meant.
- run
- Serve an addon on stdin and stdout, until told to stop.
Type Aliases§
- Credential
Handle - A shared
Credentials, because an addon needs it after configuration too. - Store
Handle - A shared
Store, for the same reasonCredentialHandleis shared.