Bus and Lifecycle Rules

1. Plugin lifecycle

  1. Host creates plugin instance.
  2. OnLoad(IHostContext) is called once.
  3. Plugin subscribes to buses, registers menus/panes.
  4. On unload, plugin must unsubscribe and release references in OnUnload().

2. Bus event usage model

BusEventUse
ISampleControllerBusStateChangedcursor/view/selection UI sync
ISampleControllerBusBufferChangedbuffer-dependent refresh
ISelectionEventBusSelectionChangedselection lifecycle; heavy work on Finished
IAudioSystemBusPlaybackStateChangedplayhead state
IAudioSystemBusMeterFrameAvailableVU meters
IWaveHoverEventBusHoverChangedstatus bar hover data

3. Selection lifecycle phases

Do not process full-buffer DSP on Dragging. Use Finished.

4. Preview lifecycle for effect dialogues

// 1) capture source
var source = _context.DocumentService.CopyEffectiveRangeToBuffer(start, end);

// 2) create preview session
using var preview = _context.DocumentService.BeginPreview(start, end);

// 3) apply preview buffer for visual/audio preview
preview.ApplyPreview(previewBuffer);

// 4a) Apply
preview.Commit();

// 4b) Cancel/Close
preview.Cancel();

Audio preview should also be stopped on close/unload using a stable PreviewOwnerId.

5. UI thread requirements

private void OnStateChanged(object? sender, SampleControllerState state)
{
    if (_label is null) return;
    if (_label.InvokeRequired)
    {
        _label.BeginInvoke(new Action(() => OnStateChanged(sender, state)));
        return;
    }

    _label.Text = state.Cursor.ToString();
}
Never update controls directly from worker/background threads.

6. Active document changed while dialogue is open

  1. Capture active document id at dialogue open.
  2. Before Apply/Commit, verify current active document id matches.
  3. If it changed, abort apply and prompt user.

7. Menus

Menu structure, ordering, grouping, and context-menu subscription are documented in Menus.

Quick format reminder:

Main menu:    <Root>.<Group>.<Item>[.<SubMenu>...]
Context menu: <Group>.<Item>[.<SubMenu>...]

Example:

context.WindowManager.AddMenuContribution(30, "Effects.100.Amplitude.Amplify", _ => OpenAmplify());
context.WindowManager.AddContextMenuContribution("SampleEditor.Wave", 200, "effectsgroup.Smooth", _ => OpenSmooth());

Back to top